From loewis@users.sourceforge.net Mon Oct 1 11:09:33 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Mon, 01 Oct 2001 03:09:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/lib-tk Tkinter.py,1.157,1.158 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory usw-pr-cvs1:/tmp/cvs-serv24727/Lib/lib-tk Modified Files: Tkinter.py Log Message: Patch #426880: Implement Listbox itemcget and itemconfigure. Index: Tkinter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/Tkinter.py,v retrieving revision 1.157 retrieving revision 1.158 diff -C2 -d -r1.157 -r1.158 *** Tkinter.py 2001/09/05 19:29:56 1.157 --- Tkinter.py 2001/10/01 10:09:31 1.158 *************** *** 2300,2303 **** --- 2300,2328 ---- if i == 'none': return None return getint(i) + def itemcget(self, index, option): + """Return the resource value for an ITEM and an OPTION.""" + return self.tk.call( + (self._w, 'itemcget') + (index, '-'+option)) + def itemconfigure(self, index, cnf=None, **kw): + """Configure resources of an ITEM. + + The values for resources are specified as keyword arguments. + To get an overview about the allowed keyword arguments + call the method without arguments. + Valid resource names: background, foreground, + selectbackground, selectforeground.""" + if cnf is None and not kw: + cnf = {} + for x in self.tk.split( + self.tk.call(self._w, 'itemconfigure', index)): + cnf[x[0][1:]] = (x[0][1:],) + x[1:] + return cnf + if type(cnf) == StringType and not kw: + x = self.tk.split(self.tk.call( + self._w, 'itemconfigure', index, '-'+cnf)) + return (x[0][1:],) + x[1:] + self.tk.call((self._w, 'itemconfigure', index) + + self._options(cnf, kw)) + itemconfig = itemconfigure def insert(self, index, *elements): """Insert ELEMENTS at INDEX.""" From loewis@users.sourceforge.net Mon Oct 1 11:09:33 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Mon, 01 Oct 2001 03:09:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.262,1.263 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv24727/Misc Modified Files: NEWS Log Message: Patch #426880: Implement Listbox itemcget and itemconfigure. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.262 retrieving revision 1.263 diff -C2 -d -r1.262 -r1.263 *** NEWS 2001/09/30 21:09:59 1.262 --- NEWS 2001/10/01 10:09:30 1.263 *************** *** 16,19 **** --- 16,21 ---- which indicates whether output is intended for the header 'Q' encoding. + - Tkinter.Listbox now exposes itemcget and itemconfigure. + Tools From gvanrossum@users.sourceforge.net Mon Oct 1 14:17:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 01 Oct 2001 06:17:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.78,2.79 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv7951 Modified Files: typeobject.c Log Message: Fix typo found by doerwalter. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.78 retrieving revision 2.79 diff -C2 -d -r2.78 -r2.79 *** typeobject.c 2001/09/30 05:58:42 2.78 --- typeobject.c 2001/10/01 13:17:24 2.79 *************** *** 2446,2450 **** {"__init__", (wrapperfunc)wrap_init, "x.__init__(...) initializes x; " ! "see x.__type__.__doc__ for signature"}, {0} }; --- 2446,2450 ---- {"__init__", (wrapperfunc)wrap_init, "x.__init__(...) initializes x; " ! "see x.__class__.__doc__ for signature"}, {0} }; From gvanrossum@users.sourceforge.net Mon Oct 1 14:47:48 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 01 Oct 2001 06:47:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.113,1.114 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv19439 Modified Files: ACKS Log Message: Another SF patch contributor. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.113 retrieving revision 1.114 diff -C2 -d -r1.113 -r1.114 *** ACKS 2001/09/30 05:09:36 1.113 --- ACKS 2001/10/01 13:47:46 1.114 *************** *** 288,291 **** --- 288,292 ---- Sjoerd Mullender Takahiro Nakayama + Travers Naran Fredrik Nehr Chad Netzer From gvanrossum@users.sourceforge.net Mon Oct 1 14:50:17 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 01 Oct 2001 06:50:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libnntplib.tex,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv20161 Modified Files: libnntplib.tex Log Message: Docs for SF patch #462628 Index: libnntplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libnntplib.tex,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** libnntplib.tex 2000/07/01 17:43:19 1.25 --- libnntplib.tex 2001/10/01 13:50:15 1.26 *************** *** 198,204 **** \end{methoddesc} ! \begin{methoddesc}{body}{id} Send a \samp{BODY} command, where \var{id} has the same meaning as for ! \method{stat()}. Return as for \method{head()}. \end{methoddesc} --- 198,210 ---- \end{methoddesc} ! \begin{methoddesc}{body}{id,\optional{fileHandle}} Send a \samp{BODY} command, where \var{id} has the same meaning as for ! \method{stat()}. If the \var{fileHandle} parameter is supplied, then ! the body is stored in a file. If \var{fileHandle} is a string, then ! the method will open a file object with that name, write to it then close it. ! If \var{fileHandle} is a file object, then it will start calling ! \method{write()} on it to store the lines of the body. ! Return as for \method{head()}. If \var{fileHandle} is supplied. Then ! the returned \var{list} is an empty list. \end{methoddesc} From gvanrossum@users.sourceforge.net Mon Oct 1 14:46:57 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 01 Oct 2001 06:46:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib nntplib.py,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv19232 Modified Files: nntplib.py Log Message: SF patch #462628 (Travers Naran) NNTPLib supports saving BODY to a file. I modified nntplib so the body method can accept an optional second parameter pointing to a filehandle or filename (string). This way, really long body articles can be stored to disk instead of kept in memory. The way I made the modification should make it easy to extend this functionality to other extended return methods. Index: nntplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/nntplib.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** nntplib.py 2001/02/09 07:02:17 1.26 --- nntplib.py 2001/10/01 13:46:55 1.27 *************** *** 32,35 **** --- 32,36 ---- import re import socket + import types __all__ = ["NNTP","NNTPReplyError","NNTPTemporaryError", *************** *** 211,228 **** 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 --- 212,244 ---- return resp ! def getlongresp(self,fileHandle=None): """Internal: get a response plus following text from the server. Raise various errors if the response indicates an error.""" ! ! openedFile = None ! try: ! # If a string was passed then open a file with that name ! if isinstance(fileHandle, types.StringType): ! openedFile = fileHandle = open(fileHandle, "w") ! ! 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:] ! if fileHandle: ! fileHandle.write(line + "\n") ! else: ! list.append(line) ! finally: ! # If this method created the file, then it must close it ! if openedFile: ! openedFile.close() ! return resp, list *************** *** 232,239 **** 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): --- 248,255 ---- return self.getresp() ! def longcmd(self, line, fileHandle=None): """Internal: send a command and get the response plus following text.""" self.putcmd(line) ! return self.getlongresp(fileHandle) def newgroups(self, date, time): *************** *** 340,346 **** 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 --- 356,362 ---- return self.statcmd('LAST') ! def artcmd(self, line, fileHandle=None): """Internal: process a HEAD, BODY or ARTICLE command.""" ! resp, list = self.longcmd(line,fileHandle) resp, nr, id = self.statparse(resp) return resp, nr, id, list *************** *** 357,370 **** 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): --- 373,388 ---- return self.artcmd('HEAD ' + id) ! def body(self, id, fileHandle=None): """Process a BODY command. Argument: - id: article number or message id + - fileHandle: Filename string or file object to store the article in Returns: - resp: server response if successful - nr: article number - id: message id ! - list: the lines of the article's body or an empty list ! if fileHandle was used""" ! return self.artcmd('BODY ' + id, fileHandle) def article(self, id): From fdrake@users.sourceforge.net Mon Oct 1 16:49:58 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 01 Oct 2001 08:49:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libmailbox.tex,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv19817 Modified Files: libmailbox.tex Log Message: Clarify comments about mailbox objects being iterable. Index: libmailbox.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libmailbox.tex,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** libmailbox.tex 2001/09/05 19:27:13 1.22 --- libmailbox.tex 2001/10/01 15:49:56 1.23 *************** *** 102,107 **** \subsection{Mailbox Objects \label{mailbox-objects}} ! All implementations of Mailbox objects are iterator objects, and so ! have one externally visible method: \begin{methoddesc}[mailbox]{next}{} --- 102,108 ---- \subsection{Mailbox Objects \label{mailbox-objects}} ! All implementations of mailbox objects are iterable objects, and ! have one externally visible method. This method is used by iterators ! created from mailbox objects and may also be used directly. \begin{methoddesc}[mailbox]{next}{} From gvanrossum@users.sourceforge.net Mon Oct 1 16:55:30 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 01 Oct 2001 08:55:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.79,2.80 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv21770 Modified Files: typeobject.c Log Message: slot_tp_new(): newargs was leaking. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.79 retrieving revision 2.80 diff -C2 -d -r2.79 -r2.80 *** typeobject.c 2001/10/01 13:17:24 2.79 --- typeobject.c 2001/10/01 15:55:28 2.80 *************** *** 3360,3363 **** --- 3360,3364 ---- } x = PyObject_Call(func, newargs, kwds); + Py_DECREF(newargs); Py_DECREF(func); return x; From fdrake@users.sourceforge.net Mon Oct 1 17:32:15 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 01 Oct 2001 09:32:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref3.tex,1.74,1.75 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv3389/ref Modified Files: ref3.tex Log Message: Refer to the objects which define __len__(), __*item__(), and __iter__() as container objects rather than as mapping objects (in the index entries). Change the section heading and intro sentence to be a little more general, since that's how things have actually evolved. Index: ref3.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -d -r1.74 -r1.75 *** ref3.tex 2001/09/18 17:58:20 1.74 --- ref3.tex 2001/10/01 16:32:13 1.75 *************** *** 1123,1130 **** ! \subsection{Emulating sequence and mapping types\label{sequence-types}} ! The following methods can be defined to emulate sequence or mapping ! objects. The first set of methods is used either to emulate a sequence or to emulate a mapping; the difference is that for a sequence, the allowable keys should be the integers \var{k} for which --- 1123,1132 ---- ! \subsection{Emulating container types\label{sequence-types}} ! The following methods can be defined to implement container ! objects. Containers usually are sequences (such as lists or tuples) ! or mappings (like dictionaries), but can represent other containers as ! well. The first set of methods is used either to emulate a sequence or to emulate a mapping; the difference is that for a sequence, the allowable keys should be the integers \var{k} for which *************** *** 1178,1182 **** \withsubitem{(numeric object method)}{\ttindex{__coerce__()}} ! \begin{methoddesc}[mapping object]{__len__}{self} Called to implement the built-in function \function{len()}\bifuncindex{len}. Should return the length of the --- 1180,1184 ---- \withsubitem{(numeric object method)}{\ttindex{__coerce__()}} ! \begin{methoddesc}[container object]{__len__}{self} Called to implement the built-in function \function{len()}\bifuncindex{len}. Should return the length of the *************** *** 1187,1191 **** \end{methoddesc} ! \begin{methoddesc}[mapping object]{__getitem__}{self, key} Called to implement evaluation of \code{\var{self}[\var{key}]}. For sequence types, the accepted keys should be integers and slice --- 1189,1193 ---- \end{methoddesc} ! \begin{methoddesc}[container object]{__getitem__}{self, key} Called to implement evaluation of \code{\var{self}[\var{key}]}. For sequence types, the accepted keys should be integers and slice *************** *** 1202,1206 **** \end{methoddesc} ! \begin{methoddesc}[mapping object]{__setitem__}{self, key, value} Called to implement assignment to \code{\var{self}[\var{key}]}. Same note as for \method{__getitem__()}. This should only be implemented --- 1204,1208 ---- \end{methoddesc} ! \begin{methoddesc}[container object]{__setitem__}{self, key, value} Called to implement assignment to \code{\var{self}[\var{key}]}. Same note as for \method{__getitem__()}. This should only be implemented *************** *** 1211,1215 **** \end{methoddesc} ! \begin{methoddesc}[mapping object]{__delitem__}{self, key} Called to implement deletion of \code{\var{self}[\var{key}]}. Same note as for \method{__getitem__()}. This should only be implemented --- 1213,1217 ---- \end{methoddesc} ! \begin{methoddesc}[container object]{__delitem__}{self, key} Called to implement deletion of \code{\var{self}[\var{key}]}. Same note as for \method{__getitem__()}. This should only be implemented *************** *** 1220,1223 **** --- 1222,1251 ---- \end{methoddesc} + \begin{methoddesc}[container object]{__iter__}{self} + This method is called when an iterator is required for a container. + This method should return a new iterator object that can iterate over + all the objects in the container. For mappings, it should iterate + over the keys of the container, and should also be made available as + the method \method{iterkeys()}. + + Iterator objects also need to implement this method; they are required + to return themselves. For more information on iterator objects, see + ``\ulink{Iterator Types}{../lib/typeiter.html}'' in the + \citetitle[../lib/lib.html]{Python Library Reference}. + \end{methoddesc} + + The membership test operators (\keyword{in} and \keyword{not in}) are + normally implemented as an iteration through a sequence. However, + container objects can supply the following special method with a more + efficient implementation, which also does not require the object be a + sequence. + + \begin{methoddesc}[container object]{__contains__}{self, item} + Called to implement membership test operators. Should return true if + \var{item} is in \var{self}, false otherwise. For mapping objects, + this should consider the keys of the mapping rather than the values or + the key-item pairs. + \end{methoddesc} + \subsection{Additional methods for emulation of sequence types *************** *** 1310,1323 **** the \method{__*item__()} methods. Calling \code{max(0, i)} conveniently returns the proper value. - - The membership test operators (\keyword{in} and \keyword{not in}) are - normally implemented as an iteration through the sequence. However, - sequence objects can supply the following special method with a more - efficient implementation: - - \begin{methoddesc}[sequence object]{__contains__}{self, item} - Called to implement membership test operators. Should return true if - \var{item} is in \var{self}, false otherwise. - \end{methoddesc} --- 1338,1341 ---- From gvanrossum@users.sourceforge.net Mon Oct 1 17:42:51 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 01 Oct 2001 09:42:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.80,2.81 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv6736 Modified Files: typeobject.c Log Message: slot_sq_length(): squash a leak. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.80 retrieving revision 2.81 diff -C2 -d -r2.80 -r2.81 *** typeobject.c 2001/10/01 15:55:28 2.80 --- typeobject.c 2001/10/01 16:42:49 2.81 *************** *** 2730,2737 **** static PyObject *len_str; PyObject *res = call_method(self, "__len__", &len_str, "()"); if (res == NULL) return -1; ! return (int)PyInt_AsLong(res); } --- 2730,2740 ---- static PyObject *len_str; PyObject *res = call_method(self, "__len__", &len_str, "()"); + int len; if (res == NULL) return -1; ! len = (int)PyInt_AsLong(res); ! Py_DECREF(res); ! return len; } From gvanrossum@users.sourceforge.net Mon Oct 1 18:18:24 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 01 Oct 2001 10:18:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.81,2.82 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv17948 Modified Files: typeobject.c Log Message: Miscellaneous code fiddling: - SLOT1BINFULL() macro: changed this to check for __rop__ overriding __op__, like binary_op1() in abstract.c -- the latter only calls the slot function once if both types use the same slot function, so the slot function must make both calls -- which it already did for the __op__, __rop__ order, but not yet for the __rop__, __op__ order when B.__class__ is a subclass of A.__class__. - slot_sq_contains(), slot_nb_nonzero(): use lookup_maybe() rather than lookup_method() which sets an exception which we then clear. - slot_nb_coerce(): don't give up when left argument's __coerce__ returns NotImplemented, but give the right argument a chance. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.81 retrieving revision 2.82 diff -C2 -d -r2.81 -r2.82 *** typeobject.c 2001/10/01 16:42:49 2.81 --- typeobject.c 2001/10/01 17:18:22 2.82 *************** *** 2694,2700 **** --- 2694,2712 ---- { \ static PyObject *cache_str, *rcache_str; \ + int do_other = self->ob_type != other->ob_type && \ + other->ob_type->tp_as_number != NULL && \ + other->ob_type->tp_as_number->SLOTNAME == TESTFUNC; \ if (self->ob_type->tp_as_number != NULL && \ self->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \ PyObject *r; \ + if (do_other && \ + PyType_IsSubtype(other->ob_type, self->ob_type)) { \ + r = call_maybe( \ + other, ROPSTR, &rcache_str, "(O)", self); \ + if (r != Py_NotImplemented) \ + return r; \ + Py_DECREF(r); \ + do_other = 0; \ + } \ r = call_maybe( \ self, OPSTR, &cache_str, "(O)", other); \ *************** *** 2704,2709 **** Py_DECREF(r); \ } \ ! if (other->ob_type->tp_as_number != NULL && \ ! other->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \ return call_maybe( \ other, ROPSTR, &rcache_str, "(O)", self); \ --- 2716,2720 ---- Py_DECREF(r); \ } \ ! if (do_other) { \ return call_maybe( \ other, ROPSTR, &rcache_str, "(O)", self); \ *************** *** 2786,2790 **** static PyObject *contains_str; ! func = lookup_method(self, "__contains__", &contains_str); if (func != NULL) { --- 2797,2801 ---- static PyObject *contains_str; ! func = lookup_maybe(self, "__contains__", &contains_str); if (func != NULL) { *************** *** 2801,2806 **** return PyObject_IsTrue(res); } else { - PyErr_Clear(); return _PySequence_IterSearch(self, value, PY_ITERSEARCH_CONTAINS); --- 2812,2818 ---- return PyObject_IsTrue(res); } + else if (PyErr_Occurred()) + return -1; else { return _PySequence_IterSearch(self, value, PY_ITERSEARCH_CONTAINS); *************** *** 2867,2887 **** static PyObject *nonzero_str, *len_str; ! func = lookup_method(self, "__nonzero__", &nonzero_str); if (func == NULL) { ! PyErr_Clear(); ! func = lookup_method(self, "__len__", &len_str); ! } ! ! if (func != NULL) { ! res = PyObject_CallObject(func, NULL); ! Py_DECREF(func); ! if (res == NULL) return -1; ! return PyObject_IsTrue(res); ! } ! else { ! PyErr_Clear(); ! return 1; } } --- 2879,2899 ---- static PyObject *nonzero_str, *len_str; ! func = lookup_maybe(self, "__nonzero__", &nonzero_str); if (func == NULL) { ! if (PyErr_Occurred()) return -1; ! func = lookup_maybe(self, "__len__", &len_str); ! if (func == NULL) { ! if (PyErr_Occurred()) ! return -1; ! else ! return 1; ! } } + res = PyObject_CallObject(func, NULL); + Py_DECREF(func); + if (res == NULL) + return -1; + return PyObject_IsTrue(res); } *************** *** 2908,2925 **** if (r == Py_NotImplemented) { Py_DECREF(r); - return 1; } ! if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) { ! PyErr_SetString(PyExc_TypeError, "__coerce__ didn't return a 2-tuple"); Py_DECREF(r); ! return -1; } - *a = PyTuple_GET_ITEM(r, 0); - Py_INCREF(*a); - *b = PyTuple_GET_ITEM(r, 1); - Py_INCREF(*b); - Py_DECREF(r); - return 0; } if (other->ob_type->tp_as_number != NULL && --- 2920,2938 ---- if (r == Py_NotImplemented) { Py_DECREF(r); } ! else { ! if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) { ! PyErr_SetString(PyExc_TypeError, "__coerce__ didn't return a 2-tuple"); + Py_DECREF(r); + return -1; + } + *a = PyTuple_GET_ITEM(r, 0); + Py_INCREF(*a); + *b = PyTuple_GET_ITEM(r, 1); + Py_INCREF(*b); Py_DECREF(r); ! return 0; } } if (other->ob_type->tp_as_number != NULL && From gvanrossum@users.sourceforge.net Mon Oct 1 18:10:21 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 01 Oct 2001 10:10:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.82,2.83 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv15540 Modified Files: abstract.c Log Message: binary_op1(), ternary_op(): rearrange the code so that slotw is tested (to see whether __rop__ should go before __op__) only when slotv is set. This saves a test+branch when only slotw is set. Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.82 retrieving revision 2.83 diff -C2 -d -r2.82 -r2.83 *** abstract.c 2001/09/30 05:58:41 2.82 --- abstract.c 2001/10/01 17:10:18 2.83 *************** *** 333,344 **** slotw = NULL; } - if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) { - x = slotw(v, w); - if (x != Py_NotImplemented) - return x; - Py_DECREF(x); /* can't do it */ - slotw = NULL; - } if (slotv) { x = slotv(v, w); if (x != Py_NotImplemented) --- 333,344 ---- slotw = NULL; } if (slotv) { + if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) { + x = slotw(v, w); + if (x != Py_NotImplemented) + return x; + Py_DECREF(x); /* can't do it */ + slotw = NULL; + } x = slotv(v, w); if (x != Py_NotImplemented) *************** *** 443,454 **** slotw = NULL; } - if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) { - x = slotw(v, w, z); - if (x != Py_NotImplemented) - return x; - Py_DECREF(x); /* can't do it */ - slotw = NULL; - } if (slotv) { x = slotv(v, w, z); if (x != Py_NotImplemented) --- 443,454 ---- slotw = NULL; } if (slotv) { + if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) { + x = slotw(v, w, z); + if (x != Py_NotImplemented) + return x; + Py_DECREF(x); /* can't do it */ + slotw = NULL; + } x = slotv(v, w, z); if (x != Py_NotImplemented) From fdrake@users.sourceforge.net Mon Oct 1 18:04:12 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 01 Oct 2001 10:04:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libcfgparser.tex,1.17,1.18 libdis.tex,1.32,1.33 libformatter.tex,1.21,1.22 libparser.tex,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv13570/lib Modified Files: libcfgparser.tex libdis.tex libformatter.tex libparser.tex Log Message: "boolean" --> "Boolean" (per the style guide). Index: libcfgparser.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcfgparser.tex,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** libcfgparser.tex 2001/09/28 16:57:16 1.17 --- libcfgparser.tex 2001/10/01 17:04:10 1.18 *************** *** 164,168 **** \begin{methoddesc}{getboolean}{section, option} A convenience method which coerces the \var{option} in the specified ! \var{section} to a boolean value. Note that the only accepted values for the option are \samp{0} and \samp{1}, any others will raise \exception{ValueError}. --- 164,168 ---- \begin{methoddesc}{getboolean}{section, option} A convenience method which coerces the \var{option} in the specified ! \var{section} to a Boolean value. Note that the only accepted values for the option are \samp{0} and \samp{1}, any others will raise \exception{ValueError}. Index: libdis.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdis.tex,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** libdis.tex 2001/04/13 17:25:38 1.32 --- libdis.tex 2001/10/01 17:04:10 1.33 *************** *** 103,107 **** \begin{datadesc}{hascompare} ! Sequence of byte codes of boolean operations. \end{datadesc} --- 103,107 ---- \begin{datadesc}{hascompare} ! Sequence of byte codes of Boolean operations. \end{datadesc} *************** *** 475,479 **** \begin{opcodedesc}{COMPARE_OP}{opname} ! Performs a boolean operation. The operation name can be found in \code{cmp_op[\var{opname}]}. \end{opcodedesc} --- 475,479 ---- \begin{opcodedesc}{COMPARE_OP}{opname} ! Performs a Boolean operation. The operation name can be found in \code{cmp_op[\var{opname}]}. \end{opcodedesc} Index: libformatter.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libformatter.tex,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** libformatter.tex 2001/07/14 02:50:55 1.21 --- libformatter.tex 2001/10/01 17:04:10 1.22 *************** *** 235,239 **** font that should be used; specific strings and their interpretation must be defined by the application. The \var{italic}, \var{bold}, and ! \var{teletype} values are boolean indicators specifying which of those font attributes should be used. \end{methoddesc} --- 235,239 ---- font that should be used; specific strings and their interpretation must be defined by the application. The \var{italic}, \var{bold}, and ! \var{teletype} values are Boolean values specifying which of those font attributes should be used. \end{methoddesc} Index: libparser.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libparser.tex,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** libparser.tex 2001/01/24 17:19:06 1.37 --- libparser.tex 2001/10/01 17:04:10 1.38 *************** *** 474,478 **** form, allowing a simple variable representation to be \code{['variable_name']}. A simple recursive function can implement ! the pattern matching, returning a boolean and a dictionary of variable name to value mappings. (See file \file{example.py}.) --- 474,478 ---- form, allowing a simple variable representation to be \code{['variable_name']}. A simple recursive function can implement ! the pattern matching, returning a Boolean and a dictionary of variable name to value mappings. (See file \file{example.py}.) From fdrake@users.sourceforge.net Mon Oct 1 18:04:12 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 01 Oct 2001 10:04:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/mac undoc.tex,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/mac In directory usw-pr-cvs1:/tmp/cvs-serv13570/mac Modified Files: undoc.tex Log Message: "boolean" --> "Boolean" (per the style guide). Index: undoc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/mac/undoc.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** undoc.tex 2001/09/12 00:43:13 1.6 --- undoc.tex 2001/10/01 17:04:10 1.7 *************** *** 29,35 **** applications} ! This module is primarily used as a help module for BuildApplet and ! BuildApplication. It is able to store compiled Python code as ! \texttt{'PYC '} resources in a file. --- 29,35 ---- applications} ! This module is primarily used as a help module for ! \program{BuildApplet} and \program{BuildApplication}. It is able to ! store compiled Python code as \texttt{'PYC~'} resources in a file. *************** *** 55,64 **** ! \section{\module{macerrors} --- MacOS Errors} \declaremodule{standard}{macerrors} \platform{Mac} ! \modulesynopsis{Constant definitions for many MacOS error codes} ! \module{macerrors} cotains constant definitions for many MacOS error codes. --- 55,64 ---- ! \section{\module{macerrors} --- Mac OS Errors} \declaremodule{standard}{macerrors} \platform{Mac} ! \modulesynopsis{Constant definitions for many Mac OS error codes} ! \module{macerrors} cotains constant definitions for many Mac OS error codes. *************** *** 99,103 **** \modulesynopsis{Easy access serial to line connections} ! This module is only available under MacOS 9 or earlier in classic PPC MacPython. \section{\module{mkcwproject} --- Create CodeWarrior projects} --- 99,104 ---- \modulesynopsis{Easy access serial to line connections} ! This module is only available under Mac OS 9 or earlier in classic PPC ! MacPython. \section{\module{mkcwproject} --- Create CodeWarrior projects} From loewis@users.sourceforge.net Mon Oct 1 18:04:05 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Mon, 01 Oct 2001 10:04:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.263,1.264 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv13480 Modified Files: NEWS Log Message: Undo last checkin. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.263 retrieving revision 1.264 diff -C2 -d -r1.263 -r1.264 *** NEWS 2001/10/01 10:09:30 1.263 --- NEWS 2001/10/01 17:04:03 1.264 *************** *** 16,21 **** which indicates whether output is intended for the header 'Q' encoding. - - Tkinter.Listbox now exposes itemcget and itemconfigure. - Tools --- 16,19 ---- From fdrake@users.sourceforge.net Mon Oct 1 18:03:50 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 01 Oct 2001 10:03:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libxmlrpclib.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv13430/lib Modified Files: libxmlrpclib.tex Log Message: Straighten out some markup. "boolean" --> "Boolean" (per the style guide). Index: libxmlrpclib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libxmlrpclib.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** libxmlrpclib.tex 2001/07/14 02:46:01 1.3 --- libxmlrpclib.tex 2001/10/01 17:03:48 1.4 *************** *** 220,227 **** \subsection{Convenience Functions} ! \begin{funcdesc}{boolean}{value, \optional{truefals=(False, True)}} ! Convert any Python value to one of the XML-RPC boolean constants. The optional second argument supplies a conversion table to be indexed ! by the first argument's Python truth value. \end{funcdesc} --- 220,228 ---- \subsection{Convenience Functions} ! \begin{funcdesc}{boolean}{value\optional{, truefalse}} ! Convert any Python value to one of the XML-RPC Boolean constants. The optional second argument supplies a conversion table to be indexed ! by the first argument's Python truth value. If omitted, the ! \code{True} and \code{False} values defined in this module are used. \end{funcdesc} From loewis@users.sourceforge.net Mon Oct 1 18:02:51 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Mon, 01 Oct 2001 10:02:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/lib-tk Tkinter.py,1.158,1.159 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory usw-pr-cvs1:/tmp/cvs-serv12903 Modified Files: Tkinter.py Log Message: Undo last checkin, since it duplicated the code. Index: Tkinter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/Tkinter.py,v retrieving revision 1.158 retrieving revision 1.159 diff -C2 -d -r1.158 -r1.159 *** Tkinter.py 2001/10/01 10:09:31 1.158 --- Tkinter.py 2001/10/01 17:02:49 1.159 *************** *** 2300,2328 **** if i == 'none': return None return getint(i) - def itemcget(self, index, option): - """Return the resource value for an ITEM and an OPTION.""" - return self.tk.call( - (self._w, 'itemcget') + (index, '-'+option)) - def itemconfigure(self, index, cnf=None, **kw): - """Configure resources of an ITEM. - - The values for resources are specified as keyword arguments. - To get an overview about the allowed keyword arguments - call the method without arguments. - Valid resource names: background, foreground, - selectbackground, selectforeground.""" - if cnf is None and not kw: - cnf = {} - for x in self.tk.split( - self.tk.call(self._w, 'itemconfigure', index)): - cnf[x[0][1:]] = (x[0][1:],) + x[1:] - return cnf - if type(cnf) == StringType and not kw: - x = self.tk.split(self.tk.call( - self._w, 'itemconfigure', index, '-'+cnf)) - return (x[0][1:],) + x[1:] - self.tk.call((self._w, 'itemconfigure', index) + - self._options(cnf, kw)) - itemconfig = itemconfigure def insert(self, index, *elements): """Insert ELEMENTS at INDEX.""" --- 2300,2303 ---- From fdrake@acm.org Mon Oct 1 18:34:20 2001 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Mon, 1 Oct 2001 13:34:20 -0400 Subject: [Python-checkins] CVS: python/dist/src/Doc/mac undoc.tex,1.6,1.7 In-Reply-To: References: Message-ID: <15288.43292.782948.723331@grendel.zope.com> Fred L. Drake writes: > Modified Files: > undoc.tex > Log Message: > "boolean" --> "Boolean" (per the style guide). Oops; this file wasn't supposed to be checked in with the others since the message should be different; sorry! I've corrected the message in the repository using "cvs admin -m". The real message is: Fix some minor style-guide conformance bugs. -Fred -- Fred L. Drake, Jr. PythonLabs at Zope Corporation From tim_one@users.sourceforge.net Mon Oct 1 18:58:42 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 01 Oct 2001 10:58:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules signalmodule.c,2.59,2.60 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv27419/python/Modules Modified Files: signalmodule.c Log Message: SF patch [#466877] SIGBREAK is missing from signal module. Patch from Steve Scott to add SIGBREAK support (unique to Windows). Index: signalmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/signalmodule.c,v retrieving revision 2.59 retrieving revision 2.60 diff -C2 -d -r2.59 -r2.60 *** signalmodule.c 2001/07/19 21:29:49 2.59 --- signalmodule.c 2001/10/01 17:58:40 2.60 *************** *** 384,387 **** --- 384,392 ---- Py_XDECREF(x); #endif + #ifdef SIGBREAK + x = PyInt_FromLong(SIGBREAK); + PyDict_SetItemString(d, "SIGBREAK", x); + Py_XDECREF(x); + #endif #ifdef SIGQUIT x = PyInt_FromLong(SIGQUIT); From montanaro@users.sourceforge.net Mon Oct 1 18:50:31 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Mon, 01 Oct 2001 10:50:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv25925 Modified Files: xmlrpclib.py Log Message: approximately double dump performance by moving import of cgi.escape back to top level. Index: xmlrpclib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xmlrpclib.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** xmlrpclib.py 2001/09/30 20:15:41 1.8 --- xmlrpclib.py 2001/10/01 17:50:29 1.9 *************** *** 137,140 **** --- 137,141 ---- import re, string, time, operator from types import * + from cgi import escape as _escape try: *************** *** 473,478 **** def dump_string(self, value): ! from cgi import escape ! self.write("%s\n" % escape(value)) dispatch[StringType] = dump_string --- 474,478 ---- def dump_string(self, value): ! self.write("%s\n" % _escape(value)) dispatch[StringType] = dump_string *************** *** 480,485 **** def dump_unicode(self, value): value = value.encode(self.encoding) ! from cgi import escape ! self.write("%s\n" % escape(value)) dispatch[UnicodeType] = dump_unicode --- 480,484 ---- def dump_unicode(self, value): value = value.encode(self.encoding) ! self.write("%s\n" % _escape(value)) dispatch[UnicodeType] = dump_unicode *************** *** 514,519 **** if type(k) is not StringType: raise TypeError, "dictionary key must be string" ! from cgi import escape ! write("%s\n" % escape(k)) self.__dump(v) write("\n") --- 513,517 ---- if type(k) is not StringType: raise TypeError, "dictionary key must be string" ! write("%s\n" % _escape(k)) self.__dump(v) write("\n") From montanaro@users.sourceforge.net Mon Oct 1 18:47:46 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Mon, 01 Oct 2001 10:47:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_xmlrpc.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv25288 Added Files: test_xmlrpc.py Log Message: simple dumps/loads test case for xmlrpclib --- NEW FILE: test_xmlrpc.py --- import test_support import unittest import xmlrpclib alist = [{'astring': 'foo@bar.baz.spam', 'afloat': 7283.43, 'anotherlist': ['.zyx.41'], 'abase64': xmlrpclib.Binary("my dog has fleas"), 'boolean': xmlrpclib.False, }] class XMLRPCTestCase(unittest.TestCase): def test_dump_load(self): self.assertEquals(alist, xmlrpclib.loads(xmlrpclib.dumps((alist,)))[0][0]) def test_main(): test_support.run_unittest(XMLRPCTestCase) if __name__ == "__main__": test_main() From tim_one@users.sourceforge.net Mon Oct 1 18:58:42 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 01 Oct 2001 10:58:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.114,1.115 NEWS,1.264,1.265 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv27419/python/Misc Modified Files: ACKS NEWS Log Message: SF patch [#466877] SIGBREAK is missing from signal module. Patch from Steve Scott to add SIGBREAK support (unique to Windows). Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.114 retrieving revision 1.115 diff -C2 -d -r1.114 -r1.115 *** ACKS 2001/10/01 13:47:46 1.114 --- ACKS 2001/10/01 17:58:40 1.115 *************** *** 363,366 **** --- 363,367 ---- Dietmar Schwertberger Barry Scott + Steven Scott Nick Seidenman Fred Sells Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.264 retrieving revision 1.265 diff -C2 -d -r1.264 -r1.265 *** NEWS 2001/10/01 17:04:03 1.264 --- NEWS 2001/10/01 17:58:40 1.265 *************** *** 32,35 **** --- 32,55 ---- Windows + - The signal module now supports SIGBREAK on Windows, thanks to Steven + Scott. Note that SIGBREAK is unique to Windows. The default SIGBREAK + action remains to call Win32 ExitProcess(). This can be changed via + signal.signal(). For example: + + # Make Ctrl+Break raise KeyboardInterrupt, like Python's default Ctrl+C + # (SIGINT) behavior. + import signal + signal.signal(signal.SIGBREAK, + signal.default_int_handler) + + try: + while 1: + pass + except KeyboardInterrupt: + # We get here on Ctrl+C or Ctrl+Break now; if we had not changed + # SIGBREAK, only on Ctrl+C (and Ctrl+Break would terminate the + # program without the possibility for any Python-level cleanup). + print "Clean exit" + What's New in Python 2.2a4? From effbot@users.sourceforge.net Mon Oct 1 20:42:05 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Mon, 01 Oct 2001 12:42:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv21782 Modified Files: xmlrpclib.py Log Message: restored 1.5.2 compatibility added local escape method (made the dumps method some 50-80% faster) minor tweaks to the unmarshalling code Index: xmlrpclib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xmlrpclib.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** xmlrpclib.py 2001/10/01 17:50:29 1.9 --- xmlrpclib.py 2001/10/01 19:42:03 1.10 *************** *** 32,35 **** --- 32,37 ---- # 2001-09-03 fl Allow Transport subclass to override getparser # 2001-09-10 fl Lazy import of urllib, cgi, xmllib (20x import speedup) + # 2001-10-01 fl Remove containers from memo cache when done with them + # 2001-10-01 fl Use faster escape method (80% dumps speedup) # # Copyright (c) 1999-2001 by Secret Labs AB. *************** *** 71,86 **** # things to look into before 1.0 final: - # TODO: unicode marshalling -DONE - # TODO: ascii-compatible encoding support -DONE - # TODO: safe transport -DONE (but mostly untested) - # TODO: sgmlop memory leak -DONE - # TODO: sgmlop xml parsing -DONE - # TODO: support unicode method names -DONE - # TODO: update selftest -DONE - # TODO: add docstrings -DONE - # TODO: clean up parser encoding (trust the parser) -DONE - # TODO: expat support -DONE - # TODO: _xmlrpclib accelerator support -DONE - # TODO: use smarter/faster escape from effdom # TODO: support basic authentication (see robin's patch) # TODO: fix host tuple handling in the server constructor --- 73,76 ---- *************** *** 88,92 **** # TODO: update documentation # TODO: authentication plugins - # TODO: memo problem (see HP's mail) """ --- 78,81 ---- *************** *** 135,141 **** """ ! import re, string, time, operator from types import * - from cgi import escape as _escape try: --- 124,130 ---- """ ! import re, string, sys, time, operator ! from types import * try: *************** *** 150,153 **** --- 139,147 ---- return data + def escape(s, replace=string.replace): + s = replace(s, "&", "&") + s = replace(s, "<", "<") + return replace(s, ">", ">",) + if unicode: def _stringify(string): *************** *** 161,165 **** return string ! __version__ = "1.0b3" # -------------------------------------------------------------------- --- 155,159 ---- return string ! __version__ = "1.0b4" # -------------------------------------------------------------------- *************** *** 473,487 **** dispatch[FloatType] = dump_double ! def dump_string(self, value): ! self.write("%s\n" % _escape(value)) dispatch[StringType] = dump_string if unicode: ! def dump_unicode(self, value): value = value.encode(self.encoding) ! self.write("%s\n" % _escape(value)) dispatch[UnicodeType] = dump_unicode ! def container(self, value): if value: i = id(value) --- 467,481 ---- dispatch[FloatType] = dump_double ! def dump_string(self, value, escape=escape): ! self.write("%s\n" % escape(value)) dispatch[StringType] = dump_string if unicode: ! def dump_unicode(self, value, escape=escape): value = value.encode(self.encoding) ! self.write("%s\n" % escape(value)) dispatch[UnicodeType] = dump_unicode ! def opencontainer(self, value): if value: i = id(value) *************** *** 490,511 **** self.memo[i] = None ! def endcontainer(self, value): if value: del self.memo[id(value)] def dump_array(self, value): ! self.container(value) write = self.write write("\n") for v in value: ! self.__dump(v) write("\n") ! self.endcontainer(value) dispatch[TupleType] = dump_array dispatch[ListType] = dump_array ! def dump_struct(self, value): ! self.container(value) write = self.write write("\n") for k, v in value.items(): --- 484,507 ---- self.memo[i] = None ! def closecontainer(self, value): if value: del self.memo[id(value)] def dump_array(self, value): ! self.opencontainer(value) write = self.write + dump = self.__dump write("\n") for v in value: ! dump(v) write("\n") ! self.closecontainer(value) dispatch[TupleType] = dump_array dispatch[ListType] = dump_array ! def dump_struct(self, value, escape=escape): ! self.opencontainer(value) write = self.write + dump = self.__dump write("\n") for k, v in value.items(): *************** *** 513,521 **** if type(k) is not StringType: raise TypeError, "dictionary key must be string" ! write("%s\n" % _escape(k)) ! self.__dump(v) write("\n") write("\n") ! self.endcontainer(value) dispatch[DictType] = dump_struct --- 509,517 ---- if type(k) is not StringType: raise TypeError, "dictionary key must be string" ! write("%s\n" % escape(k)) ! dump(v) write("\n") write("\n") ! self.closecontainer(value) dispatch[DictType] = dump_struct *************** *** 578,582 **** self._data.append(text) ! def end(self, tag): # call the appropriate end tag handler try: --- 574,578 ---- self._data.append(text) ! def end(self, tag, join=string.join): # call the appropriate end tag handler try: *************** *** 585,589 **** pass # unknown tag ? else: ! return f(self, self._data) # --- 581,585 ---- pass # unknown tag ? else: ! return f(self, join(self._data, "")) # *************** *** 604,609 **** dispatch = {} ! def end_boolean(self, data, join=string.join): ! data = join(data, "") if data == "0": self.append(False) --- 600,604 ---- dispatch = {} ! def end_boolean(self, data): if data == "0": self.append(False) *************** *** 615,631 **** dispatch["boolean"] = end_boolean ! def end_int(self, data, join=string.join): ! self.append(int(join(data, ""))) self._value = 0 dispatch["i4"] = end_int dispatch["int"] = end_int ! def end_double(self, data, join=string.join): ! self.append(float(join(data, ""))) self._value = 0 dispatch["double"] = end_double ! def end_string(self, data, join=string.join): ! data = join(data, "") if self._encoding: data = _decode(data, self._encoding) --- 610,625 ---- dispatch["boolean"] = end_boolean ! def end_int(self, data): ! self.append(int(data)) self._value = 0 dispatch["i4"] = end_int dispatch["int"] = end_int ! def end_double(self, data): ! self.append(float(data)) self._value = 0 dispatch["double"] = end_double ! def end_string(self, data): if self._encoding: data = _decode(data, self._encoding) *************** *** 655,668 **** dispatch["struct"] = end_struct ! def end_base64(self, data, join=string.join): value = Binary() ! value.decode(join(data, "")) self.append(value) self._value = 0 dispatch["base64"] = end_base64 ! def end_dateTime(self, data, join=string.join): value = DateTime() ! value.decode(join(data, "")) self.append(value) dispatch["dateTime.iso8601"] = end_dateTime --- 649,662 ---- dispatch["struct"] = end_struct ! def end_base64(self, data): value = Binary() ! value.decode(data) self.append(value) self._value = 0 dispatch["base64"] = end_base64 ! def end_dateTime(self, data): value = DateTime() ! value.decode(data) self.append(value) dispatch["dateTime.iso8601"] = end_dateTime *************** *** 683,688 **** dispatch["fault"] = end_fault ! def end_methodName(self, data, join=string.join): ! data = join(data, "") if self._encoding: data = _decode(data, self._encoding) --- 677,681 ---- dispatch["fault"] = end_fault ! def end_methodName(self, data): if self._encoding: data = _decode(data, self._encoding) From tim_one@users.sourceforge.net Mon Oct 1 20:50:09 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 01 Oct 2001 12:50:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include pyport.h,2.36,2.37 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv23560/python/Include Modified Files: pyport.h Log Message: SF patch [#466353] Py_HUGE_VAL on BeOS for Intel. The patch repaired internal gcc compiler errors on BeOS. This checkin repairs them in a simpler way, by explicitly casting the platform INFINITY to double. Index: pyport.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pyport.h,v retrieving revision 2.36 retrieving revision 2.37 diff -C2 -d -r2.36 -r2.37 *** pyport.h 2001/09/05 22:36:55 2.36 --- pyport.h 2001/10/01 19:50:06 2.37 *************** *** 236,242 **** * defined to be the largest positive finite rather than infinity. We need * the std-conforming infinity meaning (provided the platform has one!). */ #ifdef INFINITY ! #define Py_HUGE_VAL INFINITY #else #define Py_HUGE_VAL HUGE_VAL --- 236,246 ---- * defined to be the largest positive finite rather than infinity. We need * the std-conforming infinity meaning (provided the platform has one!). + * + * Then, according to a bug report on SourceForge, defining Py_HUGE_VAL as + * INFINITY caused internal compiler errors under BeOS using some version + * of gcc. Explicitly casting INFINITY to double made that problem go away. */ #ifdef INFINITY ! #define Py_HUGE_VAL ((double)INFINITY) #else #define Py_HUGE_VAL HUGE_VAL From tim_one@users.sourceforge.net Mon Oct 1 21:22:47 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 01 Oct 2001 13:22:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref5.tex,1.49,1.50 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv31378/python/Doc/ref Modified Files: ref5.tex Log Message: The description of dictionary comparison was out of date. Rather than try to explain the complex general scheme we actually use now, I decided to spell out only what equality means (which is easy to explain and intuitive), leaving the other outcomes unspecified beyond consistency. Index: ref5.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref5.tex,v retrieving revision 1.49 retrieving revision 1.50 diff -C2 -d -r1.49 -r1.50 *** ref5.tex 2001/07/06 22:49:53 1.49 --- ref5.tex 2001/10/01 20:22:45 1.50 *************** *** 192,199 **** order. When a list comprehension is supplied, it consists of a single expression followed by at least one \keyword{for} clause and zero or ! more \keyword{for} or \keyword{if} clauses. In this case, the elements of the new list are those that would be produced by considering each of the \keyword{for} or \keyword{if} clauses a block, ! nesting from left to right, and evaluating the expression to produce a list element each time the innermost block is reached. --- 192,199 ---- order. When a list comprehension is supplied, it consists of a single expression followed by at least one \keyword{for} clause and zero or ! more \keyword{for} or \keyword{if} clauses. In this case, the elements of the new list are those that would be produced by considering each of the \keyword{for} or \keyword{if} clauses a block, ! nesting from left to right, and evaluating the expression to produce a list element each time the innermost block is reached. *************** *** 816,826 **** \item ! Mappings (dictionaries) are compared through lexicographic ! comparison of their sorted (key, value) lists.\footnote{ ! This is expensive since it requires sorting the keys first, ! but it is about the only sensible definition. An earlier version of ! Python compared dictionaries by identity only, but this caused ! surprises because people expected to be able to test a dictionary for ! emptiness by comparing it to \code{\{\}}.} \item --- 816,829 ---- \item ! Mappings (dictionaries) compare equal if and only if their sorted ! (key, value) lists compare equal.\footnote{The implementation computes ! this efficiently, without constructing lists or sorting.} ! Outcomes other than equality are resolved consistently, but are not ! otherwise defined.\footnote{Earlier versions of Python used\ ! lexicographic comparison of the sorted (key, value) lists, but this ! was very expensive for the common case of comparing for equality. An ! even earlier version of Python compared dictionaries by identity only, ! but this caused surprises because people expected to be able to test ! a dictionary for emptiness by comparing it to \code{\{\}}.} \item From tim_one@users.sourceforge.net Mon Oct 1 21:25:28 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 01 Oct 2001 13:25:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref5.tex,1.50,1.51 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv752/python/Doc/ref Modified Files: ref5.tex Log Message: Removed stray backslash (a typo -- my fault). Index: ref5.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref5.tex,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -d -r1.50 -r1.51 *** ref5.tex 2001/10/01 20:22:45 1.50 --- ref5.tex 2001/10/01 20:25:26 1.51 *************** *** 820,824 **** this efficiently, without constructing lists or sorting.} Outcomes other than equality are resolved consistently, but are not ! otherwise defined.\footnote{Earlier versions of Python used\ lexicographic comparison of the sorted (key, value) lists, but this was very expensive for the common case of comparing for equality. An --- 820,824 ---- this efficiently, without constructing lists or sorting.} Outcomes other than equality are resolved consistently, but are not ! otherwise defined.\footnote{Earlier versions of Python used lexicographic comparison of the sorted (key, value) lists, but this was very expensive for the common case of comparing for equality. An From fdrake@users.sourceforge.net Mon Oct 1 22:05:33 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 01 Oct 2001 14:05:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libxmlrpclib.tex,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv11958/lib Modified Files: libxmlrpclib.tex Log Message: Fredrik tells me the truefalse parameter for boolean() is not part of the public interface, so we can simplify the documentation. Index: libxmlrpclib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libxmlrpclib.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** libxmlrpclib.tex 2001/10/01 17:03:48 1.4 --- libxmlrpclib.tex 2001/10/01 21:05:30 1.5 *************** *** 220,228 **** \subsection{Convenience Functions} ! \begin{funcdesc}{boolean}{value\optional{, truefalse}} ! Convert any Python value to one of the XML-RPC Boolean constants. ! The optional second argument supplies a conversion table to be indexed ! by the first argument's Python truth value. If omitted, the ! \code{True} and \code{False} values defined in this module are used. \end{funcdesc} --- 220,226 ---- \subsection{Convenience Functions} ! \begin{funcdesc}{boolean}{value} ! Convert any Python value to one of the XML-RPC Boolean constants, ! \code{True} or \code{False}. \end{funcdesc} From tim_one@users.sourceforge.net Tue Oct 2 04:53:43 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 01 Oct 2001 20:53:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_pyclbr.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv5055/python/Lib/test Modified Files: test_pyclbr.py Log Message: SF patch [#466616] Exclude imported items from doctest, from Tim Hochberg. Also mucho fiddling to change the way doctest determines whether a thing is a function, module or class. Under 2.2, this really requires the functions in inspect.py (e.g., types.ClassType is close to meaningless now, if not outright misleading). Index: test_pyclbr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pyclbr.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_pyclbr.py 2001/09/20 21:33:42 1.4 --- test_pyclbr.py 2001/10/02 03:53:41 1.5 *************** *** 33,37 **** ''' succeed iff hasattr(obj,attr) or attr in ignore. ''' if attr in ignore: return ! if not hasattr(obj, attr): print "???",attr self.failUnless(hasattr(obj, attr)) --- 33,37 ---- ''' succeed iff hasattr(obj,attr) or attr in ignore. ''' if attr in ignore: return ! if not hasattr(obj, attr): print "???", attr self.failUnless(hasattr(obj, attr)) *************** *** 101,105 **** def test_easy(self): self.checkModule('pyclbr') ! self.checkModule('doctest') self.checkModule('rfc822') self.checkModule('xmllib') --- 101,106 ---- def test_easy(self): self.checkModule('pyclbr') ! self.checkModule('doctest', ! ignore=['_isclass', '_isfunction', '_ismodule']) self.checkModule('rfc822') self.checkModule('xmllib') From tim_one@users.sourceforge.net Tue Oct 2 04:53:43 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 01 Oct 2001 20:53:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.265,1.266 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv5055/python/Misc Modified Files: NEWS Log Message: SF patch [#466616] Exclude imported items from doctest, from Tim Hochberg. Also mucho fiddling to change the way doctest determines whether a thing is a function, module or class. Under 2.2, this really requires the functions in inspect.py (e.g., types.ClassType is close to meaningless now, if not outright misleading). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.265 retrieving revision 1.266 diff -C2 -d -r1.265 -r1.266 *** NEWS 2001/10/01 17:58:40 1.265 --- NEWS 2001/10/02 03:53:41 1.266 *************** *** 13,16 **** --- 13,19 ---- Library + - doctest now excludes functions and classes not defined by the module + being tested, thanks to Tim Hochberg. + - quopri's encode and decode methods take an optional header parameter, which indicates whether output is intended for the header 'Q' encoding. From tim_one@users.sourceforge.net Tue Oct 2 04:53:43 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 01 Oct 2001 20:53:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib doctest.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv5055/python/Lib Modified Files: doctest.py Log Message: SF patch [#466616] Exclude imported items from doctest, from Tim Hochberg. Also mucho fiddling to change the way doctest determines whether a thing is a function, module or class. Under 2.2, this really requires the functions in inspect.py (e.g., types.ClassType is close to meaningless now, if not outright misleading). Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** doctest.py 2001/08/18 00:05:50 1.17 --- doctest.py 2001/10/02 03:53:41 1.18 *************** *** 49,56 **** + f.__doc__ for all functions f in M.__dict__.values(), except those ! with private names. + C.__doc__ for all classes C in M.__dict__.values(), except those with ! private names. + If M.__test__ exists and "is true", it must be a dict, and --- 49,56 ---- + f.__doc__ for all functions f in M.__dict__.values(), except those ! with private names and those defined in other modules. + C.__doc__ for all classes C in M.__dict__.values(), except those with ! private names and those defined in other modules. + If M.__test__ exists and "is true", it must be a dict, and *************** *** 76,101 **** of a Tester instance). - Warning: imports can cause trouble; e.g., if you do - - from XYZ import XYZclass - - then XYZclass is a name in M.__dict__ too, and doctest has no way to know - that XYZclass wasn't *defined* in M. So it may try to execute the examples - in XYZclass's docstring, and those in turn may require a different set of - globals to work correctly. I prefer to do "import *"- friendly imports, - a la - - import XYY - _XYZclass = XYZ.XYZclass - del XYZ - - or (Python 2.0) - - from XYZ import XYZclass as _XYZclass - - and then the leading underscore stops testmod from going nuts. You may - prefer the method in the next section. - - WHAT'S THE EXECUTION CONTEXT? --- 76,79 ---- *************** *** 304,314 **** import __future__ - import types - _FunctionType = types.FunctionType - _ClassType = types.ClassType - _ModuleType = types.ModuleType - _StringType = types.StringType - del types - import re PS1 = ">>>" --- 282,285 ---- *************** *** 320,323 **** --- 291,300 ---- del re + from types import StringTypes as _StringTypes + + from inspect import isclass as _isclass + from inspect import isfunction as _isfunction + from inspect import ismodule as _ismodule + # Extract interactive examples from a string. Return a list of triples, # (source, outcome, lineno). "source" is the source code, and ends *************** *** 575,578 **** --- 552,564 ---- return base[:1] == "_" and not base[:2] == "__" == base[-2:] + # Determine if a class of function was defined in the given module. + + def _from_module(module, object): + if _isfunction(object): + return module.__dict__ is object.func_globals + if _isclass(object): + return module.__name__ == object.__module__ + raise ValueError("object must be a class or function") + class Tester: """Class Tester -- runs docstring examples and accumulates stats. *************** *** 591,597 **** object.__name__) for logging. Return (#failures, #tries). ! rundict(d, name) Search for examples in docstrings in all of d.values(); use name ! for logging. Return (#failures, #tries). run__test__(d, name) --- 577,584 ---- object.__name__) for logging. Return (#failures, #tries). ! rundict(d, name, module=None) Search for examples in docstrings in all of d.values(); use name ! for logging. Exclude functions and classes not defined in module ! if specified. Return (#failures, #tries). run__test__(d, name) *************** *** 665,669 **** if mod is None and globs is None: raise TypeError("Tester.__init__: must specify mod or globs") ! if mod is not None and type(mod) is not _ModuleType: raise TypeError("Tester.__init__: mod must be a module; " + `mod`) --- 652,656 ---- if mod is None and globs is None: raise TypeError("Tester.__init__: must specify mod or globs") ! if mod is not None and not _ismodule(mod): raise TypeError("Tester.__init__: mod must be a module; " + `mod`) *************** *** 760,764 **** print f, "of", t, "examples failed in", name + ".__doc__" self.__record_outcome(name, f, t) ! if type(object) is _ClassType: f2, t2 = self.rundict(object.__dict__, name) f = f + f2 --- 747,751 ---- print f, "of", t, "examples failed in", name + ".__doc__" self.__record_outcome(name, f, t) ! if _isclass(object): f2, t2 = self.rundict(object.__dict__, name) f = f + f2 *************** *** 766,792 **** return f, t ! def rundict(self, d, name): """ ! d. name -> search for docstring examples in all of d.values(). For k, v in d.items() such that v is a function or class, do self.rundoc(v, name + "." + k). Whether this includes objects with private names depends on the constructor's ! "isprivate" argument. Return aggregate (#failures, #examples). ! >>> def _f(): ! ... '''>>> assert 1 == 1 ! ... ''' ! >>> def g(): ... '''>>> assert 2 != 1 ... ''' ! >>> d = {"_f": _f, "g": g} >>> t = Tester(globs={}, verbose=0) ! >>> t.rundict(d, "rundict_test") # _f is skipped ! (0, 1) >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0) ! >>> t.rundict(d, "rundict_test_pvt") # both are searched ! (0, 2) """ --- 753,809 ---- return f, t ! def rundict(self, d, name, module=None): """ ! d, name, module=None -> search for docstring examples in d.values(). For k, v in d.items() such that v is a function or class, do self.rundoc(v, name + "." + k). Whether this includes objects with private names depends on the constructor's ! "isprivate" argument. If module is specified, functions and ! classes that are not defined in module are excluded. Return aggregate (#failures, #examples). ! Build and populate two modules with sample functions to test that ! exclusion of external functions and classes works. ! ! >>> import new ! >>> m1 = new.module('_m1') ! >>> m2 = new.module('_m2') ! >>> test_data = \""" ! ... def f(): ! ... '''>>> assert 1 == 1 ! ... ''' ! ... def g(): ... '''>>> assert 2 != 1 ... ''' ! ... class H: ! ... '''>>> assert 2 > 1 ! ... ''' ! ... def bar(self): ! ... '''>>> assert 1 < 2 ! ... ''' ! ... \""" ! >>> exec test_data in m1.__dict__ ! >>> exec test_data in m2.__dict__ ! ! Tests that objects outside m1 are excluded: ! ! >>> d = {"_f": m1.f, "g": m1.g, "h": m1.H, ! ... "f2": m2.f, "g2": m2.g, "h2": m2.H} >>> t = Tester(globs={}, verbose=0) ! >>> t.rundict(d, "rundict_test", m1) # _f, f2 and g2 and h2 skipped ! (0, 3) ! ! Again, but with a custom isprivate function allowing _f: ! >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0) ! >>> t.rundict(d, "rundict_test_pvt", m1) # Only f2, g2 and h2 skipped ! (0, 4) ! ! And once more, not excluding stuff outside m1: ! ! >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0) ! >>> t.rundict(d, "rundict_test_pvt") # None are skipped. ! (0, 8) """ *************** *** 801,805 **** for thisname in names: value = d[thisname] ! if type(value) in (_FunctionType, _ClassType): f2, t2 = self.__runone(value, name + "." + thisname) f = f + f2 --- 818,824 ---- for thisname in names: value = d[thisname] ! if _isfunction(value) or _isclass(value): ! if module and not _from_module(module, value): ! continue f2, t2 = self.__runone(value, name + "." + thisname) f = f + f2 *************** *** 826,832 **** v = d[k] thisname = prefix + k ! if type(v) is _StringType: f, t = self.runstring(v, thisname) ! elif type(v) in (_FunctionType, _ClassType): f, t = self.rundoc(v, thisname) else: --- 845,851 ---- v = d[k] thisname = prefix + k ! if type(v) in _StringTypes: f, t = self.runstring(v, thisname) ! elif _isfunction(v) or _isclass(v): f, t = self.rundoc(v, thisname) else: *************** *** 1013,1017 **** global master ! if type(m) is not _ModuleType: raise TypeError("testmod: module required; " + `m`) if name is None: --- 1032,1036 ---- global master ! if not _ismodule(m): raise TypeError("testmod: module required; " + `m`) if name is None: From gvanrossum@users.sourceforge.net Tue Oct 2 14:05:43 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 02 Oct 2001 06:05:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/dns README,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Demo/dns In directory usw-pr-cvs1:/tmp/cvs-serv4107 Modified Files: README Log Message: Update reference to pydns. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/dns/README,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** README 1998/04/27 14:14:41 1.2 --- README 2001/10/02 13:05:41 1.3 *************** *** 9,16 **** documentation :-). ! Anthony Baxter maintains an enhanced version of this code at ! ! http://alumni.dgs.monash.edu.au/~anthony/python/ ! --Guido van Rossum, CWI, Amsterdam ! URL: --- 9,14 ---- documentation :-). ! NOTE: This code has been evolved into a much more enhanced package by ! Anthony Baxter; see the pydns project at SourceForge: ! http://sourceforge.net/projects/pydns/ From gvanrossum@users.sourceforge.net Tue Oct 2 19:27:11 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 02 Oct 2001 11:27:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib site.py,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv20678 Modified Files: site.py Log Message: Correct the URL for the license (only used when the LICENSE[.txt] file is not found). Being fancy: insert the first 3 characters of sys.version in the URL. Index: site.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/site.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** site.py 2001/08/17 18:39:24 1.35 --- site.py 2001/10/02 18:27:09 1.36 *************** *** 268,272 **** here = os.path.dirname(os.__file__) __builtin__.license = _Printer( ! "license", "See http://www.pythonlabs.com/products/python2.0/license.html", ["LICENSE.txt", "LICENSE"], [os.path.join(here, os.pardir), here, os.curdir]) --- 268,272 ---- here = os.path.dirname(os.__file__) __builtin__.license = _Printer( ! "license", "See http://www.python.org/%.3s/license.html" % sys.version, ["LICENSE.txt", "LICENSE"], [os.path.join(here, os.pardir), here, os.curdir]) From gvanrossum@users.sourceforge.net Tue Oct 2 19:33:14 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 02 Oct 2001 11:33:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv21937 Modified Files: xmlrpclib.py Log Message: Under certain conditions (sometimes triggered by the test suite), "from xml.parsers import expat" succeeds but the imported expat module is an empty shell. Make sure we don't be fooled by that. Index: xmlrpclib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xmlrpclib.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** xmlrpclib.py 2001/10/01 19:42:03 1.10 --- xmlrpclib.py 2001/10/02 18:33:11 1.11 *************** *** 362,365 **** --- 362,367 ---- try: from xml.parsers import expat + if not hasattr(expat, "ParserCreate"): + raise ImportError, "ParserCreate" except ImportError: ExpatParser = None From gvanrossum@users.sourceforge.net Tue Oct 2 20:49:49 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 02 Oct 2001 12:49:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_gc.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv8698 Modified Files: test_gc.py Log Message: The error reporting here was a bit sparse. In verbose mode, the code in run_test() referenced two non-existent variables, and in non-verbose mode, the tests didn't report the actual number, when it differed from the expected number. Fixed this. Also added an extra call to gc.collect() at the start of test_all(). This will be needed when I check in the changes to add GC to new-style classes. Index: test_gc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_gc.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_gc.py 2001/07/12 13:25:53 1.8 --- test_gc.py 2001/10/02 19:49:47 1.9 *************** *** 3,19 **** import gc def run_test(name, thunk): if verbose: print "testing %s..." % name, ! try: ! thunk() ! except TestFailed: ! if verbose: ! print "failed (expected %s but got %s)" % (result, ! test_result) ! raise TestFailed, name ! else: ! if verbose: ! print "ok" def test_list(): --- 3,21 ---- import gc + def expect(actual, expected, name): + if actual != expected: + raise TestFailed, "test_%s: actual %d, expected %d" % ( + name, actual, expected) + + def expect_not(actual, expected, name): + if actual == expected: + raise TestFailed, "test_%s: actual %d unexpected" % (name, actual) + def run_test(name, thunk): if verbose: print "testing %s..." % name, ! thunk() ! if verbose: ! print "ok" def test_list(): *************** *** 22,27 **** gc.collect() del l ! if gc.collect() != 1: ! raise TestFailed def test_dict(): --- 24,28 ---- gc.collect() del l ! expect(gc.collect(), 1, "list") def test_dict(): *************** *** 30,35 **** gc.collect() del d ! if gc.collect() != 1: ! raise TestFailed def test_tuple(): --- 31,35 ---- gc.collect() del d ! expect(gc.collect(), 1, "dict") def test_tuple(): *************** *** 41,46 **** del t del l ! if gc.collect() != 2: ! raise TestFailed def test_class(): --- 41,45 ---- del t del l ! expect(gc.collect(), 2, "tuple") def test_class(): *************** *** 50,55 **** gc.collect() del A ! if gc.collect() == 0: ! raise TestFailed def test_instance(): --- 49,53 ---- gc.collect() del A ! expect_not(gc.collect(), 0, "class") def test_instance(): *************** *** 60,65 **** gc.collect() del a ! if gc.collect() == 0: ! raise TestFailed def test_method(): --- 58,62 ---- gc.collect() del a ! expect_not(gc.collect(), 0, "instance") def test_method(): *************** *** 71,76 **** gc.collect() del a ! if gc.collect() == 0: ! raise TestFailed def test_finalizer(): --- 68,72 ---- gc.collect() del a ! expect_not(gc.collect(), 0, "method") def test_finalizer(): *************** *** 89,94 **** del a del b ! if gc.collect() == 0: ! raise TestFailed for obj in gc.garbage: if id(obj) == id_a: --- 85,89 ---- del a del b ! expect_not(gc.collect(), 0, "finalizer") for obj in gc.garbage: if id(obj) == id_a: *************** *** 96,100 **** break else: ! raise TestFailed gc.garbage.remove(obj) --- 91,95 ---- break else: ! raise TestFailed, "didn't find obj in garbage (finalizer)" gc.garbage.remove(obj) *************** *** 106,111 **** gc.collect() del d ! if gc.collect() != 2: ! raise TestFailed def test_frame(): --- 101,105 ---- gc.collect() del d ! expect(gc.collect(), 2, "function") def test_frame(): *************** *** 114,119 **** gc.collect() f() ! if gc.collect() != 1: ! raise TestFailed --- 108,112 ---- gc.collect() f() ! expect(gc.collect(), 1, "frame") *************** *** 134,138 **** break else: ! raise TestFailed gc.garbage.remove(obj) finally: --- 127,131 ---- break else: ! raise TestFailed, "didn't find obj in garbage (saveall)" gc.garbage.remove(obj) finally: *************** *** 156,159 **** --- 149,153 ---- def test_all(): + gc.collect() # Delete 2nd generation garbage run_test("lists", test_list) run_test("dicts", test_dict) From gvanrossum@users.sourceforge.net Tue Oct 2 20:58:34 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 02 Oct 2001 12:58:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.79,1.80 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv10734 Modified Files: test_descr.py Log Message: pickles(): - The test for deepcopy() in pickles() was indented wrongly, so it got run twice (one for binary pickle mode, one for text pickle mode; but the test doesn't depend on the pickle mode). - In verbose mode, show which subtest (pickle/cPickle/deepcopy, text/bin). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.79 retrieving revision 1.80 diff -C2 -d -r1.79 -r1.80 *** test_descr.py 2001/09/29 00:40:25 1.79 --- test_descr.py 2001/10/02 19:58:32 1.80 *************** *** 2082,2085 **** --- 2082,2087 ---- for p in pickle, cPickle: for bin in 0, 1: + if verbose: + print p.__name__, ["text", "binary"][bin] for cls in C, C1, C2: *************** *** 2102,2123 **** print "b = y =", b ! # Testing copy.deepcopy() ! import copy ! for cls in C, C1, C2: ! cls2 = copy.deepcopy(cls) ! verify(cls2 is cls) ! a = C1(1, 2); a.append(42); a.append(24) ! b = C2("hello", "world", 42) ! x, y = copy.deepcopy((a, b)) ! assert x.__class__ == a.__class__ ! assert sorteditems(x.__dict__) == sorteditems(a.__dict__) ! assert y.__class__ == b.__class__ ! assert sorteditems(y.__dict__) == sorteditems(b.__dict__) ! assert `x` == `a` ! assert `y` == `b` ! if verbose: ! print "a = x =", a ! print "b = y =", b def copies(): --- 2104,2127 ---- print "b = y =", b ! # Testing copy.deepcopy() ! if verbose: ! print "deepcopy" ! import copy ! for cls in C, C1, C2: ! cls2 = copy.deepcopy(cls) ! verify(cls2 is cls) ! a = C1(1, 2); a.append(42); a.append(24) ! b = C2("hello", "world", 42) ! x, y = copy.deepcopy((a, b)) ! assert x.__class__ == a.__class__ ! assert sorteditems(x.__dict__) == sorteditems(a.__dict__) ! assert y.__class__ == b.__class__ ! assert sorteditems(y.__dict__) == sorteditems(b.__dict__) ! assert `x` == `a` ! assert `y` == `b` ! if verbose: ! print "a = x =", a ! print "b = y =", b def copies(): From tim_one@users.sourceforge.net Tue Oct 2 22:01:24 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 02 Oct 2001 14:01:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libdoctest.tex,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv26155/python/Doc/lib Modified Files: libdoctest.tex Log Message: CVS patch [#466628] Doc changes for doctest patch (#466616), from Tim Hochberg. Doctest no longer searches imported objects. Index: libdoctest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdoctest.tex,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** libdoctest.tex 2001/06/11 14:55:01 1.8 --- libdoctest.tex 2001/10/02 21:01:22 1.9 *************** *** 187,191 **** module docstring, and all function, class and method docstrings are searched, with the exception of docstrings attached to objects with private ! names. In addition, if \code{M.__test__} exists and "is true", it must be a --- 187,191 ---- module docstring, and all function, class and method docstrings are searched, with the exception of docstrings attached to objects with private ! names. Objects imported into the module are not searched. In addition, if \code{M.__test__} exists and "is true", it must be a *************** *** 212,218 **** \module{M} can't leave behind crumbs that accidentally allow another test to work. This means examples can freely use any names defined at top-level ! in \module{M}, and names defined earlier in the docstring being run. It ! also means that sloppy imports (see below) can cause examples in external ! docstrings to use globals inappropriate for them. You can force use of your own dict as the execution context by passing --- 212,216 ---- \module{M} can't leave behind crumbs that accidentally allow another test to work. This means examples can freely use any names defined at top-level ! in \module{M}, and names defined earlier in the docstring being run. You can force use of your own dict as the execution context by passing *************** *** 320,344 **** \begin{enumerate} - - \item Sloppy imports can cause trouble; e.g., if you do - - \begin{verbatim} - from XYZ import XYZclass - \end{verbatim} - - then \class{XYZclass} is a name in \code{M.__dict__} too, and doctest - has no way to know that \class{XYZclass} wasn't \emph{defined} in - \module{M}. So it may try to execute the examples in - \class{XYZclass}'s docstring, and those in turn may require a - different set of globals to work correctly. I prefer to do - ``\code{import *}''-friendly imports, a la - - \begin{verbatim} - from XYZ import XYZclass as _XYZclass - \end{verbatim} - - and then the leading underscore makes \class{_XYZclass} a private name so - testmod skips it by default. Other approaches are described in - \file{doctest.py}. \item \module{doctest} is serious about requiring exact matches in expected --- 318,321 ---- From gvanrossum@users.sourceforge.net Tue Oct 2 22:24:59 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 02 Oct 2001 14:24:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_gc.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv30352/Lib/test Modified Files: test_gc.py Log Message: Add Garbage Collection support to new-style classes (not yet to their instances). Also added GC support to various auxiliary types: super, property, descriptors, wrappers, dictproxy. (Only type objects have a tp_clear field; the other types are.) One change was necessary to the GC infrastructure. We have statically allocated type objects that don't have a GC header (and can't easily be given one) and heap-allocated type objects that do have a GC header. Giving these different metatypes would be really ugly: I tried, and I had to modify pickle.py, cPickle.c, copy.py, add a new invent a new name for the new metatype and make it a built-in, change affected tests... In short, a mess. So instead, we add a new type slot tp_is_gc, which is a simple Boolean function that determines whether a particular instance has GC headers or not. This slot is only relevant for types that have the (new) GC flag bit set. If the tp_is_gc slot is NULL (by far the most common case), all instances of the type are deemed to have GC headers. This slot is called by the PyObject_IS_GC() macro (which is only used twice, both times in gcmodule.c). I also changed the extern declarations for a bunch of GC-related functions (_PyObject_GC_Del etc.): these always exist but objimpl.h only declared them when WITH_CYCLE_GC was defined, but I needed to be able to reference them without #ifdefs. (When WITH_CYCLE_GC is not defined, they do the same as their non-GC counterparts anyway.) Index: test_gc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_gc.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_gc.py 2001/10/02 19:49:47 1.9 --- test_gc.py 2001/10/02 21:24:57 1.10 *************** *** 8,14 **** name, actual, expected) ! def expect_not(actual, expected, name): ! if actual == expected: ! raise TestFailed, "test_%s: actual %d unexpected" % (name, actual) def run_test(name, thunk): --- 8,14 ---- name, actual, expected) ! def expect_nonzero(actual, name): ! if actual == 0: ! raise TestFailed, "test_%s: unexpected zero" % name def run_test(name, thunk): *************** *** 49,54 **** gc.collect() del A ! expect_not(gc.collect(), 0, "class") def test_instance(): class A: --- 49,68 ---- gc.collect() del A ! expect_nonzero(gc.collect(), "class") ! ! def test_staticclass(): ! class A(object): ! __dynamic__ = 0 ! gc.collect() ! del A ! expect_nonzero(gc.collect(), "staticclass") + def test_dynamicclass(): + class A(object): + __dynamic__ = 1 + gc.collect() + del A + expect_nonzero(gc.collect(), "dynamicclass") + def test_instance(): class A: *************** *** 58,62 **** gc.collect() del a ! expect_not(gc.collect(), 0, "instance") def test_method(): --- 72,76 ---- gc.collect() del a ! expect_nonzero(gc.collect(), "instance") def test_method(): *************** *** 68,72 **** gc.collect() del a ! expect_not(gc.collect(), 0, "method") def test_finalizer(): --- 82,86 ---- gc.collect() del a ! expect_nonzero(gc.collect(), "method") def test_finalizer(): *************** *** 85,89 **** del a del b ! expect_not(gc.collect(), 0, "finalizer") for obj in gc.garbage: if id(obj) == id_a: --- 99,103 ---- del a del b ! expect_nonzero(gc.collect(), "finalizer") for obj in gc.garbage: if id(obj) == id_a: *************** *** 154,157 **** --- 168,173 ---- run_test("tuples", test_tuple) run_test("classes", test_class) + run_test("static classes", test_staticclass) + run_test("dynamic classes", test_dynamicclass) run_test("instances", test_instance) run_test("methods", test_method) From gvanrossum@users.sourceforge.net Tue Oct 2 22:24:59 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 02 Oct 2001 14:24:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.92,2.93 objimpl.h,2.38,2.39 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv30352/Include Modified Files: object.h objimpl.h Log Message: Add Garbage Collection support to new-style classes (not yet to their instances). Also added GC support to various auxiliary types: super, property, descriptors, wrappers, dictproxy. (Only type objects have a tp_clear field; the other types are.) One change was necessary to the GC infrastructure. We have statically allocated type objects that don't have a GC header (and can't easily be given one) and heap-allocated type objects that do have a GC header. Giving these different metatypes would be really ugly: I tried, and I had to modify pickle.py, cPickle.c, copy.py, add a new invent a new name for the new metatype and make it a built-in, change affected tests... In short, a mess. So instead, we add a new type slot tp_is_gc, which is a simple Boolean function that determines whether a particular instance has GC headers or not. This slot is only relevant for types that have the (new) GC flag bit set. If the tp_is_gc slot is NULL (by far the most common case), all instances of the type are deemed to have GC headers. This slot is called by the PyObject_IS_GC() macro (which is only used twice, both times in gcmodule.c). I also changed the extern declarations for a bunch of GC-related functions (_PyObject_GC_Del etc.): these always exist but objimpl.h only declared them when WITH_CYCLE_GC was defined, but I needed to be able to reference them without #ifdefs. (When WITH_CYCLE_GC is not defined, they do the same as their non-GC counterparts anyway.) Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.92 retrieving revision 2.93 diff -C2 -d -r2.92 -r2.93 *** object.h 2001/09/20 21:45:26 2.92 --- object.h 2001/10/02 21:24:56 2.93 *************** *** 286,289 **** --- 286,290 ---- newfunc tp_new; destructor tp_free; /* Low-level free-memory routine */ + inquiry tp_is_gc; /* For PyObject_IS_GC */ PyObject *tp_bases; PyObject *tp_mro; /* method resolution order */ Index: objimpl.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/objimpl.h,v retrieving revision 2.38 retrieving revision 2.39 diff -C2 -d -r2.38 -r2.39 *** objimpl.h 2001/09/03 15:44:48 2.38 --- objimpl.h 2001/10/02 21:24:57 2.39 *************** *** 218,221 **** --- 218,225 ---- * Garbage Collection Support * ========================== + * + * Some of the functions and macros below are always defined; when + * WITH_CYCLE_GC is undefined, they simply don't do anything different + * than their non-GC counterparts. */ *************** *** 224,228 **** /* Test if an object has a GC head */ ! #define PyObject_IS_GC(o) PyType_IS_GC((o)->ob_type) extern DL_IMPORT(PyObject *) _PyObject_GC_Malloc(PyTypeObject *, int); --- 228,233 ---- /* Test if an object has a GC head */ ! #define PyObject_IS_GC(o) (PyType_IS_GC((o)->ob_type) && \ ! ((o)->ob_type->tp_is_gc == NULL || (o)->ob_type->tp_is_gc(o))) extern DL_IMPORT(PyObject *) _PyObject_GC_Malloc(PyTypeObject *, int); *************** *** 232,237 **** ( (type *) _PyObject_GC_Resize((PyVarObject *)(op), (n)) ) - #ifdef WITH_CYCLE_GC - extern DL_IMPORT(PyObject *) _PyObject_GC_New(PyTypeObject *); extern DL_IMPORT(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, int); --- 237,240 ---- *************** *** 239,242 **** --- 242,247 ---- extern DL_IMPORT(void) _PyObject_GC_Track(PyObject *); extern DL_IMPORT(void) _PyObject_GC_UnTrack(PyObject *); + + #ifdef WITH_CYCLE_GC /* GC information is stored BEFORE the object structure */ From gvanrossum@users.sourceforge.net Tue Oct 2 22:25:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 02 Oct 2001 14:25:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects descrobject.c,2.14,2.15 typeobject.c,2.82,2.83 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv30352/Objects Modified Files: descrobject.c typeobject.c Log Message: Add Garbage Collection support to new-style classes (not yet to their instances). Also added GC support to various auxiliary types: super, property, descriptors, wrappers, dictproxy. (Only type objects have a tp_clear field; the other types are.) One change was necessary to the GC infrastructure. We have statically allocated type objects that don't have a GC header (and can't easily be given one) and heap-allocated type objects that do have a GC header. Giving these different metatypes would be really ugly: I tried, and I had to modify pickle.py, cPickle.c, copy.py, add a new invent a new name for the new metatype and make it a built-in, change affected tests... In short, a mess. So instead, we add a new type slot tp_is_gc, which is a simple Boolean function that determines whether a particular instance has GC headers or not. This slot is only relevant for types that have the (new) GC flag bit set. If the tp_is_gc slot is NULL (by far the most common case), all instances of the type are deemed to have GC headers. This slot is called by the PyObject_IS_GC() macro (which is only used twice, both times in gcmodule.c). I also changed the extern declarations for a bunch of GC-related functions (_PyObject_GC_Del etc.): these always exist but objimpl.h only declared them when WITH_CYCLE_GC was defined, but I needed to be able to reference them without #ifdefs. (When WITH_CYCLE_GC is not defined, they do the same as their non-GC counterparts anyway.) Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/descrobject.c,v retrieving revision 2.14 retrieving revision 2.15 diff -C2 -d -r2.14 -r2.15 *** descrobject.c 2001/09/24 21:17:50 2.14 --- descrobject.c 2001/10/02 21:24:57 2.15 *************** *** 39,45 **** descr_dealloc(PyDescrObject *descr) { Py_XDECREF(descr->d_type); Py_XDECREF(descr->d_name); ! PyObject_DEL(descr); } --- 39,46 ---- descr_dealloc(PyDescrObject *descr) { + _PyObject_GC_UNTRACK(descr); Py_XDECREF(descr->d_type); Py_XDECREF(descr->d_name); ! PyObject_GC_Del(descr); } *************** *** 353,356 **** --- 354,371 ---- }; + static int + descr_traverse(PyObject *self, visitproc visit, void *arg) + { + PyDescrObject *descr = (PyDescrObject *)self; + int err; + + if (descr->d_type) { + err = visit((PyObject *)(descr->d_type), arg); + if (err) + return err; + } + return 0; + } + static PyTypeObject PyMethodDescr_Type = { PyObject_HEAD_INIT(&PyType_Type) *************** *** 374,380 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 389,395 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ ! descr_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ *************** *** 412,418 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 427,433 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ ! descr_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ *************** *** 450,456 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 465,471 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ ! descr_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ *************** *** 488,494 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 503,509 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ ! descr_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ *************** *** 680,685 **** proxy_dealloc(proxyobject *pp) { Py_DECREF(pp->dict); ! PyObject_DEL(pp); } --- 695,701 ---- proxy_dealloc(proxyobject *pp) { + _PyObject_GC_UNTRACK(pp); Py_DECREF(pp->dict); ! PyObject_GC_Del(pp); } *************** *** 696,699 **** --- 712,729 ---- } + static int + proxy_traverse(PyObject *self, visitproc visit, void *arg) + { + proxyobject *pp = (proxyobject *)self; + int err; + + if (pp->dict) { + err = visit(pp->dict, arg); + if (err) + return err; + } + return 0; + } + PyTypeObject proxytype = { PyObject_HEAD_INIT(&PyType_Type) *************** *** 718,724 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 748,754 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ ! proxy_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ *************** *** 740,747 **** proxyobject *pp; ! pp = PyObject_NEW(proxyobject, &proxytype); if (pp != NULL) { Py_INCREF(dict); pp->dict = dict; } return (PyObject *)pp; --- 770,778 ---- proxyobject *pp; ! pp = PyObject_GC_New(proxyobject, &proxytype); if (pp != NULL) { Py_INCREF(dict); pp->dict = dict; + _PyObject_GC_TRACK(pp); } return (PyObject *)pp; *************** *** 763,769 **** wrapper_dealloc(wrapperobject *wp) { Py_XDECREF(wp->descr); Py_XDECREF(wp->self); ! PyObject_DEL(wp); } --- 794,801 ---- wrapper_dealloc(wrapperobject *wp) { + _PyObject_GC_UNTRACK(wp); Py_XDECREF(wp->descr); Py_XDECREF(wp->self); ! PyObject_GC_Del(wp); } *************** *** 809,812 **** --- 841,863 ---- } + static int + wrapper_traverse(PyObject *self, visitproc visit, void *arg) + { + wrapperobject *wp = (wrapperobject *)self; + int err; + + if (wp->descr) { + err = visit((PyObject *)(wp->descr), arg); + if (err) + return err; + } + if (wp->self) { + err = visit(wp->self, arg); + if (err) + return err; + } + return 0; + } + PyTypeObject wrappertype = { PyObject_HEAD_INIT(&PyType_Type) *************** *** 831,837 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 882,888 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ ! wrapper_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ *************** *** 858,862 **** assert(PyObject_IsInstance(self, (PyObject *)(descr->d_type))); ! wp = PyObject_NEW(wrapperobject, &wrappertype); if (wp != NULL) { Py_INCREF(descr); --- 909,913 ---- assert(PyObject_IsInstance(self, (PyObject *)(descr->d_type))); ! wp = PyObject_GC_New(wrapperobject, &wrappertype); if (wp != NULL) { Py_INCREF(descr); *************** *** 864,867 **** --- 915,919 ---- Py_INCREF(self); wp->self = self; + _PyObject_GC_TRACK(wp); } return (PyObject *)wp; *************** *** 920,923 **** --- 972,976 ---- propertyobject *gs = (propertyobject *)self; + _PyObject_GC_UNTRACK(self); Py_XDECREF(gs->prop_get); Py_XDECREF(gs->prop_set); *************** *** 1013,1016 **** --- 1066,1089 ---- " x = property(getx, setx, delx, \"I'm the 'x' property.\")"; + static int + property_traverse(PyObject *self, visitproc visit, void *arg) + { + propertyobject *pp = (propertyobject *)self; + int err; + + #define VISIT(SLOT) \ + if (pp->SLOT) { \ + err = visit((PyObject *)(pp->SLOT), arg); \ + if (err) \ + return err; \ + } + + VISIT(prop_get); + VISIT(prop_set); + VISIT(prop_del); + + return 0; + } + PyTypeObject PyProperty_Type = { PyObject_HEAD_INIT(&PyType_Type) *************** *** 1035,1041 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ property_doc, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 1108,1115 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | ! Py_TPFLAGS_BASETYPE, /* tp_flags */ property_doc, /* tp_doc */ ! property_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ *************** *** 1054,1057 **** PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ ! _PyObject_Del, /* tp_free */ }; --- 1128,1131 ---- PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ ! _PyObject_GC_Del, /* tp_free */ }; Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.82 retrieving revision 2.83 diff -C2 -d -r2.82 -r2.83 *** typeobject.c 2001/10/01 17:18:22 2.82 --- typeobject.c 2001/10/02 21:24:57 2.83 *************** *** 266,270 **** /* Finalize GC if the base doesn't do GC and we do */ if (PyType_IS_GC(type) && !PyType_IS_GC(base)) ! PyObject_GC_Fini(self); /* Call the base tp_dealloc() */ --- 266,270 ---- /* Finalize GC if the base doesn't do GC and we do */ if (PyType_IS_GC(type) && !PyType_IS_GC(base)) ! _PyObject_GC_UNTRACK(self); /* Call the base tp_dealloc() */ *************** *** 865,868 **** --- 865,870 ---- if (dynamic) type->tp_flags |= Py_TPFLAGS_DYNAMICTYPE; + if (base->tp_flags & Py_TPFLAGS_HAVE_GC) + type->tp_flags |= Py_TPFLAGS_HAVE_GC; /* It's a new-style number unless it specifically inherits any *************** *** 935,939 **** if (add_dict) { if (base->tp_itemsize) ! type->tp_dictoffset = -(long)sizeof(PyObject *); else type->tp_dictoffset = slotoffset; --- 937,942 ---- if (add_dict) { if (base->tp_itemsize) ! type->tp_dictoffset = ! -(long)sizeof(PyObject *); else type->tp_dictoffset = slotoffset; *************** *** 967,971 **** /* Always override allocation strategy to use regular heap */ type->tp_alloc = PyType_GenericAlloc; ! type->tp_free = _PyObject_Del; /* Initialize the rest */ --- 970,980 ---- /* Always override allocation strategy to use regular heap */ type->tp_alloc = PyType_GenericAlloc; ! if (type->tp_flags & Py_TPFLAGS_HAVE_GC) { ! type->tp_free = _PyObject_GC_Del; ! type->tp_traverse = base->tp_traverse; ! type->tp_clear = base->tp_clear; ! } ! else ! type->tp_free = _PyObject_Del; /* Initialize the rest */ *************** *** 1081,1084 **** --- 1090,1094 ---- /* Assert this is a heap-allocated type object */ assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE); + _PyObject_GC_UNTRACK(type); et = (etype *)type; Py_XDECREF(type->tp_base); *************** *** 1103,1106 **** --- 1113,1182 ---- "type(name, bases, dict) -> a new type"; + static int + type_traverse(PyTypeObject *type, visitproc visit, void *arg) + { + etype *et; + int err; + + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) + return 0; + + et = (etype *)type; + + #define VISIT(SLOT) \ + if (SLOT) { \ + err = visit((PyObject *)(SLOT), arg); \ + if (err) \ + return err; \ + } + + VISIT(type->tp_dict); + VISIT(type->tp_defined); + VISIT(type->tp_mro); + VISIT(type->tp_bases); + VISIT(type->tp_base); + VISIT(et->slots); + + #undef VISIT + + return 0; + } + + static int + type_clear(PyTypeObject *type) + { + etype *et; + PyObject *tmp; + + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) + return 0; + + et = (etype *)type; + + #define CLEAR(SLOT) \ + if (SLOT) { \ + tmp = (PyObject *)(SLOT); \ + SLOT = NULL; \ + Py_DECREF(tmp); \ + } + + CLEAR(type->tp_dict); + CLEAR(type->tp_defined); + CLEAR(type->tp_mro); + CLEAR(type->tp_bases); + CLEAR(type->tp_base); + CLEAR(et->slots); + + #undef CLEAR + + return 0; + } + + static int + type_is_gc(PyTypeObject *type) + { + return type->tp_flags & Py_TPFLAGS_HEAPTYPE; + } + PyTypeObject PyType_Type = { PyObject_HEAD_INIT(&PyType_Type) *************** *** 1124,1131 **** (setattrofunc)type_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ type_doc, /* tp_doc */ ! 0, /* tp_traverse */ ! 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ --- 1200,1208 ---- (setattrofunc)type_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | ! Py_TPFLAGS_BASETYPE, /* tp_flags */ type_doc, /* tp_doc */ ! (traverseproc)type_traverse, /* tp_traverse */ ! (inquiry)type_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ *************** *** 1143,1146 **** --- 1220,1225 ---- 0, /* tp_alloc */ type_new, /* tp_new */ + _PyObject_GC_Del, /* tp_free */ + (inquiry)type_is_gc, /* tp_is_gc */ }; *************** *** 3532,3535 **** --- 3611,3615 ---- superobject *su = (superobject *)self; + _PyObject_GC_UNTRACK(self); Py_XDECREF(su->obj); Py_XDECREF(su->type); *************** *** 3667,3670 **** --- 3747,3771 ---- " super(C, self).meth(arg)"; + static int + super_traverse(PyObject *self, visitproc visit, void *arg) + { + superobject *su = (superobject *)self; + int err; + + #define VISIT(SLOT) \ + if (SLOT) { \ + err = visit((PyObject *)(SLOT), arg); \ + if (err) \ + return err; \ + } + + VISIT(su->obj); + VISIT(su->type); + + #undef VISIT + + return 0; + } + PyTypeObject PySuper_Type = { PyObject_HEAD_INIT(&PyType_Type) *************** *** 3689,3695 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ super_doc, /* tp_doc */ ! 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ --- 3790,3797 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | ! Py_TPFLAGS_BASETYPE, /* tp_flags */ super_doc, /* tp_doc */ ! super_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ *************** *** 3708,3711 **** PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ ! _PyObject_Del, /* tp_free */ }; --- 3810,3813 ---- PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ ! _PyObject_GC_Del, /* tp_free */ }; From tim_one@users.sourceforge.net Tue Oct 2 22:32:10 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 02 Oct 2001 14:32:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects stringobject.c,2.135,2.136 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv475/python/Objects Modified Files: stringobject.c Log Message: SF bug [#467265] Compile errors on SuSe Linux on IBM/s390. Unknown whether this fixes it. - stringobject.c, PyString_FromFormatV: don't assume that va_list is of a type that can be copied via an initializer. - errors.c, PyErr_Format: add a va_end() to balance the va_start(). Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.135 retrieving revision 2.136 diff -C2 -d -r2.135 -r2.136 *** stringobject.c 2001/09/27 20:30:07 2.135 --- stringobject.c 2001/10/02 21:32:07 2.136 *************** *** 151,155 **** PyString_FromFormatV(const char *format, va_list vargs) { ! va_list count = vargs; int n = 0; const char* f; --- 151,155 ---- PyString_FromFormatV(const char *format, va_list vargs) { ! va_list count; int n = 0; const char* f; *************** *** 157,160 **** --- 157,165 ---- PyObject* string; + #ifdef VA_LIST_IS_ARRAY + memcpy(count, vargs, sizeof(va_list)); + #else + count = vargs; + #endif /* step 1: figure out how large a buffer we need */ for (f = format; *f; f++) { From tim_one@users.sourceforge.net Tue Oct 2 22:32:10 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 02 Oct 2001 14:32:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python errors.c,2.65,2.66 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv475/python/Python Modified Files: errors.c Log Message: SF bug [#467265] Compile errors on SuSe Linux on IBM/s390. Unknown whether this fixes it. - stringobject.c, PyString_FromFormatV: don't assume that va_list is of a type that can be copied via an initializer. - errors.c, PyErr_Format: add a va_end() to balance the va_start(). Index: errors.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/errors.c,v retrieving revision 2.65 retrieving revision 2.66 diff -C2 -d -r2.65 -r2.66 *** errors.c 2001/09/26 19:58:38 2.65 --- errors.c 2001/10/02 21:32:07 2.66 *************** *** 408,412 **** PyErr_SetObject(exception, string); Py_XDECREF(string); ! return NULL; } --- 408,412 ---- PyErr_SetObject(exception, string); Py_XDECREF(string); ! va_end(vargs); return NULL; } From tim_one@users.sourceforge.net Tue Oct 2 23:47:10 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 02 Oct 2001 15:47:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib doctest.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv18405/python/Lib Modified Files: doctest.py Log Message: SF patch [#466616] Exclude imported items from doctest. Another installment; the new functionality wasn't actually enabled in normal use, only in the strained use checked by the test case. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** doctest.py 2001/10/02 03:53:41 1.18 --- doctest.py 2001/10/02 22:47:08 1.19 *************** *** 771,775 **** >>> m2 = new.module('_m2') >>> test_data = \""" ! ... def f(): ... '''>>> assert 1 == 1 ... ''' --- 771,775 ---- >>> m2 = new.module('_m2') >>> test_data = \""" ! ... def _f(): ... '''>>> assert 1 == 1 ... ''' *************** *** 786,796 **** >>> exec test_data in m1.__dict__ >>> exec test_data in m2.__dict__ Tests that objects outside m1 are excluded: - >>> d = {"_f": m1.f, "g": m1.g, "h": m1.H, - ... "f2": m2.f, "g2": m2.g, "h2": m2.H} >>> t = Tester(globs={}, verbose=0) ! >>> t.rundict(d, "rundict_test", m1) # _f, f2 and g2 and h2 skipped (0, 3) --- 786,795 ---- >>> exec test_data in m1.__dict__ >>> exec test_data in m2.__dict__ + >>> m1.__dict__.update({"f2": m2._f, "g2": m2.g, "h2": m2.H}) Tests that objects outside m1 are excluded: >>> t = Tester(globs={}, verbose=0) ! >>> t.rundict(m1.__dict__, "rundict_test", m1) # _f, f2 and g2 and h2 skipped (0, 3) *************** *** 798,802 **** >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0) ! >>> t.rundict(d, "rundict_test_pvt", m1) # Only f2, g2 and h2 skipped (0, 4) --- 797,801 ---- >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0) ! >>> t.rundict(m1.__dict__, "rundict_test_pvt", m1) # Only f2, g2 and h2 skipped (0, 4) *************** *** 804,809 **** >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0) ! >>> t.rundict(d, "rundict_test_pvt") # None are skipped. (0, 8) """ --- 803,815 ---- >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0) ! >>> t.rundict(m1.__dict__, "rundict_test_pvt") # None are skipped. (0, 8) + + The exclusion of objects from outside the designated module is + meant to be invoked automagically by testmod. + + >>> testmod(m1) + (0, 3) + """ *************** *** 1038,1042 **** tester = Tester(m, globs=globs, verbose=verbose, isprivate=isprivate) failures, tries = tester.rundoc(m, name) ! f, t = tester.rundict(m.__dict__, name) failures = failures + f tries = tries + t --- 1044,1048 ---- tester = Tester(m, globs=globs, verbose=verbose, isprivate=isprivate) failures, tries = tester.rundoc(m, name) ! f, t = tester.rundict(m.__dict__, name, m) failures = failures + f tries = tries + t From gvanrossum@users.sourceforge.net Wed Oct 3 00:13:18 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 02 Oct 2001 16:13:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/dns README,1.3,NONE asgethost.py,1.2,NONE dnsclass.py,1.1,NONE dnslib.py,1.3,NONE dnsopcode.py,1.1,NONE dnstype.py,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Demo/dns In directory usw-pr-cvs1:/tmp/cvs-serv24241 Removed Files: README asgethost.py dnsclass.py dnslib.py dnsopcode.py dnstype.py Log Message: Removed Demo/dns -- see sf.net/projects/pydns/ instead. --- README DELETED --- --- asgethost.py DELETED --- --- dnsclass.py DELETED --- --- dnslib.py DELETED --- --- dnsopcode.py DELETED --- --- dnstype.py DELETED --- From gvanrossum@users.sourceforge.net Wed Oct 3 00:15:39 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 02 Oct 2001 16:15:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.266,1.267 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv24749 Modified Files: NEWS Log Message: Note removal of Demo/dns, point to PyDNS. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.266 retrieving revision 1.267 diff -C2 -d -r1.266 -r1.267 *** NEWS 2001/10/02 03:53:41 1.266 --- NEWS 2001/10/02 23:15:37 1.267 *************** *** 19,23 **** which indicates whether output is intended for the header 'Q' encoding. ! Tools Build --- 19,27 ---- which indicates whether output is intended for the header 'Q' encoding. ! Tools/Demos ! ! - Demo/dns was removed. It no longer serves any purpose; a package ! derived from it is now maintained by Anthony Baxter, see ! http://PyDNS.SourceForge.net. Build From gvanrossum@users.sourceforge.net Wed Oct 3 01:50:20 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 02 Oct 2001 17:50:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.83,2.84 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv14623 Modified Files: typeobject.c Log Message: call_method(), call_maybe(): fix a performance bug: the argument pointing to a static variable to hold the object form of the string was never used, causing endless calls to PyString_InternFromString(). One particular test (with lots of __getitem__ calls) became a third faster with this! Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.83 retrieving revision 2.84 diff -C2 -d -r2.83 -r2.84 *** typeobject.c 2001/10/02 21:24:57 2.83 --- typeobject.c 2001/10/03 00:50:18 2.84 *************** *** 379,394 **** va_list va; PyObject *args, *func = 0, *retval; - PyObject *dummy_str = NULL; va_start(va, format); ! func = lookup_maybe(o, name, &dummy_str); if (func == NULL) { va_end(va); if (!PyErr_Occurred()) ! PyErr_SetObject(PyExc_AttributeError, dummy_str); ! Py_XDECREF(dummy_str); return NULL; } - Py_DECREF(dummy_str); if (format && *format) --- 379,391 ---- va_list va; PyObject *args, *func = 0, *retval; va_start(va, format); ! func = lookup_maybe(o, name, nameobj); if (func == NULL) { va_end(va); if (!PyErr_Occurred()) ! PyErr_SetObject(PyExc_AttributeError, *nameobj); return NULL; } if (format && *format) *************** *** 418,426 **** va_list va; PyObject *args, *func = 0, *retval; - PyObject *dummy_str = NULL; va_start(va, format); ! func = lookup_maybe(o, name, &dummy_str); ! Py_XDECREF(dummy_str); if (func == NULL) { va_end(va); --- 415,421 ---- va_list va; PyObject *args, *func = 0, *retval; va_start(va, format); ! func = lookup_maybe(o, name, nameobj); if (func == NULL) { va_end(va); From gvanrossum@users.sourceforge.net Wed Oct 3 04:01:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 02 Oct 2001 20:01:00 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv18044 Modified Files: PLAN.txt Log Message: Mark treatment of binary operators for __rop__-before-__op__ as done. Add more detail about the speed optimizations needed for __dynamic__. The weak reference solution becomes more attractive... Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PLAN.txt,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** PLAN.txt 2001/09/28 18:19:21 1.11 --- PLAN.txt 2001/10/03 03:00:56 1.12 *************** *** 5,16 **** ----------- - Treat all binary operators the same way as I just did for rich - comparison: in a b, if isinstance(b, type(a)), try b.__rop__(a) - before trying a.__op__(b). - Make __dynamic__ the default (this requires more performance work -- one particular test, test_descr.inherits(), is about 10x slower when ! __dynamic__ is 1. :-( Add __del__ handlers. --- 5,22 ---- ----------- Make __dynamic__ the default (this requires more performance work -- one particular test, test_descr.inherits(), is about 10x slower when ! __dynamic__ is 1. :-( There are two ways to go about the performance ! work: ! ! a) Add shortcuts to the slot_tp_XXX to recognize a PyWrapperDescr ! with the correct wrap_tp_XXX function. + b) Add a list or dict of weak refs to derived classes to each dynamic + class, and trap setattr+delattr on the base class so that they + update the tp_XXX slot in each derived class when the base class + __XXX__ gets set or deleted. More work, but more gain (zero waste + in slot_tp_XXX when __XXX__ is not overridden). + Add __del__ handlers. *************** *** 33,36 **** --- 39,46 ---- Done (mostly) ------------- + + Treat all binary operators the same way as I just did for rich + comparison: in a b, if type(a) is not type(b) and isinstance(b, + type(a)), try b.__rop__(a) before trying a.__op__(b). *** Done. *** Fix comparisons. There's some nasty stuff here: when two types are From tim_one@users.sourceforge.net Wed Oct 3 05:08:28 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 02 Oct 2001 21:08:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib doctest.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv14897/python/Lib Modified Files: doctest.py Log Message: SF bug [#467336] doctest failures w/ new-style classes. Taught doctest about static methods, class methods, and property docstrings in new-style classes. As for inspect.py/pydoc.py before it, the new stuff needed didn't really fit into the old architecture (but was less of a strain to force-fit here). New-style class docstrings still aren't found, but that's the subject of a different bug and I want to fix that right instead of hacking around it in doctest. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** doctest.py 2001/10/02 22:47:08 1.19 --- doctest.py 2001/10/03 04:08:26 1.20 *************** *** 259,263 **** 6 tests in doctest.Tester 10 tests in doctest.Tester.merge ! 7 tests in doctest.Tester.rundict 3 tests in doctest.Tester.rundoc 3 tests in doctest.Tester.runstring --- 259,263 ---- 6 tests in doctest.Tester 10 tests in doctest.Tester.merge ! 14 tests in doctest.Tester.rundict 3 tests in doctest.Tester.rundoc 3 tests in doctest.Tester.runstring *************** *** 268,273 **** 2 tests in doctest.__test__.string 7 tests in doctest.is_private ! 53 tests in 17 items. ! 53 passed and 0 failed. Test passed. """ --- 268,273 ---- 2 tests in doctest.__test__.string 7 tests in doctest.is_private ! 60 tests in 17 items. ! 60 passed and 0 failed. Test passed. """ *************** *** 296,299 **** --- 296,300 ---- from inspect import isfunction as _isfunction from inspect import ismodule as _ismodule + from inspect import classify_class_attrs as _classify_class_attrs # Extract interactive examples from a string. Return a list of triples, *************** *** 748,754 **** self.__record_outcome(name, f, t) if _isclass(object): ! f2, t2 = self.rundict(object.__dict__, name) ! f = f + f2 ! t = t + t2 return f, t --- 749,797 ---- self.__record_outcome(name, f, t) if _isclass(object): ! # In 2.2, class and static methods complicate life. Build ! # a dict "that works", by hook or by crook. ! d = {} ! for tag, kind, homecls, value in _classify_class_attrs(object): ! ! if homecls is not object: ! # Only look at names defined immediately by the class. ! continue ! ! elif self.isprivate(name, tag): ! continue ! ! elif kind == "method": ! # value is already a function ! d[tag] = value ! ! elif kind == "static method": ! # value isn't a function, but getattr reveals one ! d[tag] = getattr(object, tag) ! ! elif kind == "class method": ! # Hmm. A classmethod object doesn't seem to reveal ! # enough. But getattr turns it into a bound method, ! # and from there .im_func retrieves the underlying ! # function. ! d[tag] = getattr(object, tag).im_func ! ! elif kind == "property": ! # The methods implementing the property have their ! # own docstrings -- but the property may have one too. ! if value.__doc__ is not None: ! d[tag] = str(value.__doc__) ! ! elif kind == "data": ! # Grab nested classes. ! if _isclass(value): ! d[tag] = value ! ! else: ! raise ValueError("teach doctest about %r" % kind) ! ! f2, t2 = self.run__test__(d, name) ! f += f2 ! t += t2 ! return f, t From tim_one@users.sourceforge.net Wed Oct 3 05:08:28 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 02 Oct 2001 21:08:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_doctest2.py,NONE,1.1 test_pyclbr.py,1.5,1.6 test_support.py,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv14897/python/Lib/test Modified Files: test_pyclbr.py test_support.py Added Files: test_doctest2.py Log Message: SF bug [#467336] doctest failures w/ new-style classes. Taught doctest about static methods, class methods, and property docstrings in new-style classes. As for inspect.py/pydoc.py before it, the new stuff needed didn't really fit into the old architecture (but was less of a strain to force-fit here). New-style class docstrings still aren't found, but that's the subject of a different bug and I want to fix that right instead of hacking around it in doctest. --- NEW FILE: test_doctest2.py --- """A module to test whether doctest recognizes some 2.2 features, like static and class methods. >>> print 'yup' # 1 yup """ import test_support # XXX The class docstring is skipped. class C(object): """Class C. >>> print C() # 2 42 """ def __init__(self): """C.__init__. >>> print C() # 3 42 """ def __str__(self): """ >>> print C() # 4 42 """ return "42" # XXX The class docstring is skipped. class D(object): """A nested D class. >>> print "In D!" # 5 In D! """ def nested(self): """ >>> print 3 # 6 3 """ def getx(self): """ >>> c = C() # 7 >>> c.x = 12 # 8 >>> print c.x # 9 -12 """ return -self._x def setx(self, value): """ >>> c = C() # 10 >>> c.x = 12 # 11 >>> print c.x # 12 -12 """ self._x = value x = property(getx, setx, doc="""\ >>> c = C() # 13 >>> c.x = 12 # 14 >>> print c.x # 15 -12 """) def statm(): """ A static method. >>> print C.statm() # 16 666 >>> print C().statm() # 17 666 """ return 666 statm = staticmethod(statm) def clsm(cls, val): """ A class method. >>> print C.clsm(22) # 18 22 >>> print C().clsm(22) # 19 22 """ return 22 clsm = classmethod(clsm) def test_main(): import test_doctest2 # XXX 2 class docstrings are skipped. # EXPECTED = 19 EXPECTED = 17 f, t = test_support.run_doctest(test_doctest2) if t != EXPECTED: raise test_support.TestFailed("expected %d tests to run, not %d" % (EXPECTED, t)) # Pollute the namespace with a bunch of imported functions and classes, # to make sure they don't get tested. from doctest import * if __name__ == '__main__': test_main() Index: test_pyclbr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pyclbr.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_pyclbr.py 2001/10/02 03:53:41 1.5 --- test_pyclbr.py 2001/10/03 04:08:26 1.6 *************** *** 102,106 **** self.checkModule('pyclbr') self.checkModule('doctest', ! ignore=['_isclass', '_isfunction', '_ismodule']) self.checkModule('rfc822') self.checkModule('xmllib') --- 102,109 ---- self.checkModule('pyclbr') self.checkModule('doctest', ! ignore=['_isclass', ! '_isfunction', ! '_ismodule', ! '_classify_class_attrs']) self.checkModule('rfc822') self.checkModule('xmllib') Index: test_support.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_support.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** test_support.py 2001/09/25 20:05:11 1.37 --- test_support.py 2001/10/03 04:08:26 1.38 *************** *** 177,181 **** def run_doctest(module, verbosity=None): ! """Run doctest on the given module. If optional argument verbosity is not specified (or is None), pass --- 177,181 ---- def run_doctest(module, verbosity=None): ! """Run doctest on the given module. Return (#failures, #tests). If optional argument verbosity is not specified (or is None), pass *************** *** 199,202 **** --- 199,203 ---- if f: raise TestFailed("%d of %d doctests failed" % (f, t)) + return f, t finally: sys.stdout = save_stdout From tim_one@users.sourceforge.net Wed Oct 3 05:15:30 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 02 Oct 2001 21:15:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_doctest2.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21417/python/Lib/test Modified Files: test_doctest2.py Log Message: Made the classmethod docstring test a bit less trivial. Index: test_doctest2.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_doctest2.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_doctest2.py 2001/10/03 04:08:26 1.1 --- test_doctest2.py 2001/10/03 04:15:28 1.2 *************** *** 88,95 **** >>> print C.clsm(22) # 18 22 ! >>> print C().clsm(22) # 19 ! 22 """ ! return 22 clsm = classmethod(clsm) --- 88,95 ---- >>> print C.clsm(22) # 18 22 ! >>> print C().clsm(23) # 19 ! 23 """ ! return val clsm = classmethod(clsm) From gvanrossum@users.sourceforge.net Wed Oct 3 13:09:32 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 03 Oct 2001 05:09:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include descrobject.h,2.5,2.6 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv24226/Include Modified Files: descrobject.h Log Message: *EXPERIMENTAL* speedup of slot_sq_item. This sped up the following test dramatically: class T(tuple): __dynamic__ = 1 t = T(range(1000)) for i in range(1000): tt = tuple(t) The speedup was about 5x compared to the previous state of CVS (1.7 vs. 8.8, in arbitrary time units). But it's still more than twice as slow as as the same test with __dynamic__ = 0 (0.8). I'm not sure that I really want to go through the trouble of this kind of speedup for every slot. Even doing it just for the most popular slots will be a major effort (the new slot_sq_item is 40+ lines, while the old one was one line with a powerful macro -- unfortunately the speedup comes from expanding the macro and doing things in a way specific to the slot signature). An alternative that I'm currently considering is sketched in PLAN.txt: trap setattr on type objects. But this will require keeping track of all derived types using weak references. Index: descrobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/descrobject.h,v retrieving revision 2.5 retrieving revision 2.6 diff -C2 -d -r2.5 -r2.6 *** descrobject.h 2001/09/20 21:45:26 2.5 --- descrobject.h 2001/10/03 12:09:29 2.6 *************** *** 21,24 **** --- 21,58 ---- }; + /* Various kinds of descriptor objects */ + + #define PyDescr_COMMON \ + PyObject_HEAD \ + PyTypeObject *d_type; \ + PyObject *d_name + + typedef struct { + PyDescr_COMMON; + } PyDescrObject; + + typedef struct { + PyDescr_COMMON; + PyMethodDef *d_method; + } PyMethodDescrObject; + + typedef struct { + PyDescr_COMMON; + struct PyMemberDef *d_member; + } PyMemberDescrObject; + + typedef struct { + PyDescr_COMMON; + PyGetSetDef *d_getset; + } PyGetSetDescrObject; + + typedef struct { + PyDescr_COMMON; + struct wrapperbase *d_base; + void *d_wrapped; /* This can be any function pointer */ + } PyWrapperDescrObject; + + extern DL_IMPORT(PyTypeObject) PyWrapperDescr_Type; + extern DL_IMPORT(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); extern DL_IMPORT(PyObject *) PyDescr_NewMember(PyTypeObject *, From gvanrossum@users.sourceforge.net Wed Oct 3 13:09:32 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 03 Oct 2001 05:09:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects descrobject.c,2.15,2.16 typeobject.c,2.84,2.85 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv24226/Objects Modified Files: descrobject.c typeobject.c Log Message: *EXPERIMENTAL* speedup of slot_sq_item. This sped up the following test dramatically: class T(tuple): __dynamic__ = 1 t = T(range(1000)) for i in range(1000): tt = tuple(t) The speedup was about 5x compared to the previous state of CVS (1.7 vs. 8.8, in arbitrary time units). But it's still more than twice as slow as as the same test with __dynamic__ = 0 (0.8). I'm not sure that I really want to go through the trouble of this kind of speedup for every slot. Even doing it just for the most popular slots will be a major effort (the new slot_sq_item is 40+ lines, while the old one was one line with a powerful macro -- unfortunately the speedup comes from expanding the macro and doing things in a way specific to the slot signature). An alternative that I'm currently considering is sketched in PLAN.txt: trap setattr on type objects. But this will require keeping track of all derived types using weak references. Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/descrobject.c,v retrieving revision 2.15 retrieving revision 2.16 diff -C2 -d -r2.15 -r2.16 *** descrobject.c 2001/10/02 21:24:57 2.15 --- descrobject.c 2001/10/03 12:09:30 2.16 *************** *** 4,39 **** #include "structmember.h" /* Why is this not included in Python.h? */ - /* Various kinds of descriptor objects */ - - #define COMMON \ - PyObject_HEAD \ - PyTypeObject *d_type; \ - PyObject *d_name - - typedef struct { - COMMON; - } PyDescrObject; - - typedef struct { - COMMON; - PyMethodDef *d_method; - } PyMethodDescrObject; - - typedef struct { - COMMON; - PyMemberDef *d_member; - } PyMemberDescrObject; - - typedef struct { - COMMON; - PyGetSetDef *d_getset; - } PyGetSetDescrObject; - - typedef struct { - COMMON; - struct wrapperbase *d_base; - void *d_wrapped; /* This can be any function pointer */ - } PyWrapperDescrObject; - static void descr_dealloc(PyDescrObject *descr) --- 4,7 ---- *************** *** 482,486 **** }; ! static PyTypeObject PyWrapperDescr_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, --- 450,454 ---- }; ! PyTypeObject PyWrapperDescr_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.84 retrieving revision 2.85 diff -C2 -d -r2.84 -r2.85 *** typeobject.c 2001/10/03 00:50:18 2.84 --- typeobject.c 2001/10/03 12:09:30 2.85 *************** *** 2114,2123 **** int i; ! if (!PyArg_ParseTuple(args, "O", &arg)) ! return NULL; ! i = getindex(self, arg); ! if (i == -1 && PyErr_Occurred()) ! return NULL; ! return (*func)(self, i); } --- 2114,2127 ---- int i; ! if (PyTuple_GET_SIZE(args) == 1) { ! arg = PyTuple_GET_ITEM(args, 0); ! i = getindex(self, arg); ! if (i == -1 && PyErr_Occurred()) ! return NULL; ! return (*func)(self, i); ! } ! PyArg_ParseTuple(args, "O", &arg); ! assert(PyErr_Occurred()); ! return NULL; } *************** *** 2826,2830 **** SLOT1(slot_sq_concat, "__add__", PyObject *, "O") SLOT1(slot_sq_repeat, "__mul__", int, "i") ! SLOT1(slot_sq_item, "__getitem__", int, "i") SLOT2(slot_sq_slice, "__getslice__", int, int, "ii") --- 2830,2884 ---- SLOT1(slot_sq_concat, "__add__", PyObject *, "O") SLOT1(slot_sq_repeat, "__mul__", int, "i") ! ! /* Super-optimized version of slot_sq_item. ! Other slots could do the same... */ ! static PyObject * ! slot_sq_item(PyObject *self, int i) ! { ! static PyObject *getitem_str; ! PyObject *func, *args = NULL, *ival = NULL, *retval = NULL; ! descrgetfunc f; ! ! if (getitem_str == NULL) { ! getitem_str = PyString_InternFromString("__getitem__"); ! if (getitem_str == NULL) ! return NULL; ! } ! func = _PyType_Lookup(self->ob_type, getitem_str); ! if (func != NULL) { ! if (func->ob_type == &PyWrapperDescr_Type) { ! PyWrapperDescrObject *wrapper = ! (PyWrapperDescrObject *)func; ! if (wrapper->d_base->wrapper == wrap_sq_item) { ! intargfunc f; ! f = (intargfunc)(wrapper->d_wrapped); ! return f(self, i); ! } ! } ! if ((f = func->ob_type->tp_descr_get) == NULL) ! Py_INCREF(func); ! else ! func = f(func, self, (PyObject *)(self->ob_type)); ! ival = PyInt_FromLong(i); ! if (ival != NULL) { ! args = PyTuple_New(1); ! if (args != NULL) { ! PyTuple_SET_ITEM(args, 0, ival); ! retval = PyObject_Call(func, args, NULL); ! Py_XDECREF(args); ! Py_XDECREF(func); ! return retval; ! } ! } ! } ! else { ! PyErr_SetObject(PyExc_AttributeError, getitem_str); ! } ! Py_XDECREF(args); ! Py_XDECREF(ival); ! Py_XDECREF(func); ! return NULL; ! } ! SLOT2(slot_sq_slice, "__getslice__", int, int, "ii") From montanaro@users.sourceforge.net Wed Oct 3 13:21:26 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Wed, 03 Oct 2001 05:21:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib SocketServer.py,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv28638 Modified Files: SocketServer.py Log Message: remove empty __del__ method from BaseRequestHandler to avoid cyclic garbage loss for no reason. Index: SocketServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/SocketServer.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** SocketServer.py 2001/07/24 20:34:08 1.26 --- SocketServer.py 2001/10/03 12:21:23 1.27 *************** *** 507,513 **** pass - def __del__(self): - pass - def handle(self): pass --- 507,510 ---- From gvanrossum@users.sourceforge.net Wed Oct 3 14:58:37 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 03 Oct 2001 06:58:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.85,2.86 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv20203 Modified Files: typeobject.c Log Message: typeobject.c, slot_tp_gettattr_hook(): fix the speedup hack -- the test for getattribute==NULL was bogus because it always found object.__getattribute__. Pick it apart using the trick we learned from slot_sq_item, and if it's just a wrapper around PyObject_GenericGetAttr, zap it. Also added a long XXX comment explaining the consequences. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.85 retrieving revision 2.86 diff -C2 -d -r2.85 -r2.86 *** typeobject.c 2001/10/03 12:09:30 2.85 --- typeobject.c 2001/10/03 13:58:35 2.86 *************** *** 3297,3302 **** --- 3297,3314 ---- getattr = _PyType_Lookup(tp, getattr_str); getattribute = _PyType_Lookup(tp, getattribute_str); + if (getattribute != NULL && + getattribute->ob_type == &PyWrapperDescr_Type && + ((PyWrapperDescrObject *)getattribute)->d_wrapped == + PyObject_GenericGetAttr) + getattribute = NULL; if (getattr == NULL && getattribute == NULL) { /* Avoid further slowdowns */ + /* XXX This is questionable: it means that a class that + isn't born with __getattr__ or __getattribute__ cannot + acquire them in later life. But it's a relatively big + speedup, so I'm keeping it in for now. If this is + removed, you can also remove the "def __getattr__" from + class C (marked with another XXX comment) in dynamics() + in Lib/test/test_descr.py. */ if (tp->tp_getattro == slot_tp_getattr_hook) tp->tp_getattro = PyObject_GenericGetAttr; From gvanrossum@users.sourceforge.net Wed Oct 3 14:59:57 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 03 Oct 2001 06:59:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.80,1.81 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20567 Modified Files: test_descr.py Log Message: dynamics(): add a dummy __getattr__ method to the C class so that the test for modifying __getattr__ works, now that slot_tp_getattr_hook zaps the slot if there's no hook. Added an XXX comment with a ref back to slot_tp_getattr_hook. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.80 retrieving revision 1.81 diff -C2 -d -r1.80 -r1.81 *** test_descr.py 2001/10/02 19:58:32 1.80 --- test_descr.py 2001/10/03 13:59:54 1.81 *************** *** 871,874 **** --- 871,879 ---- class C(object): __dynamic__ = 1 + # XXX Ideally the following def shouldn't be necessary, + # but it's too much of a performance burden. + # See XXX comment in slot_tp_getattr_hook. + def __getattr__(self, name): + raise AttributeError, name a = C() verify(not hasattr(a, "foobar")) From akuchling@users.sourceforge.net Wed Oct 3 18:07:27 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Wed, 03 Oct 2001 10:07:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib asyncore.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv13544 Modified Files: asyncore.py Log Message: Set .addr in a few more places (patch approved by Sam Rushing) Index: asyncore.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asyncore.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** asyncore.py 2001/09/19 17:31:47 1.19 --- asyncore.py 2001/10/03 17:07:25 1.20 *************** *** 202,205 **** --- 202,206 ---- self.socket.setblocking (0) self.connected = 1 + self.addr = sock.getpeername() def __repr__ (self): *************** *** 307,310 **** --- 308,312 ---- else: raise socket.error, why + self.addr = address self.connected = 1 self.handle_connect() From gward@users.sourceforge.net Wed Oct 3 20:59:32 2001 From: gward@users.sourceforge.net (Greg Ward) Date: Wed, 03 Oct 2001 12:59:32 -0700 Subject: [Python-checkins] CVS: python/dist/src setup.py,1.57,1.58 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv17250 Modified Files: setup.py Log Message: Fix a spelling error that has been bugging me for longer than I care to admit. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.57 retrieving revision 1.58 diff -C2 -d -r1.57 -r1.58 *** setup.py 2001/09/18 20:32:13 1.57 --- setup.py 2001/10/03 19:59:30 1.58 *************** *** 415,419 **** # refer to pympz.sourceforge.net. ! # A compatible MP library unencombered by the GPL also exists. It was # posted to comp.sources.misc in volume 40 and is widely available from # FTP archive sites. One URL for it is: --- 415,419 ---- # refer to pympz.sourceforge.net. ! # A compatible MP library unencumbered by the GPL also exists. It was # posted to comp.sources.misc in volume 40 and is widely available from # FTP archive sites. One URL for it is: From fdrake@users.sourceforge.net Wed Oct 3 22:12:34 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 03 Oct 2001 14:12:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv1023 Modified Files: profile.py Log Message: Undo previous patch; it did not quite work out. Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** profile.py 2001/09/27 16:28:42 1.31 --- profile.py 2001/10/03 21:12:32 1.32 *************** *** 242,246 **** def trace_dispatch_exception(self, frame, t): rt, rtt, rct, rfn, rframe, rcur = self.cur ! if (rframe is frame) and rcur: return self.trace_dispatch_return(rframe, t) return 0 --- 242,246 ---- def trace_dispatch_exception(self, frame, t): rt, rtt, rct, rfn, rframe, rcur = self.cur ! if (rframe is not frame) and rcur: return self.trace_dispatch_return(rframe, t) return 0 From fdrake@users.sourceforge.net Wed Oct 3 22:15:34 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 03 Oct 2001 14:15:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_profilehooks.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv3395/test Modified Files: test_profilehooks.py Log Message: Add some more test cases to be sure we do the right thing in various cases. Index: test_profilehooks.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_profilehooks.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_profilehooks.py 2001/09/26 21:00:33 1.4 --- test_profilehooks.py 2001/10/03 21:15:32 1.5 *************** *** 1,2 **** --- 1,4 ---- + from __future__ import generators + import pprint import sys *************** *** 41,44 **** --- 43,47 ---- def callback(self, frame, event, arg): + # Callback registered with sys.setprofile()/sys.settrace() self.dispatch[event](self, frame) *************** *** 56,59 **** --- 59,64 ---- self.stack.pop() else: + # Either an exception was raised in Python or a C function + # raised an exception; this does not represent propogation. self.add_event('ignore', frame) *************** *** 193,197 **** --- 198,275 ---- ]) + def test_distant_exception(self): + def f(): + 1/0 + def g(): + f() + def h(): + g() + def i(): + h() + def j(p): + i() + f_ident = ident(f) + g_ident = ident(g) + h_ident = ident(h) + i_ident = ident(i) + j_ident = ident(j) + self.check_events(j, [(1, 'call', j_ident), + (2, 'call', i_ident), + (3, 'call', h_ident), + (4, 'call', g_ident), + (5, 'call', f_ident), + (5, 'exception', f_ident), + (4, 'exception', g_ident), + (3, 'exception', h_ident), + (2, 'exception', i_ident), + (1, 'exception', j_ident), + (0, 'exception', protect_ident), + ]) + def test_generator(self): + def f(): + for i in range(2): + yield i + def g(p): + for i in f(): + pass + f_ident = ident(f) + g_ident = ident(g) + self.check_events(g, [(1, 'call', g_ident), + # call the iterator twice to generate values + (2, 'call', f_ident), + (2, 'return', f_ident), + (2, 'call', f_ident), + (2, 'return', f_ident), + # once more; returns end-of-iteration with + # actually raising an exception + (2, 'call', f_ident), + (2, 'return', f_ident), + (1, 'return', g_ident), + ]) + + def test_stop_iteration(self): + def f(): + for i in range(2): + yield i + raise StopIteration + def g(p): + for i in f(): + pass + f_ident = ident(f) + g_ident = ident(g) + self.check_events(g, [(1, 'call', g_ident), + # call the iterator twice to generate values + (2, 'call', f_ident), + (2, 'return', f_ident), + (2, 'call', f_ident), + (2, 'return', f_ident), + # once more to hit the raise: + (2, 'call', f_ident), + (2, 'exception', f_ident), + (1, 'return', g_ident), + ]) + + class ProfileSimulatorTestCase(TestCaseBase): def new_watcher(self): *************** *** 213,216 **** --- 291,333 ---- (1, 'ignore', f_ident), (1, 'propogate-from', f_ident), + ]) + + def test_caught_exception(self): + def f(p): + try: 1/0 + except: pass + f_ident = ident(f) + self.check_events(f, [(1, 'call', f_ident), + (1, 'ignore', f_ident), + (1, 'return', f_ident), + ]) + + def test_distant_exception(self): + def f(): + 1/0 + def g(): + f() + def h(): + g() + def i(): + h() + def j(p): + i() + f_ident = ident(f) + g_ident = ident(g) + h_ident = ident(h) + i_ident = ident(i) + j_ident = ident(j) + self.check_events(j, [(1, 'call', j_ident), + (2, 'call', i_ident), + (3, 'call', h_ident), + (4, 'call', g_ident), + (5, 'call', f_ident), + (5, 'ignore', f_ident), + (5, 'propogate-from', f_ident), + (4, 'propogate-from', g_ident), + (3, 'propogate-from', h_ident), + (2, 'propogate-from', i_ident), + (1, 'propogate-from', j_ident), ]) From fdrake@users.sourceforge.net Wed Oct 3 22:52:53 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 03 Oct 2001 14:52:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.151,1.152 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv26021/api Modified Files: api.tex Log Message: Expand the documentation of the low-level tracing/profiling interface. This reflects what is currently in CVS, which may change before 2.2 is final. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.151 retrieving revision 1.152 diff -C2 -d -r1.151 -r1.152 *** api.tex 2001/09/26 18:12:49 1.151 --- api.tex 2001/10/03 21:52:51 1.152 *************** *** 5226,5238 **** \cfunction{PyEval_SetProfile()} and \cfunction{PyEval_SetTrace()}. The first parameter is the object passed to the registration ! function, \end{ctypedesc} \begin{cvardesc}{int}{PyTrace_CALL} The value of the \var{what} parameter to a \ctype{Py_tracefunc} ! function when a new function or method call is being reported. \end{cvardesc} \begin{cvardesc}{int}{PyTrace_EXCEPT} \end{cvardesc} --- 5226,5259 ---- \cfunction{PyEval_SetProfile()} and \cfunction{PyEval_SetTrace()}. The first parameter is the object passed to the registration ! function as \var{obj}, \var{frame} is the frame object to which the ! event pertains, \var{what} is one of the constants ! \constant{PyTrace_CALL}, \constant{PyTrace_EXCEPT}, ! \constant{PyTrace_LINE} or \constant{PyTrace_RETURN}, and \var{arg} ! depends on the value of \var{what}: ! ! \begin{tableii}{l|l}{constant}{Value of \var{what}}{Meaning of \var{arg}} ! \lineii{PyTrace_CALL}{Always \NULL.} ! \lineii{PyTrace_EXCEPT}{Exception information as returned by ! \function{sys.exc_info()}.} ! \lineii{PyTrace_LINE}{Always \NULL.} ! \lineii{PyTrace_RETURN}{Value being returned to the caller.} ! \end{tableii} \end{ctypedesc} \begin{cvardesc}{int}{PyTrace_CALL} The value of the \var{what} parameter to a \ctype{Py_tracefunc} ! function when a new call to a function or method is being reported, ! or a new entry into a generator. Note that the creation of the ! iterator for a generator function is not reported as there is no ! control transfer to the Python bytecode in the corresponding frame. \end{cvardesc} \begin{cvardesc}{int}{PyTrace_EXCEPT} + The value of the \var{what} parameter to a \ctype{Py_tracefunc} + function when an exception has been raised by Python code as the + result of an operation. The operation may have explictly intended + to raise the operation (as with a \keyword{raise} statement), or may + have triggered an exception in the runtime as a result of the + specific operation. \end{cvardesc} From gvanrossum@users.sourceforge.net Thu Oct 4 01:58:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 03 Oct 2001 17:58:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_profile,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv14852/test/output Added Files: test_profile Log Message: Hopefully fix the profiler right. Add a test suite that checks that it deals correctly with some anomalous cases; according to this test suite I've fixed it right. The anomalous cases had to do with 'exception' events: these aren't generated when they would be most helpful, and the profiler has to work hard to recover the right information. The problems occur when C code (such as hasattr(), which is used as the example here) calls back into Python code and clears an exception raised by that Python code. Consider this example: def foo(): hasattr(obj, "bar") Where obj is an instance from a class like this: class C: def __getattr__(self, name): raise AttributeError The profiler sees the following sequence of events: call (foo) call (__getattr__) exception (in __getattr__) return (from foo) Previously, the profiler would assume the return event returned from __getattr__. An if statement checking for this condition and raising an exception was commented out... This version does the right thing. --- NEW FILE: test_profile --- test_profile 53 function calls in 1.000 CPU seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 1.000 1.000 :1(?) 0 0.000 0.000 profile:0(profiler) 1 0.000 0.000 1.000 1.000 profile:0(testfunc()) 1 0.400 0.400 1.000 1.000 test_profile.py:21(testfunc) 2 0.080 0.040 0.600 0.300 test_profile.py:30(helper) 4 0.116 0.029 0.120 0.030 test_profile.py:48(helper1) 8 0.312 0.039 0.400 0.050 test_profile.py:56(helper2) 8 0.064 0.008 0.080 0.010 test_profile.py:66(subhelper) 28 0.028 0.001 0.028 0.001 test_profile.py:78(__getattr__) From gvanrossum@users.sourceforge.net Thu Oct 4 01:58:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 03 Oct 2001 17:58:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_profile.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv14852/test Added Files: test_profile.py Log Message: Hopefully fix the profiler right. Add a test suite that checks that it deals correctly with some anomalous cases; according to this test suite I've fixed it right. The anomalous cases had to do with 'exception' events: these aren't generated when they would be most helpful, and the profiler has to work hard to recover the right information. The problems occur when C code (such as hasattr(), which is used as the example here) calls back into Python code and clears an exception raised by that Python code. Consider this example: def foo(): hasattr(obj, "bar") Where obj is an instance from a class like this: class C: def __getattr__(self, name): raise AttributeError The profiler sees the following sequence of events: call (foo) call (__getattr__) exception (in __getattr__) return (from foo) Previously, the profiler would assume the return event returned from __getattr__. An if statement checking for this condition and raising an exception was commented out... This version does the right thing. --- NEW FILE: test_profile.py --- """Test suite for the profile module.""" import profile # In order to have reproducible time, we simulate a timer in the global # variable 'ticks', which represents simulated time in milliseconds. # (We can't use a helper function increment the timer since it would be # included in the profile and would appear to consume all the time.) ticks = 0 def test_main(): global ticks ticks = 0 prof = profile.Profile(timer) prof.runctx("testfunc()", globals(), globals()) prof.print_stats() def timer(): return ticks*0.001 def testfunc(): # 1 call # 1000 ticks total: 400 ticks local, 600 ticks in subfunctions global ticks ticks += 199 helper() # 300 helper() # 300 ticks += 201 def helper(): # 2 calls # 300 ticks total: 40 ticks local, 260 ticks in subfunctions global ticks ticks += 1 helper1() # 30 ticks += 3 helper1() # 30 ticks += 6 helper2() # 50 ticks += 5 helper2() # 50 ticks += 4 helper2() # 50 ticks += 7 helper2() # 50 ticks += 14 def helper1(): # 4 calls # 30 ticks total: 29 ticks local, 1 tick in subfunctions global ticks ticks += 10 hasattr(C(), "foo") ticks += 19 def helper2(): # 8 calls # 50 ticks local: 39 ticks local, 11 ticks in subfunctions global ticks ticks += 11 hasattr(C(), "bar") # 1 ticks += 13 subhelper() # 10 ticks += 15 def subhelper(): # 8 calls # 10 ticks total: 8 ticks local, 2 ticks in subfunctions global ticks ticks += 2 for i in range(2): try: C().foo # 1 x 2 except AttributeError: ticks += 3 # 3 x 2 class C: def __getattr__(self, name): # 28 calls # 1 tick, local global ticks ticks += 1 raise AttributeError if __name__ == "__main__": test_main() From gvanrossum@users.sourceforge.net Thu Oct 4 01:58:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 03 Oct 2001 17:58:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv14852 Modified Files: profile.py Log Message: Hopefully fix the profiler right. Add a test suite that checks that it deals correctly with some anomalous cases; according to this test suite I've fixed it right. The anomalous cases had to do with 'exception' events: these aren't generated when they would be most helpful, and the profiler has to work hard to recover the right information. The problems occur when C code (such as hasattr(), which is used as the example here) calls back into Python code and clears an exception raised by that Python code. Consider this example: def foo(): hasattr(obj, "bar") Where obj is an instance from a class like this: class C: def __getattr__(self, name): raise AttributeError The profiler sees the following sequence of events: call (foo) call (__getattr__) exception (in __getattr__) return (from foo) Previously, the profiler would assume the return event returned from __getattr__. An if statement checking for this condition and raising an exception was commented out... This version does the right thing. Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** profile.py 2001/10/03 21:12:32 1.32 --- profile.py 2001/10/04 00:58:24 1.33 *************** *** 110,125 **** used to write into the frames local dictionary!!) Derived classes can change the definition of some entries, as long as they leave ! [-2:] intact. ! [ 0] = Time that needs to be charged to the parent frame's function. ! It is used so that a function call will not have to access the ! timing data for the parent frame. ! [ 1] = Total time spent in this frame's function, excluding time in ! subfunctions ! [ 2] = Cumulative time spent in this frame's function, including time in ! all subfunctions to this frame. ! [-3] = Name of the function that corresponds to this frame. ! [-2] = Actual frame that we correspond to (used to sync exception handling) ! [-1] = Our parent 6-tuple (corresponds to frame.f_back) Timing data for each function is stored as a 5-tuple in the dictionary --- 110,125 ---- used to write into the frames local dictionary!!) Derived classes can change the definition of some entries, as long as they leave ! [3:] intact. ! [0] = Time that needs to be charged to the parent frame's function. ! It is used so that a function call will not have to access the ! timing data for the parent frame. ! [1] = Total time spent in this frame's function, excluding time in ! subfunctions ! [2] = Cumulative time spent in this frame's function, including time in ! all subfunctions to this frame (but excluding this frame!). ! [3] = Name of the function that corresponds to this frame. ! [4] = Actual frame that we correspond to (used to sync exception handling) ! [5] = Our parent 6-tuple (corresponds to frame.f_back) Timing data for each function is stored as a 5-tuple in the dictionary *************** *** 244,251 **** if (rframe is not frame) and rcur: return self.trace_dispatch_return(rframe, t) ! return 0 def trace_dispatch_call(self, frame, t): fcode = frame.f_code fn = (fcode.co_filename, fcode.co_firstlineno, fcode.co_name) --- 244,262 ---- if (rframe is not frame) and rcur: return self.trace_dispatch_return(rframe, t) ! self.cur = rt, rtt+t, rct, rfn, rframe, rcur ! return 1 def trace_dispatch_call(self, frame, t): + if self.cur and frame.f_back is not self.cur[4]: + rt, rtt, rct, rfn, rframe, rcur = self.cur + if not isinstance(rframe, Profile.fake_frame): + if rframe.f_back is not frame.f_back: + print rframe, rframe.f_back + print frame, frame.f_back + raise "Bad call", self.cur[3] + self.trace_dispatch_return(rframe, 0) + if self.cur and frame.f_back is not self.cur[4]: + raise "Bad call[2]", self.cur[3] fcode = frame.f_code fn = (fcode.co_filename, fcode.co_firstlineno, fcode.co_name) *************** *** 260,264 **** def trace_dispatch_return(self, frame, t): ! # if not frame is self.cur[-2]: raise "Bad return", self.cur[3] # Prefix "r" means part of the Returning or exiting frame --- 271,279 ---- def trace_dispatch_return(self, frame, t): ! if frame is not self.cur[4]: ! if frame is self.cur[4].f_back: ! self.trace_dispatch_return(self.cur[4], 0) ! else: ! raise "Bad return", self.cur[3] # Prefix "r" means part of the Returning or exiting frame *************** *** 303,307 **** def set_cmd(self, cmd): ! if self.cur[-1]: return # already set self.cmd = cmd self.simulate_call(cmd) --- 318,322 ---- def set_cmd(self, cmd): ! if self.cur[5]: return # already set self.cmd = cmd self.simulate_call(cmd) *************** *** 325,329 **** code = self.fake_code('profile', 0, name) if self.cur: ! pframe = self.cur[-2] else: pframe = None --- 340,344 ---- code = self.fake_code('profile', 0, name) if self.cur: ! pframe = self.cur[4] else: pframe = None *************** *** 338,345 **** get_time = self.get_time t = get_time() - self.t ! while self.cur[-1]: # We *can* cause assertion errors here if # dispatch_trace_return checks for a frame match! ! a = self.dispatch['return'](self, self.cur[-2], t) t = 0 self.t = get_time() - t --- 353,360 ---- get_time = self.get_time t = get_time() - self.t ! while self.cur[5]: # We *can* cause assertion errors here if # dispatch_trace_return checks for a frame match! ! a = self.dispatch['return'](self, self.cur[4], t) t = 0 self.t = get_time() - t From montanaro@users.sourceforge.net Thu Oct 4 05:58:58 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Wed, 03 Oct 2001 21:58:58 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0252.txt,1.18,1.19 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv31327 Modified Files: pep-0252.txt Log Message: fix three trivial typos. Index: pep-0252.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0252.txt,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** pep-0252.txt 2001/09/08 12:42:48 1.18 --- pep-0252.txt 2001/10/04 04:58:56 1.19 *************** *** 159,163 **** In the discussion below, I distinguish two kinds of objects: regular objects (like lists, ints, functions) and meta-objects. ! Types and classes and meta-objects. Meta-objects are also regular objects, but we're mostly interested in them because they are referenced by the __class__ attribute of regular objects (or by --- 159,163 ---- In the discussion below, I distinguish two kinds of objects: regular objects (like lists, ints, functions) and meta-objects. ! Types and classes are meta-objects. Meta-objects are also regular objects, but we're mostly interested in them because they are referenced by the __class__ attribute of regular objects (or by *************** *** 226,230 **** an empty sequence of bases. There must never be a cycle in the relationship between meta-objects defined by __bases__ ! attributes; in other words, the __bases__ attributes define an directed acyclic graph, with arcs pointing from derived meta-objects to their base meta-objects. (It is not --- 226,230 ---- an empty sequence of bases. There must never be a cycle in the relationship between meta-objects defined by __bases__ ! attributes; in other words, the __bases__ attributes define a directed acyclic graph, with arcs pointing from derived meta-objects to their base meta-objects. (It is not *************** *** 556,560 **** above is suitable for most built-in objects such as lists, strings, numbers. However, some object types have a dictionary ! in each instance that can store arbitrary attribute. In fact, when you use a class statement to subtype an existing built-in type, you automatically get such a dictionary (unless you --- 556,560 ---- above is suitable for most built-in objects such as lists, strings, numbers. However, some object types have a dictionary ! in each instance that can store arbitrary attributes. In fact, when you use a class statement to subtype an existing built-in type, you automatically get such a dictionary (unless you From tim_one@users.sourceforge.net Thu Oct 4 06:27:02 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 03 Oct 2001 22:27:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.81,1.82 test_doctest2.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv1972/python/Lib/test Modified Files: test_descr.py test_doctest2.py Log Message: SF bug [#467331] ClassType.__doc__ always None. For a dynamically constructed type object, fill in the tp_doc slot with a copy of the argument dict's "__doc__" value, provided the latter exists and is a string. NOTE: I don't know what to do if it's a Unicode string, so in that case tp_doc is left NULL (which shows up as Py_None if you do Class.__doc__). Note that tp_doc holds a char*, not a general PyObject*. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.81 retrieving revision 1.82 diff -C2 -d -r1.81 -r1.82 *** test_descr.py 2001/10/03 13:59:54 1.81 --- test_descr.py 2001/10/04 05:27:00 1.82 *************** *** 89,92 **** --- 89,124 ---- verify(dict['a'] == res) + def class_docstrings(): + class Classic: + "A classic docstring." + verify(Classic.__doc__ == "A classic docstring.") + verify(Classic.__dict__['__doc__'] == "A classic docstring.") + + class Classic2: + pass + verify(Classic2.__doc__ is None) + + class NewStatic: + "Another docstring." + __dynamic__ = 0 + verify(NewStatic.__doc__ == "Another docstring.") + verify(NewStatic.__dict__['__doc__'] == "Another docstring.") + + class NewStatic2: + __dynamic__ = 0 + pass + verify(NewStatic2.__doc__ is None) + + class NewDynamic: + "Another docstring." + __dynamic__ = 1 + verify(NewDynamic.__doc__ == "Another docstring.") + verify(NewDynamic.__dict__['__doc__'] == "Another docstring.") + + class NewDynamic2: + __dynamic__ = 1 + pass + verify(NewDynamic2.__doc__ is None) + def lists(): if verbose: print "Testing list operations..." *************** *** 2169,2173 **** else: return I(pow(int(other), int(self), int(mod))) ! vereq(`I(1) + I(2)`, "I(3)") vereq(`I(1) + 2`, "I(3)") --- 2201,2205 ---- else: return I(pow(int(other), int(self), int(mod))) ! vereq(`I(1) + I(2)`, "I(3)") vereq(`I(1) + 2`, "I(3)") *************** *** 2183,2186 **** --- 2215,2219 ---- def test_main(): + class_docstrings() lists() dicts() Index: test_doctest2.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_doctest2.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_doctest2.py 2001/10/03 04:15:28 1.2 --- test_doctest2.py 2001/10/04 05:27:00 1.3 *************** *** 8,12 **** import test_support - # XXX The class docstring is skipped. class C(object): """Class C. --- 8,11 ---- *************** *** 30,34 **** return "42" - # XXX The class docstring is skipped. class D(object): """A nested D class. --- 29,32 ---- *************** *** 97,103 **** def test_main(): import test_doctest2 ! # XXX 2 class docstrings are skipped. ! # EXPECTED = 19 ! EXPECTED = 17 f, t = test_support.run_doctest(test_doctest2) if t != EXPECTED: --- 95,99 ---- def test_main(): import test_doctest2 ! EXPECTED = 19 f, t = test_support.run_doctest(test_doctest2) if t != EXPECTED: From tim_one@users.sourceforge.net Thu Oct 4 06:27:02 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 03 Oct 2001 22:27:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.86,2.87 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv1972/python/Objects Modified Files: typeobject.c Log Message: SF bug [#467331] ClassType.__doc__ always None. For a dynamically constructed type object, fill in the tp_doc slot with a copy of the argument dict's "__doc__" value, provided the latter exists and is a string. NOTE: I don't know what to do if it's a Unicode string, so in that case tp_doc is left NULL (which shows up as Py_None if you do Class.__doc__). Note that tp_doc holds a char*, not a general PyObject*. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.86 retrieving revision 2.87 diff -C2 -d -r2.86 -r2.87 *** typeobject.c 2001/10/03 13:58:35 2.86 --- typeobject.c 2001/10/04 05:27:00 2.87 *************** *** 901,904 **** --- 901,922 ---- } + /* Set tp_doc to a copy of dict['__doc__'], if the latter is there + and is a string (tp_doc is a char* -- can't copy a general object + into it). + XXX What if it's a Unicode string? Don't know -- this ignores it. + */ + { + PyObject *doc = PyDict_GetItemString(dict, "__doc__"); + if (doc != NULL && PyString_Check(doc)) { + const size_t n = (size_t)PyString_GET_SIZE(doc); + type->tp_doc = PyObject_MALLOC(n+1); + if (type->tp_doc == NULL) { + Py_DECREF(type); + return NULL; + } + memcpy(type->tp_doc, PyString_AS_STRING(doc), n+1); + } + } + /* Special-case __new__: if it's a plain function, make it a static function */ *************** *** 1163,1166 **** --- 1181,1189 ---- CLEAR(et->slots); + if (type->tp_doc != NULL) { + PyObject_FREE(type->tp_doc); + type->tp_doc = NULL; + } + #undef CLEAR *************** *** 1351,1355 **** "__class__ assignment: " "'%s' object layout differs from '%s'", ! new->tp_name, old->tp_name); return -1; --- 1374,1378 ---- "__class__ assignment: " "'%s' object layout differs from '%s'", ! new->tp_name, old->tp_name); return -1; From tim_one@users.sourceforge.net Thu Oct 4 06:36:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 03 Oct 2001 22:36:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib difflib.py,1.5,1.6 quopri.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv3849/python/Lib Modified Files: difflib.py quopri.py Log Message: Whitespace normalization. Index: difflib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/difflib.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** difflib.py 2001/09/22 21:30:22 1.5 --- difflib.py 2001/10/04 05:36:56 1.6 *************** *** 947,951 **** yield "- " + aline if atags: ! yield "? %s%s\n" % ("\t" * common, atags) yield "+ " + bline --- 947,951 ---- yield "- " + aline if atags: ! yield "? %s%s\n" % ("\t" * common, atags) yield "+ " + bline Index: quopri.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/quopri.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** quopri.py 2001/09/30 20:32:10 1.16 --- quopri.py 2001/10/04 05:36:56 1.17 *************** *** 13,20 **** try: ! from binascii import a2b_qp, b2a_qp except: ! a2b_qp = None ! b2a_qp = None --- 13,20 ---- try: ! from binascii import a2b_qp, b2a_qp except: ! a2b_qp = None ! b2a_qp = None *************** *** 29,33 **** return quotetabs # if header, we have to escape _ because _ is used to escape space ! if c == '_': return header return c == ESCAPE or not (' ' <= c <= '~') --- 29,33 ---- return quotetabs # if header, we have to escape _ because _ is used to escape space ! if c == '_': return header return c == ESCAPE or not (' ' <= c <= '~') *************** *** 56,60 **** output.write(odata) return ! def write(s, output=output, lineEnd='\n'): # RFC 1521 requires that the line ending in a space or tab must have --- 56,60 ---- output.write(odata) return ! def write(s, output=output, lineEnd='\n'): # RFC 1521 requires that the line ending in a space or tab must have From tim_one@users.sourceforge.net Thu Oct 4 06:36:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 03 Oct 2001 22:36:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email Encoders.py,1.2,1.3 Errors.py,1.1,1.2 Generator.py,1.2,1.3 Iterators.py,1.2,1.3 MIMEBase.py,1.2,1.3 MIMEImage.py,1.1,1.2 MIMEMessage.py,1.1,1.2 MIMEText.py,1.1,1.2 Message.py,1.2,1.3 Parser.py,1.2,1.3 Utils.py,1.1,1.2 __init__.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv3849/python/Lib/email Modified Files: Encoders.py Errors.py Generator.py Iterators.py MIMEBase.py MIMEImage.py MIMEMessage.py MIMEText.py Message.py Parser.py Utils.py __init__.py Log Message: Whitespace normalization. Index: Encoders.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Encoders.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Encoders.py 2001/09/26 05:26:22 1.2 --- Encoders.py 2001/10/04 05:36:56 1.3 *************** *** 9,13 **** ! # Helpers def _qencode(s): --- 9,13 ---- ! # Helpers def _qencode(s): *************** *** 27,31 **** ! def encode_base64(msg): """Encode the message's payload in Base64. --- 27,31 ---- ! def encode_base64(msg): """Encode the message's payload in Base64. *************** *** 39,43 **** ! def encode_quopri(msg): """Encode the message's payload in Quoted-Printable. --- 39,43 ---- ! def encode_quopri(msg): """Encode the message's payload in Quoted-Printable. *************** *** 51,55 **** ! def encode_7or8bit(msg): """Set the Content-Transfer-Encoding: header to 7bit or 8bit.""" --- 51,55 ---- ! def encode_7or8bit(msg): """Set the Content-Transfer-Encoding: header to 7bit or 8bit.""" *************** *** 65,69 **** ! def encode_noop(msg): """Do nothing.""" --- 65,69 ---- ! def encode_noop(msg): """Do nothing.""" Index: Errors.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Errors.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Errors.py 2001/09/23 03:17:28 1.1 --- Errors.py 2001/10/04 05:36:56 1.2 *************** *** 6,10 **** ! class MessageError(Exception): """Base class for errors in this module.""" --- 6,10 ---- ! class MessageError(Exception): """Base class for errors in this module.""" Index: Generator.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Generator.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Generator.py 2001/09/26 05:32:41 1.2 --- Generator.py 2001/10/04 05:36:56 1.3 *************** *** 26,30 **** ! class Generator: """Generates output from a Message object tree. --- 26,30 ---- ! class Generator: """Generates output from a Message object tree. *************** *** 279,283 **** ! class DecodedGenerator(Generator): """Generator a text representation of a message. --- 279,283 ---- ! class DecodedGenerator(Generator): """Generator a text representation of a message. *************** *** 335,339 **** ! # Helper def _make_boundary(self, text=None): --- 335,339 ---- ! # Helper def _make_boundary(self, text=None): Index: Iterators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Iterators.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Iterators.py 2001/09/26 05:35:47 1.2 --- Iterators.py 2001/10/04 05:36:56 1.3 *************** *** 10,14 **** ! def body_line_iterator(msg): """Iterate over the parts, returning string payloads line-by-line.""" --- 10,14 ---- ! def body_line_iterator(msg): """Iterate over the parts, returning string payloads line-by-line.""" *************** *** 20,24 **** ! def typed_subpart_iterator(msg, maintype='text', subtype=None): """Iterate over the subparts with a given MIME type. --- 20,24 ---- ! def typed_subpart_iterator(msg, maintype='text', subtype=None): """Iterate over the subparts with a given MIME type. Index: MIMEBase.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/MIMEBase.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** MIMEBase.py 2001/09/26 05:36:36 1.2 --- MIMEBase.py 2001/10/04 05:36:56 1.3 *************** *** 8,12 **** ! class MIMEBase(Message.Message): """Base class for MIME specializations.""" --- 8,12 ---- ! class MIMEBase(Message.Message): """Base class for MIME specializations.""" Index: MIMEImage.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/MIMEImage.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** MIMEImage.py 2001/09/26 05:34:30 1.1 --- MIMEImage.py 2001/10/04 05:36:56 1.2 *************** *** 13,17 **** ! class MIMEImage(MIMEBase.MIMEBase): """Class for generating image/* type MIME documents.""" --- 13,17 ---- ! class MIMEImage(MIMEBase.MIMEBase): """Class for generating image/* type MIME documents.""" Index: MIMEMessage.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/MIMEMessage.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** MIMEMessage.py 2001/09/26 05:34:30 1.1 --- MIMEMessage.py 2001/10/04 05:36:56 1.2 *************** *** 9,13 **** ! class MIMEMessage(MIMEBase.MIMEBase): """Class representing message/* MIME documents.""" --- 9,13 ---- ! class MIMEMessage(MIMEBase.MIMEBase): """Class representing message/* MIME documents.""" Index: MIMEText.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/MIMEText.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** MIMEText.py 2001/09/26 05:34:30 1.1 --- MIMEText.py 2001/10/04 05:36:56 1.2 *************** *** 9,13 **** ! class MIMEText(MIMEBase.MIMEBase): """Class for generating text/* type MIME documents.""" --- 9,13 ---- ! class MIMEText(MIMEBase.MIMEBase): """Class for generating text/* type MIME documents.""" Index: Message.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Message.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Message.py 2001/09/26 05:41:51 1.2 --- Message.py 2001/10/04 05:36:56 1.3 *************** *** 21,25 **** ! class Message: """Basic message object for use inside the object tree. --- 21,25 ---- ! class Message: """Basic message object for use inside the object tree. *************** *** 431,435 **** def get_charsets(self, failobj=None): """Return a list containing the charset(s) used in this message. ! The returned list of items describes the Content-Type: headers' charset parameter for this message and all the subparts in its --- 431,435 ---- def get_charsets(self, failobj=None): """Return a list containing the charset(s) used in this message. ! The returned list of items describes the Content-Type: headers' charset parameter for this message and all the subparts in its Index: Parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Parser.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Parser.py 2001/09/26 05:44:09 1.2 --- Parser.py 2001/10/04 05:36:56 1.3 *************** *** 15,19 **** ! class Parser: def __init__(self, _class=Message.Message): --- 15,19 ---- ! class Parser: def __init__(self, _class=Message.Message): Index: Utils.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Utils.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Utils.py 2001/09/23 03:17:28 1.1 --- Utils.py 2001/10/04 05:36:56 1.2 *************** *** 22,26 **** ! # Helpers --- 22,26 ---- ! # Helpers *************** *** 43,47 **** ! def getaddresses(fieldvalues): """Return a list of (REALNAME, EMAIL) for each fieldvalue.""" --- 43,47 ---- ! def getaddresses(fieldvalues): """Return a list of (REALNAME, EMAIL) for each fieldvalue.""" *************** *** 51,55 **** ! ecre = re.compile(r''' =\? # literal =? --- 51,55 ---- ! ecre = re.compile(r''' =\? # literal =? *************** *** 93,97 **** ! def encode(s, charset='iso-8859-1', encoding='q'): """Encode a string according to RFC 2047.""" --- 93,97 ---- ! def encode(s, charset='iso-8859-1', encoding='q'): """Encode a string according to RFC 2047.""" Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/__init__.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** __init__.py 2001/09/23 03:17:28 1.1 --- __init__.py 2001/10/04 05:36:56 1.2 *************** *** 23,27 **** ! # Some convenience routines from Parser import Parser as _Parser --- 23,27 ---- ! # Some convenience routines from Parser import Parser as _Parser From tim_one@users.sourceforge.net Thu Oct 4 06:36:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 03 Oct 2001 22:36:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_email.py,1.2,1.3 test_iter.py,1.21,1.22 test_profile.py,1.1,1.2 test_unicode.py,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv3849/python/Lib/test Modified Files: test_email.py test_iter.py test_profile.py test_unicode.py Log Message: Whitespace normalization. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_email.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_email.py 2001/09/26 05:47:08 1.2 --- test_email.py 2001/10/04 05:36:56 1.3 *************** *** 29,33 **** ! def openfile(filename): path = os.path.join(os.path.dirname(test.regrtest.__file__), --- 29,33 ---- ! def openfile(filename): path = os.path.join(os.path.dirname(test.regrtest.__file__), *************** *** 36,40 **** ! # Base test class class TestEmailBase(unittest.TestCase): --- 36,40 ---- ! # Base test class class TestEmailBase(unittest.TestCase): *************** *** 48,57 **** ! # Test various aspects of the Message class's API class TestMessageAPI(TestEmailBase): def test_get_charsets(self): eq = self.assertEqual ! msg = self._msgobj('msg_08.txt') charsets = msg.get_charsets() --- 48,57 ---- ! # Test various aspects of the Message class's API class TestMessageAPI(TestEmailBase): def test_get_charsets(self): eq = self.assertEqual ! msg = self._msgobj('msg_08.txt') charsets = msg.get_charsets() *************** *** 176,180 **** "Content-Disposition: blarg; filename\n") self.assertEqual(msg.get_filename(), '') ! def test_missing_boundary(self): msg = email.message_from_string("From: foo\n") --- 176,180 ---- "Content-Disposition: blarg; filename\n") self.assertEqual(msg.get_filename(), '') ! def test_missing_boundary(self): msg = email.message_from_string("From: foo\n") *************** *** 218,222 **** ! # Test the email.Encoders module class TestEncoders(unittest.TestCase): --- 218,222 ---- ! # Test the email.Encoders module class TestEncoders(unittest.TestCase): *************** *** 255,259 **** ! class TestLongHeaders(unittest.TestCase): def test_header_splitter(self): --- 255,259 ---- ! class TestLongHeaders(unittest.TestCase): def test_header_splitter(self): *************** *** 272,281 **** Content-Transfer-Encoding: 7bit X-Foobar-Spoink-Defrobnit: wasnipoop; giraffes="very-long-necked-animals"; ! spooge="yummy"; hippos="gargantuan"; marshmallows="gooey" ''') ! class TestFromMangling(unittest.TestCase): def setUp(self): --- 272,281 ---- Content-Transfer-Encoding: 7bit X-Foobar-Spoink-Defrobnit: wasnipoop; giraffes="very-long-necked-animals"; ! spooge="yummy"; hippos="gargantuan"; marshmallows="gooey" ''') ! class TestFromMangling(unittest.TestCase): def setUp(self): *************** *** 310,314 **** ! # Test the basic MIMEImage class class TestMIMEImage(unittest.TestCase): --- 310,314 ---- ! # Test the basic MIMEImage class class TestMIMEImage(unittest.TestCase): *************** *** 363,367 **** ! # Test the basic MIMEText class class TestMIMEText(unittest.TestCase): --- 363,367 ---- ! # Test the basic MIMEText class class TestMIMEText(unittest.TestCase): *************** *** 384,388 **** ! class TestMultipartMixed(unittest.TestCase): def setUp(self): --- 384,388 ---- ! class TestMultipartMixed(unittest.TestCase): def setUp(self): *************** *** 407,411 **** container['To'] = 'Dingus Lovers ' container['Subject'] = 'Here is your dingus fish' ! now = 987809702.54848599 timetuple = time.localtime(now) --- 407,411 ---- container['To'] = 'Dingus Lovers ' container['Subject'] = 'Here is your dingus fish' ! now = 987809702.54848599 timetuple = time.localtime(now) *************** *** 446,450 **** ! class TestNonConformant(TestEmailBase): def test_parse_missing_minor_type(self): --- 446,450 ---- ! class TestNonConformant(TestEmailBase): def test_parse_missing_minor_type(self): *************** *** 467,471 **** ! class TestRFC2047(unittest.TestCase): def test_iso_8859_1(self): --- 467,471 ---- ! class TestRFC2047(unittest.TestCase): def test_iso_8859_1(self): *************** *** 498,502 **** ! class TestMIMEMessage(TestEmailBase): def setUp(self): --- 498,502 ---- ! class TestMIMEMessage(TestEmailBase): def setUp(self): *************** *** 604,608 **** ! class TestIdempotent(unittest.TestCase): def _msgobj(self, filename): --- 604,608 ---- ! class TestIdempotent(unittest.TestCase): def _msgobj(self, filename): *************** *** 653,657 **** msg, text = self._msgobj('msg_06.txt') self._idempotent(msg, text) ! def test_multipart_report(self): msg, text = self._msgobj('msg_05.txt') --- 653,657 ---- msg, text = self._msgobj('msg_06.txt') self._idempotent(msg, text) ! def test_multipart_report(self): msg, text = self._msgobj('msg_05.txt') *************** *** 661,665 **** msg, text = self._msgobj('msg_16.txt') self._idempotent(msg, text) ! def test_content_type(self): eq = self.assertEquals --- 661,665 ---- msg, text = self._msgobj('msg_16.txt') self._idempotent(msg, text) ! def test_content_type(self): eq = self.assertEquals *************** *** 702,708 **** self.failUnless(isinstance(msg1.get_payload(), StringType)) eq(msg1.get_payload(), '\n') - ! class TestMiscellaneous(unittest.TestCase): def test_message_from_string(self): --- 702,708 ---- self.failUnless(isinstance(msg1.get_payload(), StringType)) eq(msg1.get_payload(), '\n') ! ! class TestMiscellaneous(unittest.TestCase): def test_message_from_string(self): *************** *** 745,749 **** class MyMessage(Message): pass ! msg = email.message_from_string(text, MyMessage) unless(isinstance(msg, MyMessage)) --- 745,749 ---- class MyMessage(Message): pass ! msg = email.message_from_string(text, MyMessage) unless(isinstance(msg, MyMessage)) *************** *** 764,768 **** class MyMessage(Message): pass ! fp = openfile('msg_01.txt') try: --- 764,768 ---- class MyMessage(Message): pass ! fp = openfile('msg_01.txt') try: *************** *** 781,785 **** ! class TestIterators(TestEmailBase): def test_body_line_iterator(self): --- 781,785 ---- ! class TestIterators(TestEmailBase): def test_body_line_iterator(self): *************** *** 802,814 **** eq(EMPTYSTRING.join(lines), """\ Send Ppp mailing list submissions to ! ppp@zzz.org To subscribe or unsubscribe via the World Wide Web, visit ! http://www.zzz.org/mailman/listinfo/ppp or, via email, send a message with subject or body 'help' to ! ppp-request@zzz.org You can reach the person managing the list at ! ppp-admin@zzz.org When replying, please edit your Subject line so it is more specific --- 802,814 ---- eq(EMPTYSTRING.join(lines), """\ Send Ppp mailing list submissions to ! ppp@zzz.org To subscribe or unsubscribe via the World Wide Web, visit ! http://www.zzz.org/mailman/listinfo/ppp or, via email, send a message with subject or body 'help' to ! ppp-request@zzz.org You can reach the person managing the list at ! ppp-admin@zzz.org When replying, please edit your Subject line so it is more specific *************** *** 864,868 **** ! def suite(): suite = unittest.TestSuite() --- 864,868 ---- ! def suite(): suite = unittest.TestSuite() *************** *** 883,887 **** ! if __name__ == '__main__': unittest.main(defaultTest='suite') --- 883,887 ---- ! if __name__ == '__main__': unittest.main(defaultTest='suite') Index: test_iter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_iter.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** test_iter.py 2001/09/23 04:06:04 1.21 --- test_iter.py 2001/10/04 05:36:56 1.22 *************** *** 649,653 **** self.assertRaises(TypeError, f.writelines, None) self.assertRaises(TypeError, f.writelines, 42) ! f.writelines(["1\n", "2\n"]) f.writelines(("3\n", "4\n")) --- 649,653 ---- self.assertRaises(TypeError, f.writelines, None) self.assertRaises(TypeError, f.writelines, 42) ! f.writelines(["1\n", "2\n"]) f.writelines(("3\n", "4\n")) *************** *** 679,684 **** def __iter__(self): return Iterator(self.start, self.finish) ! ! f.writelines(Whatever(6, 6+2000)) f.close() --- 679,684 ---- def __iter__(self): return Iterator(self.start, self.finish) ! ! f.writelines(Whatever(6, 6+2000)) f.close() *************** *** 686,690 **** expected = [str(i) + "\n" for i in range(1, 2006)] self.assertEqual(list(f), expected) ! finally: f.close() --- 686,690 ---- expected = [str(i) + "\n" for i in range(1, 2006)] self.assertEqual(list(f), expected) ! finally: f.close() Index: test_profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_profile.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_profile.py 2001/10/04 00:58:24 1.1 --- test_profile.py 2001/10/04 05:36:56 1.2 *************** *** 8,12 **** # included in the profile and would appear to consume all the time.) ticks = 0 ! def test_main(): global ticks --- 8,12 ---- # included in the profile and would appear to consume all the time.) ticks = 0 ! def test_main(): global ticks Index: test_unicode.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode.py,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** test_unicode.py 2001/09/21 15:46:41 1.40 --- test_unicode.py 2001/10/04 05:36:56 1.41 *************** *** 410,414 **** verify( x.encode('utf-7') == y ) ! try: unicode('+3ADYAA-', 'utf-7') # surrogates not supported except UnicodeError: --- 410,414 ---- verify( x.encode('utf-7') == y ) ! try: unicode('+3ADYAA-', 'utf-7') # surrogates not supported except UnicodeError: From tim_one@users.sourceforge.net Thu Oct 4 06:43:04 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 03 Oct 2001 22:43:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.87,2.88 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv4540/python/Objects Modified Files: typeobject.c Log Message: type_new(): cast PyObject_MALLOC's result to char*, for clarity. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.87 retrieving revision 2.88 diff -C2 -d -r2.87 -r2.88 *** typeobject.c 2001/10/04 05:27:00 2.87 --- typeobject.c 2001/10/04 05:43:02 2.88 *************** *** 910,914 **** if (doc != NULL && PyString_Check(doc)) { const size_t n = (size_t)PyString_GET_SIZE(doc); ! type->tp_doc = PyObject_MALLOC(n+1); if (type->tp_doc == NULL) { Py_DECREF(type); --- 910,914 ---- if (doc != NULL && PyString_Check(doc)) { const size_t n = (size_t)PyString_GET_SIZE(doc); ! type->tp_doc = (char *)PyObject_MALLOC(n+1); if (type->tp_doc == NULL) { Py_DECREF(type); From tim_one@users.sourceforge.net Thu Oct 4 06:48:15 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 03 Oct 2001 22:48:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.82,1.83 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv5375/python/Lib/test Modified Files: test_descr.py Log Message: class_docstrings(): The new-style class tests should use new-style classes (sheesh!). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.82 retrieving revision 1.83 diff -C2 -d -r1.82 -r1.83 *** test_descr.py 2001/10/04 05:27:00 1.82 --- test_descr.py 2001/10/04 05:48:13 1.83 *************** *** 99,103 **** verify(Classic2.__doc__ is None) ! class NewStatic: "Another docstring." __dynamic__ = 0 --- 99,103 ---- verify(Classic2.__doc__ is None) ! class NewStatic(object): "Another docstring." __dynamic__ = 0 *************** *** 105,114 **** verify(NewStatic.__dict__['__doc__'] == "Another docstring.") ! class NewStatic2: __dynamic__ = 0 pass verify(NewStatic2.__doc__ is None) ! class NewDynamic: "Another docstring." __dynamic__ = 1 --- 105,114 ---- verify(NewStatic.__dict__['__doc__'] == "Another docstring.") ! class NewStatic2(object): __dynamic__ = 0 pass verify(NewStatic2.__doc__ is None) ! class NewDynamic(object): "Another docstring." __dynamic__ = 1 *************** *** 116,120 **** verify(NewDynamic.__dict__['__doc__'] == "Another docstring.") ! class NewDynamic2: __dynamic__ = 1 pass --- 116,120 ---- verify(NewDynamic.__dict__['__doc__'] == "Another docstring.") ! class NewDynamic2(object): __dynamic__ = 1 pass From tim_one@users.sourceforge.net Thu Oct 4 07:26:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 03 Oct 2001 23:26:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_email.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv11557/python/Lib/test Modified Files: test_email.py Log Message: This test relied on hard tab characters, so failed after whitespace normalization. Now uses \t in strings instead of hard tabs. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_email.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_email.py 2001/10/04 05:36:56 1.3 --- test_email.py 2001/10/04 06:26:17 1.4 *************** *** 272,276 **** Content-Transfer-Encoding: 7bit X-Foobar-Spoink-Defrobnit: wasnipoop; giraffes="very-long-necked-animals"; ! spooge="yummy"; hippos="gargantuan"; marshmallows="gooey" ''') --- 272,276 ---- Content-Transfer-Encoding: 7bit X-Foobar-Spoink-Defrobnit: wasnipoop; giraffes="very-long-necked-animals"; ! \tspooge="yummy"; hippos="gargantuan"; marshmallows="gooey" ''') *************** *** 802,814 **** eq(EMPTYSTRING.join(lines), """\ Send Ppp mailing list submissions to ! ppp@zzz.org To subscribe or unsubscribe via the World Wide Web, visit ! http://www.zzz.org/mailman/listinfo/ppp or, via email, send a message with subject or body 'help' to ! ppp-request@zzz.org You can reach the person managing the list at ! ppp-admin@zzz.org When replying, please edit your Subject line so it is more specific --- 802,814 ---- eq(EMPTYSTRING.join(lines), """\ Send Ppp mailing list submissions to ! \tppp@zzz.org To subscribe or unsubscribe via the World Wide Web, visit ! \thttp://www.zzz.org/mailman/listinfo/ppp or, via email, send a message with subject or body 'help' to ! \tppp-request@zzz.org You can reach the person managing the list at ! \tppp-admin@zzz.org When replying, please edit your Subject line so it is more specific From tim_one@users.sourceforge.net Thu Oct 4 07:43:14 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 03 Oct 2001 23:43:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.267,1.268 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv15409/python/Misc Modified Files: NEWS Log Message: Added a little type/class NEWS. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.267 retrieving revision 1.268 diff -C2 -d -r1.267 -r1.268 *** NEWS 2001/10/02 23:15:37 1.267 --- NEWS 2001/10/04 06:43:12 1.268 *************** *** 5,8 **** --- 5,14 ---- Type/class unification and new-style classes + - C.__doc__ now works as expected for new-style classes (in 2.2a4 it + always returned None, even when there was a class docstring). + + - doctest now finds and runs docstrings attached to new-style classes, + class methods, static methods, and properties. + Core From tim_one@users.sourceforge.net Thu Oct 4 07:53:22 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 03 Oct 2001 23:53:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.88,1.89 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv17101/python/Doc/lib Modified Files: libfuncs.tex Log Message: Make clear that tuple() accepts the same kind of arguments as list(). Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.88 retrieving revision 1.89 diff -C2 -d -r1.88 -r1.89 *** libfuncs.tex 2001/09/30 06:32:59 1.88 --- libfuncs.tex 2001/10/04 06:53:20 1.89 *************** *** 723,727 **** \begin{funcdesc}{tuple}{sequence} Return a tuple whose items are the same and in the same order as ! \var{sequence}'s items. If \var{sequence} is already a tuple, it is returned unchanged. For instance, \code{tuple('abc')} returns returns \code{('a', 'b', 'c')} and \code{tuple([1, 2, 3])} returns --- 723,729 ---- \begin{funcdesc}{tuple}{sequence} Return a tuple whose items are the same and in the same order as ! \var{sequence}'s items. \var{sequence} may be a sequence, a ! container that supports iteration, or an iterator object. ! If \var{sequence} is already a tuple, it is returned unchanged. For instance, \code{tuple('abc')} returns returns \code{('a', 'b', 'c')} and \code{tuple([1, 2, 3])} returns From gvanrossum@users.sourceforge.net Thu Oct 4 11:19:02 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 04 Oct 2001 03:19:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.268,1.269 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv29918 Modified Files: NEWS Log Message: Add note about profile fix. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.268 retrieving revision 1.269 diff -C2 -d -r1.268 -r1.269 *** NEWS 2001/10/04 06:43:12 1.268 --- NEWS 2001/10/04 10:19:00 1.269 *************** *** 22,25 **** --- 22,30 ---- being tested, thanks to Tim Hochberg. + - profile now produces correct output in situations where an exception + raised in Python is cleared by C code (e.g. hasattr()). This used + to cause wrong output, including spurious claims of recursive + functions and attribution of time spent to the wrong function. + - quopri's encode and decode methods take an optional header parameter, which indicates whether output is intended for the header 'Q' encoding. From fdrake@users.sourceforge.net Thu Oct 4 15:48:44 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 04 Oct 2001 07:48:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.279,2.280 sysmodule.c,2.92,2.93 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv28459/Python Modified Files: ceval.c sysmodule.c Log Message: Rationalize the events passed to the profiler (no changes for the tracer). The profiler does not need to know anything about the exception state, so we no longer call it when an exception is raised. We do, however, make sure we *always* call the profiler when we exit a frame. This ensures that timing events are more easily isolated by a profiler and finally clauses that do a lot of work don't have their time mis-allocated. When an exception is propogated out of the frame, the C callback for the profiler now receives a PyTrace_RETURN event with an arg of NULL; the Python-level profile hook function will see a 'return' event with an arg of None. This means that from Python it is impossible for the profiler to determine if the frame exited with an exception or if it returned None, but this doesn't matter for profiling. A C-based profiler could tell the difference, but this doesn't seem important. ceval.c:eval_frame(): Simplify the code in two places so that the profiler is called for every exit from a frame and not for exceptions. sysmodule.c:profile_trampoline(): Make sure we don't expose Python code to NULL; use None instead. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.279 retrieving revision 2.280 diff -C2 -d -r2.279 -r2.280 *** ceval.c 2001/09/30 05:58:42 2.279 --- ceval.c 2001/10/04 14:48:42 2.280 *************** *** 2199,2210 **** PyTraceBack_Here(f); ! if (tstate->use_tracing) { ! if (tstate->c_tracefunc) ! call_exc_trace(tstate->c_tracefunc, ! tstate->c_traceobj, f); ! if (tstate->c_profilefunc) ! call_exc_trace(tstate->c_profilefunc, ! tstate->c_profileobj,f); ! } } --- 2199,2205 ---- PyTraceBack_Here(f); ! if (tstate->c_tracefunc != NULL) ! call_exc_trace(tstate->c_tracefunc, ! tstate->c_traceobj, f); } *************** *** 2302,2307 **** } } ! if (tstate->c_profilefunc ! && (why == WHY_RETURN || why == WHY_YIELD)) { if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, f, --- 2297,2301 ---- } } ! if (tstate->c_profilefunc) { if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, f, Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.92 retrieving revision 2.93 diff -C2 -d -r2.92 -r2.93 *** sysmodule.c 2001/08/17 18:39:25 2.92 --- sysmodule.c 2001/10/04 14:48:42 2.93 *************** *** 261,264 **** --- 261,266 ---- PyObject *result; + if (arg == NULL) + arg = Py_None; result = call_trampoline(tstate, self, frame, what, arg); if (result == NULL) { From fdrake@users.sourceforge.net Thu Oct 4 15:49:48 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 04 Oct 2001 07:49:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_profilehooks.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv28778 Modified Files: test_profilehooks.py Log Message: Updated to reflect the rationalized profiler event reporting. Index: test_profilehooks.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_profilehooks.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_profilehooks.py 2001/10/03 21:15:32 1.5 --- test_profilehooks.py 2001/10/04 14:49:46 1.6 *************** *** 38,42 **** class ProfileSimulator(HookWatcher): ! def __init__(self): self.stack = [] HookWatcher.__init__(self) --- 38,43 ---- class ProfileSimulator(HookWatcher): ! def __init__(self, testcase): ! self.testcase = testcase self.stack = [] HookWatcher.__init__(self) *************** *** 55,65 **** def trace_exception(self, frame): ! if len(self.stack) >= 2 and frame is self.stack[-2]: ! self.add_event('propogate-from', self.stack[-1]) ! self.stack.pop() ! else: ! # Either an exception was raised in Python or a C function ! # raised an exception; this does not represent propogation. ! self.add_event('ignore', frame) dispatch = { --- 56,61 ---- def trace_exception(self, frame): ! self.testcase.fail( ! "the profiler should never receive exception events") dispatch = { *************** *** 95,100 **** f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), ! (1, 'exception', f_ident), ! (0, 'exception', protect_ident), ]) --- 91,95 ---- f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), ! (1, 'return', f_ident), ]) *************** *** 105,109 **** f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), - (1, 'exception', f_ident), (1, 'return', f_ident), ]) --- 100,103 ---- *************** *** 115,119 **** f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), - (1, 'exception', f_ident), (1, 'return', f_ident), ]) --- 109,112 ---- *************** *** 124,132 **** f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), - (1, 'exception', f_ident), # This isn't what I expected: ! (0, 'exception', protect_ident), # I expected this again: ! # (1, 'exception', f_ident), ]) --- 117,124 ---- f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), # This isn't what I expected: ! # (0, 'exception', protect_ident), # I expected this again: ! (1, 'return', f_ident), ]) *************** *** 144,152 **** self.check_events(g, [(1, 'call', g_ident), (2, 'call', f_ident), ! (2, 'exception', f_ident), ! (1, 'exception', g_ident), (3, 'call', f_ident), ! (3, 'exception', f_ident), ! (1, 'exception', g_ident), (1, 'return', g_ident), ]) --- 136,142 ---- self.check_events(g, [(1, 'call', g_ident), (2, 'call', f_ident), ! (2, 'return', f_ident), (3, 'call', f_ident), ! (3, 'return', f_ident), (1, 'return', g_ident), ]) *************** *** 162,169 **** self.check_events(g, [(1, 'call', g_ident), (2, 'call', f_ident), ! (2, 'exception', f_ident), ! (1, 'exception', g_ident), (1, 'falling through', g_ident), ! (0, 'exception', protect_ident), ]) --- 152,158 ---- self.check_events(g, [(1, 'call', g_ident), (2, 'call', f_ident), ! (2, 'return', f_ident), (1, 'falling through', g_ident), ! (1, 'return', g_ident), ]) *************** *** 174,180 **** f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), ! (1, 'exception', f_ident), ! (1, 'exception', f_ident), ! (0, 'exception', protect_ident) ]) --- 163,167 ---- f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), ! (1, 'return', f_ident), ]) *************** *** 185,190 **** f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), ! (1, 'exception', f_ident), ! (0, 'exception', protect_ident) ]) --- 172,176 ---- f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), ! (1, 'return', f_ident), ]) *************** *** 194,199 **** f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), ! (1, 'exception', f_ident), ! (0, 'exception', protect_ident) ]) --- 180,184 ---- f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), ! (1, 'return', f_ident), ]) *************** *** 219,228 **** (4, 'call', g_ident), (5, 'call', f_ident), ! (5, 'exception', f_ident), ! (4, 'exception', g_ident), ! (3, 'exception', h_ident), ! (2, 'exception', i_ident), ! (1, 'exception', j_ident), ! (0, 'exception', protect_ident), ]) --- 204,212 ---- (4, 'call', g_ident), (5, 'call', f_ident), ! (5, 'return', f_ident), ! (4, 'return', g_ident), ! (3, 'return', h_ident), ! (2, 'return', i_ident), ! (1, 'return', j_ident), ]) *************** *** 267,271 **** # once more to hit the raise: (2, 'call', f_ident), ! (2, 'exception', f_ident), (1, 'return', g_ident), ]) --- 251,255 ---- # once more to hit the raise: (2, 'call', f_ident), ! (2, 'return', f_ident), (1, 'return', g_ident), ]) *************** *** 274,278 **** class ProfileSimulatorTestCase(TestCaseBase): def new_watcher(self): ! return ProfileSimulator() def test_simple(self): --- 258,262 ---- class ProfileSimulatorTestCase(TestCaseBase): def new_watcher(self): ! return ProfileSimulator(self) def test_simple(self): *************** *** 289,294 **** f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), ! (1, 'ignore', f_ident), ! (1, 'propogate-from', f_ident), ]) --- 273,277 ---- f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), ! (1, 'return', f_ident), ]) *************** *** 299,303 **** f_ident = ident(f) self.check_events(f, [(1, 'call', f_ident), - (1, 'ignore', f_ident), (1, 'return', f_ident), ]) --- 282,285 ---- *************** *** 324,333 **** (4, 'call', g_ident), (5, 'call', f_ident), ! (5, 'ignore', f_ident), ! (5, 'propogate-from', f_ident), ! (4, 'propogate-from', g_ident), ! (3, 'propogate-from', h_ident), ! (2, 'propogate-from', i_ident), ! (1, 'propogate-from', j_ident), ]) --- 306,314 ---- (4, 'call', g_ident), (5, 'call', f_ident), ! (5, 'return', f_ident), ! (4, 'return', g_ident), ! (3, 'return', h_ident), ! (2, 'return', i_ident), ! (1, 'return', j_ident), ]) From gward@users.sourceforge.net Thu Oct 4 15:52:08 2001 From: gward@users.sourceforge.net (Greg Ward) Date: Thu, 04 Oct 2001 07:52:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python import.c,2.186,2.187 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv29523/Python Modified Files: import.c Log Message: Remove a couple of unused local variables (bug #445960, compiler warnings on IRIX 6.5). Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.186 retrieving revision 2.187 diff -C2 -d -r2.186 -r2.187 *** import.c 2001/08/30 05:16:13 2.186 --- import.c 2001/10/04 14:52:06 2.187 *************** *** 867,871 **** int i, npath; size_t len, namelen; - struct _frozen *f; struct filedescr *fdp = NULL; FILE *fp = NULL; --- 867,870 ---- *************** *** 904,908 **** return &fd_builtin; } ! if ((f = find_frozen(name)) != NULL) { strcpy(buf, name); return &fd_frozen; --- 903,907 ---- return &fd_builtin; } ! if ((find_frozen(name)) != NULL) { strcpy(buf, name); return &fd_frozen; *************** *** 1389,1395 **** { struct _inittab *p; - PyObject *mod; ! if ((mod = _PyImport_FindExtension(name, name)) != NULL) return 1; --- 1388,1393 ---- { struct _inittab *p; ! if (_PyImport_FindExtension(name, name) != NULL) return 1; From gward@users.sourceforge.net Thu Oct 4 15:54:55 2001 From: gward@users.sourceforge.net (Greg Ward) Date: Thu, 04 Oct 2001 07:54:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules binascii.c,2.30,2.31 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv30040/Modules Modified Files: binascii.c Log Message: Add various typecasts (back and forth from char * to unsigned char *) to make the SGI C compiler happier (bug #445960). Index: binascii.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/binascii.c,v retrieving revision 2.30 retrieving revision 2.31 diff -C2 -d -r2.30 -r2.31 *** binascii.c 2001/09/30 20:32:11 2.30 --- binascii.c 2001/10/04 14:54:53 2.31 *************** *** 1014,1018 **** /* We allocate the output same size as input, this is overkill */ ! odata = (char *) calloc(1, datalen); if (odata == NULL) { --- 1014,1018 ---- /* We allocate the output same size as input, this is overkill */ ! odata = (unsigned char *) calloc(1, datalen); if (odata == NULL) { *************** *** 1066,1070 **** } } ! if ((rv = PyString_FromStringAndSize(odata, out)) == NULL) { free (odata); return NULL; --- 1066,1070 ---- } } ! if ((rv = PyString_FromStringAndSize((char *)odata, out)) == NULL) { free (odata); return NULL; *************** *** 1120,1124 **** * the end of lines to be the same depending on this detection * here */ ! p = strchr(data, '\n'); if ((p != NULL) && (p > data) && (*(p-1) == '\r')) crlf = 1; --- 1120,1124 ---- * the end of lines to be the same depending on this detection * here */ ! p = (unsigned char *) strchr((char *)data, '\n'); if ((p != NULL) && (p > data) && (*(p-1) == '\r')) crlf = 1; *************** *** 1184,1188 **** } ! odata = (char *) calloc(1, odatalen); if (odata == NULL) { --- 1184,1188 ---- } ! odata = (unsigned char *) calloc(1, odatalen); if (odata == NULL) { *************** *** 1257,1261 **** } } ! if ((rv = PyString_FromStringAndSize(odata, out)) == NULL) { free (odata); return NULL; --- 1257,1261 ---- } } ! if ((rv = PyString_FromStringAndSize((char *)odata, out)) == NULL) { free (odata); return NULL; From bwarsaw@users.sourceforge.net Thu Oct 4 17:27:07 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 04 Oct 2001 09:27:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib smtpd.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv25377 Modified Files: smtpd.py Log Message: Script arguments localhost:localport and remotehost:remoteport are now optional, and default to `localhost' and ports 8025 and 25 respectively. SMTPChannel.__init__(): Calculate __fqdn using socket.getfqdn() instead of gethostby*() and friends. This allows us to run this script even if we don't have access to dns (assuming the localhost is configured properly). Also, restore my precious page breaks. Hands off, oh Whitespace Normalizer! Index: smtpd.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/smtpd.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** smtpd.py 2001/08/13 21:18:01 1.7 --- smtpd.py 2001/10/04 16:27:04 1.8 *************** *** 2,6 **** """An RFC 2821 smtp proxy. ! Usage: %(program)s [options] localhost:port remotehost:port Options: --- 2,6 ---- """An RFC 2821 smtp proxy. ! Usage: %(program)s [options] [localhost:localport [remotehost:remoteport]] Options: *************** *** 31,36 **** --- 31,40 ---- Version: %(__version__)s + If localhost is not given then `localhost' is used, and if localport is not + given then 8025 is used. If remotehost is not given then `localhost' is used, + and if remoteport is not given, then 25 is used. """ + # Overview: # *************** *** 90,96 **** NEWLINE = '\n' EMPTYSTRING = '' ! def usage(code, msg=''): print >> sys.stderr, __doc__ % globals() --- 94,101 ---- NEWLINE = '\n' EMPTYSTRING = '' ! COMMASPACE = ', ' + def usage(code, msg=''): print >> sys.stderr, __doc__ % globals() *************** *** 100,104 **** ! class SMTPChannel(asynchat.async_chat): COMMAND = 0 --- 105,109 ---- ! class SMTPChannel(asynchat.async_chat): COMMAND = 0 *************** *** 116,121 **** self.__rcpttos = [] self.__data = '' ! self.__fqdn = socket.gethostbyaddr( ! socket.gethostbyname(socket.gethostname()))[0] self.__peer = conn.getpeername() print >> DEBUGSTREAM, 'Peer:', repr(self.__peer) --- 121,125 ---- self.__rcpttos = [] self.__data = '' ! self.__fqdn = socket.getfqdn() self.__peer = conn.getpeername() print >> DEBUGSTREAM, 'Peer:', repr(self.__peer) *************** *** 265,270 **** self.push('354 End data with .') - class SMTPServer(asyncore.dispatcher): def __init__(self, localaddr, remoteaddr): --- 269,274 ---- self.push('354 End data with .') + class SMTPServer(asyncore.dispatcher): def __init__(self, localaddr, remoteaddr): *************** *** 314,317 **** --- 318,322 ---- + class DebuggingServer(SMTPServer): # Do something with the gathered message *************** *** 328,333 **** print '------------ END MESSAGE ------------' - class PureProxy(SMTPServer): def process_message(self, peer, mailfrom, rcpttos, data): --- 333,338 ---- print '------------ END MESSAGE ------------' + class PureProxy(SMTPServer): def process_message(self, peer, mailfrom, rcpttos, data): *************** *** 369,374 **** return refused - class MailmanProxy(PureProxy): def process_message(self, peer, mailfrom, rcpttos, data): --- 374,379 ---- return refused + class MailmanProxy(PureProxy): def process_message(self, peer, mailfrom, rcpttos, data): *************** *** 449,453 **** ! class Options: setuid = 1 --- 454,458 ---- ! class Options: setuid = 1 *************** *** 455,458 **** --- 460,464 ---- + def parseargs(): global DEBUGSTREAM *************** *** 479,508 **** # parse the rest of the arguments ! try: localspec = args[0] ! remotespec = args[1] ! except IndexError: ! usage(1, 'Not enough arguments') # split into host/port pairs i = localspec.find(':') if i < 0: ! usage(1, 'Bad local spec: "%s"' % localspec) options.localhost = localspec[:i] try: options.localport = int(localspec[i+1:]) except ValueError: ! usage(1, 'Bad local port: "%s"' % localspec) i = remotespec.find(':') if i < 0: ! usage(1, 'Bad remote spec: "%s"' % remotespec) options.remotehost = remotespec[:i] try: options.remoteport = int(remotespec[i+1:]) except ValueError: ! usage(1, 'Bad remote port: "%s"' % remotespec) return options ! if __name__ == '__main__': options = parseargs() --- 485,518 ---- # parse the rest of the arguments ! if len(args) < 1: ! localspec = 'localhost:8025' ! remotespec = 'localhost:25' ! elif len(args) < 2: localspec = args[0] ! remotespec = 'localhost:25' ! else: ! usage(1, 'Invalid arguments: %s' % COMMASPACE.join(args)) ! # split into host/port pairs i = localspec.find(':') if i < 0: ! usage(1, 'Bad local spec: %s' % localspec) options.localhost = localspec[:i] try: options.localport = int(localspec[i+1:]) except ValueError: ! usage(1, 'Bad local port: %s' % localspec) i = remotespec.find(':') if i < 0: ! usage(1, 'Bad remote spec: %s' % remotespec) options.remotehost = remotespec[:i] try: options.remoteport = int(remotespec[i+1:]) except ValueError: ! usage(1, 'Bad remote port: %s' % remotespec) return options ! if __name__ == '__main__': options = parseargs() From gvanrossum@users.sourceforge.net Thu Oct 4 18:00:09 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 04 Oct 2001 10:00:09 -0700 Subject: [Python-checkins] CVS: python/dist/src README,1.126,1.127 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv5408 Modified Files: README Log Message: Add note about profiling. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/README,v retrieving revision 1.126 retrieving revision 1.127 diff -C2 -d -r1.126 -r1.127 *** README 2001/09/06 08:16:17 1.126 --- README 2001/10/04 17:00:07 1.127 *************** *** 560,563 **** --- 560,578 ---- + Profiling + --------- + + If you want C profiling turned on, the easiest way is to run configure + with the CC environment variable to the necessary compiler + invocation. For example, on Linux, this works for profiling using + gprof(1): + + CC="gcc -pg" ./configure + + Note that on Linux, gprof apparently does not work for shared + libraries. The Makefile/Setup mechanism can be used to compile and + link most extension module statically. + + Testing ------- From bwarsaw@users.sourceforge.net Thu Oct 4 18:05:13 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 04 Oct 2001 10:05:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email Encoders.py,1.3,1.4 Errors.py,1.2,1.3 Generator.py,1.3,1.4 Iterators.py,1.3,1.4 MIMEBase.py,1.3,1.4 MIMEImage.py,1.2,1.3 MIMEMessage.py,1.2,1.3 MIMEText.py,1.2,1.3 Message.py,1.3,1.4 Parser.py,1.3,1.4 Utils.py,1.2,1.3 __init__.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv6739 Modified Files: Encoders.py Errors.py Generator.py Iterators.py MIMEBase.py MIMEImage.py MIMEMessage.py MIMEText.py Message.py Parser.py Utils.py __init__.py Log Message: Give me back my page breaks. Index: Encoders.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Encoders.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Encoders.py 2001/10/04 05:36:56 1.3 --- Encoders.py 2001/10/04 17:05:11 1.4 *************** *** 9,13 **** ! # Helpers def _qencode(s): --- 9,13 ---- ! # Helpers def _qencode(s): *************** *** 26,31 **** return value - def encode_base64(msg): """Encode the message's payload in Base64. --- 26,31 ---- return value + def encode_base64(msg): """Encode the message's payload in Base64. *************** *** 38,43 **** msg['Content-Transfer-Encoding'] = 'base64' - def encode_quopri(msg): """Encode the message's payload in Quoted-Printable. --- 38,43 ---- msg['Content-Transfer-Encoding'] = 'base64' + def encode_quopri(msg): """Encode the message's payload in Quoted-Printable. *************** *** 50,55 **** msg['Content-Transfer-Encoding'] = 'quoted-printable' - def encode_7or8bit(msg): """Set the Content-Transfer-Encoding: header to 7bit or 8bit.""" --- 50,55 ---- msg['Content-Transfer-Encoding'] = 'quoted-printable' + def encode_7or8bit(msg): """Set the Content-Transfer-Encoding: header to 7bit or 8bit.""" *************** *** 65,69 **** ! def encode_noop(msg): """Do nothing.""" --- 65,69 ---- ! def encode_noop(msg): """Do nothing.""" Index: Errors.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Errors.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Errors.py 2001/10/04 05:36:56 1.2 --- Errors.py 2001/10/04 17:05:11 1.3 *************** *** 6,10 **** ! class MessageError(Exception): """Base class for errors in this module.""" --- 6,10 ---- ! class MessageError(Exception): """Base class for errors in this module.""" Index: Generator.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Generator.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Generator.py 2001/10/04 05:36:56 1.3 --- Generator.py 2001/10/04 17:05:11 1.4 *************** *** 26,30 **** ! class Generator: """Generates output from a Message object tree. --- 26,30 ---- ! class Generator: """Generates output from a Message object tree. *************** *** 278,283 **** self._fp.write(s.getvalue()) - class DecodedGenerator(Generator): """Generator a text representation of a message. --- 278,283 ---- self._fp.write(s.getvalue()) + class DecodedGenerator(Generator): """Generator a text representation of a message. *************** *** 334,339 **** } - # Helper def _make_boundary(self, text=None): --- 334,339 ---- } + # Helper def _make_boundary(self, text=None): Index: Iterators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Iterators.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Iterators.py 2001/10/04 05:36:56 1.3 --- Iterators.py 2001/10/04 17:05:11 1.4 *************** *** 10,14 **** ! def body_line_iterator(msg): """Iterate over the parts, returning string payloads line-by-line.""" --- 10,14 ---- ! def body_line_iterator(msg): """Iterate over the parts, returning string payloads line-by-line.""" *************** *** 20,24 **** ! def typed_subpart_iterator(msg, maintype='text', subtype=None): """Iterate over the subparts with a given MIME type. --- 20,24 ---- ! def typed_subpart_iterator(msg, maintype='text', subtype=None): """Iterate over the subparts with a given MIME type. Index: MIMEBase.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/MIMEBase.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** MIMEBase.py 2001/10/04 05:36:56 1.3 --- MIMEBase.py 2001/10/04 17:05:11 1.4 *************** *** 8,12 **** ! class MIMEBase(Message.Message): """Base class for MIME specializations.""" --- 8,12 ---- ! class MIMEBase(Message.Message): """Base class for MIME specializations.""" Index: MIMEImage.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/MIMEImage.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** MIMEImage.py 2001/10/04 05:36:56 1.2 --- MIMEImage.py 2001/10/04 17:05:11 1.3 *************** *** 13,17 **** ! class MIMEImage(MIMEBase.MIMEBase): """Class for generating image/* type MIME documents.""" --- 13,17 ---- ! class MIMEImage(MIMEBase.MIMEBase): """Class for generating image/* type MIME documents.""" Index: MIMEMessage.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/MIMEMessage.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** MIMEMessage.py 2001/10/04 05:36:56 1.2 --- MIMEMessage.py 2001/10/04 17:05:11 1.3 *************** *** 9,13 **** ! class MIMEMessage(MIMEBase.MIMEBase): """Class representing message/* MIME documents.""" --- 9,13 ---- ! class MIMEMessage(MIMEBase.MIMEBase): """Class representing message/* MIME documents.""" Index: MIMEText.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/MIMEText.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** MIMEText.py 2001/10/04 05:36:56 1.2 --- MIMEText.py 2001/10/04 17:05:11 1.3 *************** *** 9,13 **** ! class MIMEText(MIMEBase.MIMEBase): """Class for generating text/* type MIME documents.""" --- 9,13 ---- ! class MIMEText(MIMEBase.MIMEBase): """Class for generating text/* type MIME documents.""" Index: Message.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Message.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Message.py 2001/10/04 05:36:56 1.3 --- Message.py 2001/10/04 17:05:11 1.4 *************** *** 21,25 **** ! class Message: """Basic message object for use inside the object tree. --- 21,25 ---- ! class Message: """Basic message object for use inside the object tree. Index: Parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Parser.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Parser.py 2001/10/04 05:36:56 1.3 --- Parser.py 2001/10/04 17:05:11 1.4 *************** *** 15,19 **** ! class Parser: def __init__(self, _class=Message.Message): --- 15,19 ---- ! class Parser: def __init__(self, _class=Message.Message): Index: Utils.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Utils.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Utils.py 2001/10/04 05:36:56 1.2 --- Utils.py 2001/10/04 17:05:11 1.3 *************** *** 22,26 **** ! # Helpers --- 22,26 ---- ! # Helpers *************** *** 43,47 **** ! def getaddresses(fieldvalues): """Return a list of (REALNAME, EMAIL) for each fieldvalue.""" --- 43,47 ---- ! def getaddresses(fieldvalues): """Return a list of (REALNAME, EMAIL) for each fieldvalue.""" *************** *** 51,55 **** ! ecre = re.compile(r''' =\? # literal =? --- 51,55 ---- ! ecre = re.compile(r''' =\? # literal =? *************** *** 93,97 **** ! def encode(s, charset='iso-8859-1', encoding='q'): """Encode a string according to RFC 2047.""" --- 93,97 ---- ! def encode(s, charset='iso-8859-1', encoding='q'): """Encode a string according to RFC 2047.""" Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/__init__.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** __init__.py 2001/10/04 05:36:56 1.2 --- __init__.py 2001/10/04 17:05:11 1.3 *************** *** 23,27 **** ! # Some convenience routines from Parser import Parser as _Parser --- 23,27 ---- ! # Some convenience routines from Parser import Parser as _Parser From bwarsaw@users.sourceforge.net Thu Oct 4 18:58:52 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 04 Oct 2001 10:58:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_email.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21064 Modified Files: test_email.py Log Message: test_header_splitter(), test_body_line_iterator(): Move the test data into tests/data/msg_*.txt files. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_email.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_email.py 2001/10/04 06:26:17 1.4 --- test_email.py 2001/10/04 17:58:50 1.5 *************** *** 29,33 **** ! def openfile(filename): path = os.path.join(os.path.dirname(test.regrtest.__file__), --- 29,33 ---- ! def openfile(filename): path = os.path.join(os.path.dirname(test.regrtest.__file__), *************** *** 36,40 **** ! # Base test class class TestEmailBase(unittest.TestCase): --- 36,40 ---- ! # Base test class class TestEmailBase(unittest.TestCase): *************** *** 48,52 **** ! # Test various aspects of the Message class's API class TestMessageAPI(TestEmailBase): --- 48,52 ---- ! # Test various aspects of the Message class's API class TestMessageAPI(TestEmailBase): *************** *** 217,222 **** self.failIf(msg.has_key('headeri')) - # Test the email.Encoders module class TestEncoders(unittest.TestCase): --- 217,222 ---- self.failIf(msg.has_key('headeri')) + # Test the email.Encoders module class TestEncoders(unittest.TestCase): *************** *** 254,259 **** eq(msg['content-transfer-encoding'], 'quoted-printable') - class TestLongHeaders(unittest.TestCase): def test_header_splitter(self): --- 254,260 ---- eq(msg['content-transfer-encoding'], 'quoted-printable') + + # Test long header wrapping class TestLongHeaders(unittest.TestCase): def test_header_splitter(self): *************** *** 267,281 **** g = Generator(sfp) g(msg) ! self.assertEqual(sfp.getvalue(), '''\ ! Content-Type: text/plain; charset="us-ascii" ! MIME-Version: 1.0 ! Content-Transfer-Encoding: 7bit ! X-Foobar-Spoink-Defrobnit: wasnipoop; giraffes="very-long-necked-animals"; ! \tspooge="yummy"; hippos="gargantuan"; marshmallows="gooey" ! ! ''') ! class TestFromMangling(unittest.TestCase): def setUp(self): --- 268,276 ---- g = Generator(sfp) g(msg) ! self.assertEqual(sfp.getvalue(), openfile('msg_18.txt').read()) + + # Test mangling of "From " lines in the body of a message class TestFromMangling(unittest.TestCase): def setUp(self): *************** *** 310,314 **** ! # Test the basic MIMEImage class class TestMIMEImage(unittest.TestCase): --- 305,309 ---- ! # Test the basic MIMEImage class class TestMIMEImage(unittest.TestCase): *************** *** 362,367 **** header='foobar') is missing) - # Test the basic MIMEText class class TestMIMEText(unittest.TestCase): --- 357,362 ---- header='foobar') is missing) + # Test the basic MIMEText class class TestMIMEText(unittest.TestCase): *************** *** 383,388 **** self.failUnless(not self._msg.is_multipart()) - class TestMultipartMixed(unittest.TestCase): def setUp(self): --- 378,384 ---- self.failUnless(not self._msg.is_multipart()) + + # Test a more complicated multipart/mixed type message class TestMultipartMixed(unittest.TestCase): def setUp(self): *************** *** 446,450 **** ! class TestNonConformant(TestEmailBase): def test_parse_missing_minor_type(self): --- 442,447 ---- ! ! # Test some badly formatted messages class TestNonConformant(TestEmailBase): def test_parse_missing_minor_type(self): *************** *** 467,471 **** ! class TestRFC2047(unittest.TestCase): def test_iso_8859_1(self): --- 464,469 ---- ! ! # Test RFC 2047 header encoding and decoding class TestRFC2047(unittest.TestCase): def test_iso_8859_1(self): *************** *** 498,502 **** ! class TestMIMEMessage(TestEmailBase): def setUp(self): --- 496,501 ---- ! ! # Test the MIMEMessage class class TestMIMEMessage(TestEmailBase): def setUp(self): *************** *** 604,608 **** ! class TestIdempotent(unittest.TestCase): def _msgobj(self, filename): --- 603,612 ---- ! ! # A general test of parser->model->generator idempotency. IOW, read a message ! # in, parse it into a message object tree, then without touching the tree, ! # regenerate the plain text. The original text and the transformed text ! # should be identical. Note: that we ignore the Unix-From since that may ! # contain a changed date. class TestIdempotent(unittest.TestCase): def _msgobj(self, filename): *************** *** 703,708 **** eq(msg1.get_payload(), '\n') - class TestMiscellaneous(unittest.TestCase): def test_message_from_string(self): --- 707,713 ---- eq(msg1.get_payload(), '\n') + + # Test various other bits of the package's functionality class TestMiscellaneous(unittest.TestCase): def test_message_from_string(self): *************** *** 780,785 **** unless(isinstance(subpart, MyMessage)) - class TestIterators(TestEmailBase): def test_body_line_iterator(self): --- 785,791 ---- unless(isinstance(subpart, MyMessage)) + + # Test the iterator/generators class TestIterators(TestEmailBase): def test_body_line_iterator(self): *************** *** 800,848 **** lines.append(line) eq(len(lines), 43) ! eq(EMPTYSTRING.join(lines), """\ ! Send Ppp mailing list submissions to ! \tppp@zzz.org ! ! To subscribe or unsubscribe via the World Wide Web, visit ! \thttp://www.zzz.org/mailman/listinfo/ppp ! or, via email, send a message with subject or body 'help' to ! \tppp-request@zzz.org ! ! You can reach the person managing the list at ! \tppp-admin@zzz.org ! ! When replying, please edit your Subject line so it is more specific ! than "Re: Contents of Ppp digest..." ! ! Today's Topics: ! ! 1. testing #1 (Barry A. Warsaw) ! 2. testing #2 (Barry A. Warsaw) ! 3. testing #3 (Barry A. Warsaw) ! 4. testing #4 (Barry A. Warsaw) ! 5. testing #5 (Barry A. Warsaw) ! ! hello ! ! ! hello ! ! ! hello ! ! ! hello ! ! ! hello ! ! ! ! _______________________________________________ ! Ppp mailing list ! Ppp@zzz.org ! http://www.zzz.org/mailman/listinfo/ppp ! ! """) def test_typed_subpart_iterator(self): --- 806,810 ---- lines.append(line) eq(len(lines), 43) ! eq(EMPTYSTRING.join(lines), openfile('msg_19.txt').read()) def test_typed_subpart_iterator(self): *************** *** 863,868 **** """) - def suite(): suite = unittest.TestSuite() --- 825,830 ---- """) + def suite(): suite = unittest.TestSuite() *************** *** 882,887 **** return suite - if __name__ == '__main__': unittest.main(defaultTest='suite') --- 844,849 ---- return suite + if __name__ == '__main__': unittest.main(defaultTest='suite') From bwarsaw@users.sourceforge.net Thu Oct 4 18:59:44 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 04 Oct 2001 10:59:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/data msg_18.txt,NONE,1.1 msg_19.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/data In directory usw-pr-cvs1:/tmp/cvs-serv21182 Added Files: msg_18.txt msg_19.txt Log Message: More test data for test_email.py --- NEW FILE: msg_18.txt --- Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Foobar-Spoink-Defrobnit: wasnipoop; giraffes="very-long-necked-animals"; spooge="yummy"; hippos="gargantuan"; marshmallows="gooey" --- NEW FILE: msg_19.txt --- Send Ppp mailing list submissions to ppp@zzz.org To subscribe or unsubscribe via the World Wide Web, visit http://www.zzz.org/mailman/listinfo/ppp or, via email, send a message with subject or body 'help' to ppp-request@zzz.org You can reach the person managing the list at ppp-admin@zzz.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Ppp digest..." Today's Topics: 1. testing #1 (Barry A. Warsaw) 2. testing #2 (Barry A. Warsaw) 3. testing #3 (Barry A. Warsaw) 4. testing #4 (Barry A. Warsaw) 5. testing #5 (Barry A. Warsaw) hello hello hello hello hello _______________________________________________ Ppp mailing list Ppp@zzz.org http://www.zzz.org/mailman/listinfo/ppp From bwarsaw@users.sourceforge.net Thu Oct 4 19:18:39 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 04 Oct 2001 11:18:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_email.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv25762 Modified Files: test_email.py Log Message: TestIterators: Tim Peters suggests a more succinct spelling of "listify an iterator". Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_email.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_email.py 2001/10/04 17:58:50 1.5 --- test_email.py 2001/10/04 18:18:37 1.6 *************** *** 794,800 **** msg = self._msgobj('msg_01.txt') it = Iterators.body_line_iterator(msg) ! lines = [] ! for line in it: ! lines.append(line) eq(len(lines), 6) eq(EMPTYSTRING.join(lines), msg.get_payload()) --- 794,798 ---- msg = self._msgobj('msg_01.txt') it = Iterators.body_line_iterator(msg) ! lines = list(it) eq(len(lines), 6) eq(EMPTYSTRING.join(lines), msg.get_payload()) *************** *** 802,808 **** msg = self._msgobj('msg_02.txt') it = Iterators.body_line_iterator(msg) ! lines = [] ! for line in it: ! lines.append(line) eq(len(lines), 43) eq(EMPTYSTRING.join(lines), openfile('msg_19.txt').read()) --- 800,804 ---- msg = self._msgobj('msg_02.txt') it = Iterators.body_line_iterator(msg) ! lines = list(it) eq(len(lines), 43) eq(EMPTYSTRING.join(lines), openfile('msg_19.txt').read()) *************** *** 812,821 **** msg = self._msgobj('msg_04.txt') it = Iterators.typed_subpart_iterator(msg, 'text') ! lines = [] ! subparts = 0 ! for subpart in it: ! subparts += 1 ! lines.append(subpart.get_payload()) ! eq(subparts, 2) eq(EMPTYSTRING.join(lines), """\ a simple kind of mirror --- 808,813 ---- msg = self._msgobj('msg_04.txt') it = Iterators.typed_subpart_iterator(msg, 'text') ! lines = [subpart.get_payload() for subpart in it] ! eq(len(lines), 2) eq(EMPTYSTRING.join(lines), """\ a simple kind of mirror From fdrake@users.sourceforge.net Thu Oct 4 20:26:45 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 04 Oct 2001 12:26:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.280,2.281 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv8683/Python Modified Files: ceval.c Log Message: Fix bug in profiler modifications detected only in debug builds. The new profiler event stream includes a "return" event even when an exception is being propogated, but the machinery that called the profile hook did not save & restore the exception. In debug mode, the exception was detected during the execution of the profile callback, which did not have the proper internal flags set for the exception. Saving & restoring the exception state solves the problem. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.280 retrieving revision 2.281 diff -C2 -d -r2.280 -r2.281 *** ceval.c 2001/10/04 14:48:42 2.280 --- ceval.c 2001/10/04 19:26:43 2.281 *************** *** 49,52 **** --- 49,54 ---- static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *, int, PyObject *); + static void call_trace_protected(Py_tracefunc, PyObject *, + PyFrameObject *, int); static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *); static PyObject *loop_subscript(PyObject *, PyObject *); *************** *** 2298,2304 **** } if (tstate->c_profilefunc) { ! if (call_trace(tstate->c_profilefunc, ! tstate->c_profileobj, f, ! PyTrace_RETURN, retval)) { Py_XDECREF(retval); retval = NULL; --- 2300,2310 ---- } if (tstate->c_profilefunc) { ! if (why == WHY_EXCEPTION) ! call_trace_protected(tstate->c_profilefunc, ! tstate->c_profileobj, f, ! PyTrace_RETURN); ! else if (call_trace(tstate->c_profilefunc, ! tstate->c_profileobj, f, ! PyTrace_RETURN, retval)) { Py_XDECREF(retval); retval = NULL; *************** *** 2813,2816 **** --- 2819,2839 ---- err = call_trace(func, self, f, PyTrace_EXCEPTION, arg); Py_DECREF(arg); + if (err == 0) + PyErr_Restore(type, value, traceback); + else { + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(traceback); + } + } + + static void + call_trace_protected(Py_tracefunc func, PyObject *obj, PyFrameObject *frame, + int what) + { + PyObject *type, *value, *traceback; + int err; + PyErr_Fetch(&type, &value, &traceback); + err = call_trace(func, obj, frame, what, NULL); if (err == 0) PyErr_Restore(type, value, traceback); From tim_one@users.sourceforge.net Thu Oct 4 20:44:12 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 04 Oct 2001 12:44:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts reindent.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv12078/python/Tools/scripts Modified Files: reindent.py Log Message: Changed the reindenter to strip only trailing spaces and tabs from lines, not other control characters string.rstrip() got rid of. This caters to the \f thingies Barry likes putting in Python source files. Index: reindent.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/reindent.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** reindent.py 2000/10/05 03:48:38 1.1 --- reindent.py 2001/10/04 19:44:10 1.2 *************** *** 10,15 **** Change Python (.py) files to use 4-space indents and no hard tab characters. ! Also trim excess whitespace from ends of lines, and empty lines at the ends ! of files. Ensure the last line ends with a newline. Pass one or more file and/or directory paths. When a directory path, all --- 10,15 ---- Change Python (.py) files to use 4-space indents and no hard tab characters. ! Also trim excess spaces and tabs from ends of lines, and remove empty lines ! at the end of files. Also ensure the last line ends with a newline. Pass one or more file and/or directory paths. When a directory path, all *************** *** 109,112 **** --- 109,125 ---- print "unchanged." + def _rstrip(line, JUNK='\n \t'): + """Return line stripped of trailing spaces, tabs, newlines. + + Note that line.rstrip() instead also strips sundry control characters, + but at least one known Emacs user expects to keep junk like that, not + mentioning Barry by name or anything . + """ + + i = len(line) + while i > 0 and line[i-1] in JUNK: + i -= 1 + return line[:i] + class Reindenter: *************** *** 121,125 **** # that we can use tokenize's 1-based line numbering easily. # Note that a line is all-blank iff it's "\n". ! self.lines = [line.rstrip().expandtabs() + "\n" for line in self.raw] self.lines.insert(0, None) --- 134,138 ---- # that we can use tokenize's 1-based line numbering easily. # Note that a line is all-blank iff it's "\n". ! self.lines = [_rstrip(line).expandtabs() + "\n" for line in self.raw] self.lines.insert(0, None) From gvanrossum@users.sourceforge.net Thu Oct 4 20:46:08 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 04 Oct 2001 12:46:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.269,1.270 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv13410/Misc Modified Files: NEWS Log Message: Make new classes dynamic by default. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.269 retrieving revision 1.270 diff -C2 -d -r1.269 -r1.270 *** NEWS 2001/10/04 10:19:00 1.269 --- NEWS 2001/10/04 19:46:06 1.270 *************** *** 5,8 **** --- 5,18 ---- Type/class unification and new-style classes + - New-style classes are now dynamic by default. Previous, they were + static (meaning class attributes could not be assigned to) and + dynamic classes had to be requested by adding __dynamic__ = 1 to the + body of the class or to the module. Static classes are faster than + dynamic classes, but dynamic classes are now at most 50% slower than + static classes; previously, they could be up to 10x slower. (This + was accomplished by making dynamic classes faster, not by making + static classes slower. :-) Note that according to one benchmark, + static classes are about the same speed as classic classes. + - C.__doc__ now works as expected for new-style classes (in 2.2a4 it always returned None, even when there was a class docstring). From gvanrossum@users.sourceforge.net Thu Oct 4 20:46:08 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 04 Oct 2001 12:46:08 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv13410 Modified Files: PLAN.txt Log Message: Make new classes dynamic by default. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PLAN.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** PLAN.txt 2001/10/03 03:00:56 1.12 --- PLAN.txt 2001/10/04 19:46:06 1.13 *************** *** 5,23 **** ----------- ! Make __dynamic__ the default (this requires more performance work -- ! one particular test, test_descr.inherits(), is about 10x slower when ! __dynamic__ is 1. :-( There are two ways to go about the performance ! work: ! ! a) Add shortcuts to the slot_tp_XXX to recognize a PyWrapperDescr ! with the correct wrap_tp_XXX function. ! b) Add a list or dict of weak refs to derived classes to each dynamic class, and trap setattr+delattr on the base class so that they update the tp_XXX slot in each derived class when the base class __XXX__ gets set or deleted. More work, but more gain (zero waste ! in slot_tp_XXX when __XXX__ is not overridden). ! Add __del__ handlers. Allow assignment to __bases__ and __dict__? --- 5,20 ---- ----------- ! More performance work -- one particular test, test_descr.inherits(), ! is still about 50% slower with dynamic classes. :-( The approach of ! choice would be: ! Add a list of weak refs to derived classes to each dynamic class, and trap setattr+delattr on the base class so that they update the tp_XXX slot in each derived class when the base class __XXX__ gets set or deleted. More work, but more gain (zero waste ! in slot_tp_XXX when __XXX__ is not overridden). This is currently ! awaiting Fred turning the weak ref API into a standard object API. ! Add __del__ handlers? Allow assignment to __bases__ and __dict__? *************** *** 39,42 **** --- 36,42 ---- Done (mostly) ------------- + + Make __dynamic__ the default. *** done (but more performance work + needs to be done). *** Treat all binary operators the same way as I just did for rich From gvanrossum@users.sourceforge.net Thu Oct 4 20:46:08 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 04 Oct 2001 12:46:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.88,2.89 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv13410/Objects Modified Files: typeobject.c Log Message: Make new classes dynamic by default. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.88 retrieving revision 2.89 diff -C2 -d -r2.88 -r2.89 *** typeobject.c 2001/10/04 05:43:02 2.88 --- typeobject.c 2001/10/04 19:46:06 2.89 *************** *** 760,766 **** 2) in the module dict (globals) The first variable that is an int >= 0 is used. ! Otherwise, a default is calculated from the base classes: ! if any base class is dynamic, this class is dynamic; otherwise ! it is static. */ dynamic = -1; /* Not yet determined */ /* Look in the class */ --- 760,764 ---- 2) in the module dict (globals) The first variable that is an int >= 0 is used. ! Otherwise, the default is dynamic. */ dynamic = -1; /* Not yet determined */ /* Look in the class */ *************** *** 784,800 **** } if (dynamic < 0) { ! /* Make a new class dynamic if any of its bases is ! dynamic. This is not always the same as inheriting ! the __dynamic__ class attribute! */ ! dynamic = 0; ! for (i = 0; i < nbases; i++) { ! tmptype = (PyTypeObject *) ! PyTuple_GET_ITEM(bases, i); ! if (tmptype->tp_flags & ! Py_TPFLAGS_DYNAMICTYPE) { ! dynamic = 1; ! break; ! } ! } } --- 782,788 ---- } if (dynamic < 0) { ! /* Default to dynamic */ ! dynamic = 1; ! } From fdrake@users.sourceforge.net Thu Oct 4 20:46:09 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 04 Oct 2001 12:46:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_support.py,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv13493 Modified Files: test_support.py Log Message: run_suite(): If testclass is not available, provide an even more general error message. run_unittest(): Provide the testclass to run_suite() so it can construct the error message. This closes SF bug #467763. Index: test_support.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_support.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** test_support.py 2001/10/03 04:08:26 1.38 --- test_support.py 2001/10/04 19:46:07 1.39 *************** *** 149,153 **** ! def run_suite(suite): """Run tests from a unittest.TestSuite-derived class.""" if verbose: --- 149,153 ---- ! def run_suite(suite, testclass=None): """Run tests from a unittest.TestSuite-derived class.""" if verbose: *************** *** 163,168 **** err = result.failures[0][1] else: ! raise TestFailed("errors occurred in %s.%s" ! % (testclass.__module__, testclass.__name__)) raise TestFailed(err) --- 163,172 ---- err = result.failures[0][1] else: ! if testclass is None: ! msg = "errors occurred; run in verbose mode for details" ! else: ! msg = "errors occurred in %s.%s" \ ! % (testclass.__module__, testclass.__name__) ! raise TestFailed(msg) raise TestFailed(err) *************** *** 170,174 **** def run_unittest(testclass): """Run tests from a unittest.TestCase-derived class.""" ! run_suite(unittest.makeSuite(testclass)) --- 174,178 ---- def run_unittest(testclass): """Run tests from a unittest.TestCase-derived class.""" ! run_suite(unittest.makeSuite(testclass), testclass) From gvanrossum@users.sourceforge.net Thu Oct 4 20:58:48 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 04 Oct 2001 12:58:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib ConfigParser.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv15959 Modified Files: ConfigParser.py Log Message: Apply modified SF patch 467580: ConfigParser.getboolean(): FALSE, TRUE. This patch allows ConfigParser.getboolean() to interpret TRUE, FALSE, YES, NO, ON and OFF instead just '0' and '1'. While just allowing '0' and '1' sounds more correct users often demand to use more descriptive directives in configuration files. Instead of forcing every programmer do brew his own solution a system should include the batteries for this. [My modification to the patch is a slight rewording of the docstring and use of lowercase instead of uppercase templates. The code is still case sensitive. GvR.] Index: ConfigParser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ConfigParser.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** ConfigParser.py 2001/08/17 18:39:24 1.36 --- ConfigParser.py 2001/10/04 19:58:46 1.37 *************** *** 67,72 **** getboolean(section, options) ! like get(), but convert value to a boolean (currently defined as 0 or ! 1, only) remove_section(section) --- 67,73 ---- getboolean(section, options) ! like get(), but convert value to a boolean (currently case ! insensitively defined as 0, false, no, off for 0, and 1, true, ! yes, on for 1). Returns 0 or 1. remove_section(section) *************** *** 307,315 **** def getboolean(self, section, option): ! v = self.get(section, option) ! val = int(v) ! if val not in (0, 1): raise ValueError, 'Not a boolean: %s' % v ! return val def optionxform(self, optionstr): --- 308,317 ---- def getboolean(self, section, option): ! states = {'1': 1, 'yes': 1, 'true': 1, 'on': 1, ! '0': 0, 'no': 0, 'false': 0, 'off': 0} ! v = self.get(section, option) ! if not states.has_key(v.lower()): raise ValueError, 'Not a boolean: %s' % v ! return states[v.lower()] def optionxform(self, optionstr): From fdrake@users.sourceforge.net Thu Oct 4 21:05:12 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 04 Oct 2001 13:05:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_htmllib.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv18328 Added Files: test_htmllib.py Log Message: Non-failing test for SF bug #467059. --- NEW FILE: test_htmllib.py --- import formatter import htmllib import unittest import test_support class AnchorCollector(htmllib.HTMLParser): def __init__(self, *args, **kw): self.__anchors = [] htmllib.HTMLParser.__init__(self, *args, **kw) def get_anchor_info(self): return self.__anchors def anchor_bgn(self, *args): self.__anchors.append(args) class HTMLParserTestCase(unittest.TestCase): def test_anchor_collection(self): # See SF bug #467059. parser = AnchorCollector(formatter.NullFormatter(), verbose=1) parser.feed( """ """) parser.close() self.assertEquals(parser.get_anchor_info(), [('http://foo.org/', 'splat', ''), ('http://www.python.org/', '', ''), ('', 'frob', ''), ]) def test_main(): test_support.run_unittest(HTMLParserTestCase) if __name__ == "__main__": test_main() From fdrake@users.sourceforge.net Thu Oct 4 21:40:09 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 04 Oct 2001 13:40:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libresource.tex,1.14,1.15 librestricted.tex,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv27082/lib Modified Files: libresource.tex librestricted.tex Log Message: Update a couple of old addresses that point to CNRI. Index: libresource.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libresource.tex,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** libresource.tex 2001/07/14 02:50:55 1.14 --- libresource.tex 2001/10/04 20:40:07 1.15 *************** *** 6,11 **** \modulesynopsis{An interface to provide resource usage information on the current process.} ! \moduleauthor{Jeremy Hylton}{jhylton@cnri.reston.va.us} ! \sectionauthor{Jeremy Hylton}{jhylton@cnri.reston.va.us} --- 6,11 ---- \modulesynopsis{An interface to provide resource usage information on the current process.} ! \moduleauthor{Jeremy Hylton}{jeremy@alum.mit.edu} ! \sectionauthor{Jeremy Hylton}{jeremy@alum.mit.edu} Index: librestricted.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/librestricted.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** librestricted.tex 2001/07/14 02:50:55 1.7 --- librestricted.tex 2001/10/04 20:40:07 1.8 *************** *** 67,76 **** \begin{seealso} ! \seetext{Andrew Kuchling, ``Restricted Execution HOWTO.'' Available ! online at \url{http://www.python.org/doc/howto/rexec/}.} ! ! \seetext{Grail, an Internet browser written in Python, is available ! at \url{http://grail.cnri.reston.va.us/grail/}. More ! information on the use of Python's restricted execution ! mode in Grail is available on the Web site.} \end{seealso} --- 67,78 ---- \begin{seealso} ! \seetitle[http://www.python.org/doc/howto/rexec/] ! {Restricted Execution HOWTO} ! {Andrew Kuchling's tutorial on the use of the restricted ! execution facilities in Python.} ! \seetitle[http://grail.sourceforge.net/]{Grail Home Page} ! {Grail, an Internet browser written in Python, uses these ! modules to support Python applets. More ! information on the use of Python's restricted execution ! mode in Grail is available on the Web site.} \end{seealso} From loewis@users.sourceforge.net Thu Oct 4 23:44:28 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 04 Oct 2001 15:44:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libos.tex,1.65,1.66 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv23175/Doc/lib Modified Files: libos.tex Log Message: Add chroot call. Implements feature #459267. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.65 retrieving revision 1.66 diff -C2 -d -r1.65 -r1.66 *** libos.tex 2001/09/28 16:14:18 1.65 --- libos.tex 2001/10/04 22:44:26 1.66 *************** *** 578,581 **** --- 578,587 ---- \end{funcdesc} + \begin{funcdesc}{chroot}{path} + Change the root directory of the current process to \var{path}. + Availability: \UNIX{}. + \versionadded{2.2} + \end{funcdesc} + \begin{funcdesc}{chmod}{path, mode} Change the mode of \var{path} to the numeric \var{mode}. From loewis@users.sourceforge.net Thu Oct 4 23:44:28 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 04 Oct 2001 15:44:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.199,2.200 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv23175/Modules Modified Files: posixmodule.c Log Message: Add chroot call. Implements feature #459267. Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.199 retrieving revision 2.200 diff -C2 -d -r2.199 -r2.200 *** posixmodule.c 2001/09/06 00:32:15 2.199 --- posixmodule.c 2001/10/04 22:44:26 2.200 *************** *** 725,728 **** --- 725,740 ---- + #ifdef HAVE_CHROOT + static char posix_chroot__doc__[] = + "chroot(path) -> None\n\ + Change root directory to path."; + + static PyObject * + posix_chroot(PyObject *self, PyObject *args) + { + return posix_1str(args, "et:chroot", chroot); + } + #endif + #ifdef HAVE_FSYNC static char posix_fsync__doc__[] = *************** *** 5337,5340 **** --- 5349,5355 ---- {"chown", posix_chown, METH_VARARGS, posix_chown__doc__}, #endif /* HAVE_CHOWN */ + #ifdef HAVE_CHROOT + {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__}, + #endif #ifdef HAVE_CTERMID {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__}, From loewis@users.sourceforge.net Thu Oct 4 23:44:28 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 04 Oct 2001 15:44:28 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.254,1.255 configure.in,1.262,1.263 pyconfig.h.in,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv23175 Modified Files: configure configure.in pyconfig.h.in Log Message: Add chroot call. Implements feature #459267. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.254 retrieving revision 1.255 diff -C2 -d -r1.254 -r1.255 *** configure 2001/09/30 21:09:58 1.254 --- configure 2001/10/04 22:44:25 1.255 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.261 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.262 # Guess values for system-dependent variables and create Makefiles. *************** *** 4684,4688 **** # checks for library functions ! for ac_func in alarm chown clock confstr ctermid ctermid_r execv \ flock fork fsync fdatasync fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getpeername getpid getpwent getwd \ --- 4684,4688 ---- # checks for library functions ! for ac_func in alarm chown chroot clock confstr ctermid ctermid_r execv \ flock fork fsync fdatasync fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getpeername getpid getpwent getwd \ Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.262 retrieving revision 1.263 diff -C2 -d -r1.262 -r1.263 *** configure.in 2001/09/30 21:09:58 1.262 --- configure.in 2001/10/04 22:44:26 1.263 *************** *** 1317,1321 **** # checks for library functions ! AC_CHECK_FUNCS(alarm chown clock confstr ctermid ctermid_r execv \ flock fork fsync fdatasync fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getpeername getpid getpwent getwd \ --- 1317,1321 ---- # checks for library functions ! AC_CHECK_FUNCS(alarm chown chroot clock confstr ctermid ctermid_r execv \ flock fork fsync fdatasync fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getpeername getpid getpwent getwd \ Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** pyconfig.h.in 2001/09/30 21:09:58 1.12 --- pyconfig.h.in 2001/10/04 22:44:26 1.13 *************** *** 322,325 **** --- 322,328 ---- #undef HAVE_CHOWN + /* Define if you have the chroot function. */ + #undef HAVE_CHROOT + /* Define if you have the clock function. */ #undef HAVE_CLOCK From loewis@users.sourceforge.net Thu Oct 4 23:46:43 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 04 Oct 2001 15:46:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.270,1.271 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv23740/Misc Modified Files: NEWS Log Message: Document addition of chroot. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.270 retrieving revision 1.271 diff -C2 -d -r1.270 -r1.271 *** NEWS 2001/10/04 19:46:06 1.270 --- NEWS 2001/10/04 22:46:41 1.271 *************** *** 27,30 **** --- 27,32 ---- - readline now supports setting the startup_hook and the pre_event_hook. + - posix supports chroot where available. + Library From akuchling@users.sourceforge.net Fri Oct 5 13:24:18 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Fri, 05 Oct 2001 05:24:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules threadmodule.c,2.41,2.42 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv7284 Modified Files: threadmodule.c Log Message: Fix typo in docstring Index: threadmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/threadmodule.c,v retrieving revision 2.41 retrieving revision 2.42 diff -C2 -d -r2.41 -r2.42 *** threadmodule.c 2001/01/23 01:47:18 2.41 --- threadmodule.c 2001/10/05 12:24:15 2.42 *************** *** 256,260 **** static char start_new_doc[] = ! "start_new_thread(functon, args[, kwargs])\n\ (start_new() is an obsolete synonym)\n\ \n\ --- 256,260 ---- static char start_new_doc[] = ! "start_new_thread(function, args[, kwargs])\n\ (start_new() is an obsolete synonym)\n\ \n\ From gvanrossum@users.sourceforge.net Fri Oct 5 15:06:29 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 05 Oct 2001 07:06:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.115,1.116 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv22660 Modified Files: ACKS Log Message: Another contributor. Give Fred his Jr. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.115 retrieving revision 1.116 diff -C2 -d -r1.115 -r1.116 *** ACKS 2001/10/01 17:58:40 1.115 --- ACKS 2001/10/05 14:06:27 1.116 *************** *** 103,107 **** Walter Dörwald Jaromir Dolecek ! Fred Drake John DuBois Paul Dubois --- 103,107 ---- Walter Dörwald Jaromir Dolecek ! Fred Drake, Jr. John DuBois Paul Dubois *************** *** 414,417 **** --- 414,418 ---- Stephen Turner Bill Tutt + Doobee R. Tzeck Lionel Ulmer Jaap Vermeulen From fdrake@users.sourceforge.net Fri Oct 5 15:12:26 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 07:12:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.116,1.117 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv26047/Misc Modified Files: ACKS Log Message: Frankly, I'd like my "L." as well! Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.116 retrieving revision 1.117 diff -C2 -d -r1.116 -r1.117 *** ACKS 2001/10/05 14:06:27 1.116 --- ACKS 2001/10/05 14:12:23 1.117 *************** *** 103,107 **** Walter Dörwald Jaromir Dolecek ! Fred Drake, Jr. John DuBois Paul Dubois --- 103,107 ---- Walter Dörwald Jaromir Dolecek ! Fred L. Drake, Jr. John DuBois Paul Dubois From fdrake@users.sourceforge.net Fri Oct 5 17:45:55 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 09:45:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/mac mac.tex,1.8,1.9 libmacconsole.tex,1.13,NONE libmacdnr.tex,1.12,NONE libmactcp.tex,1.15,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Doc/mac In directory usw-pr-cvs1:/tmp/cvs-serv19884 Modified Files: mac.tex Removed Files: libmacconsole.tex libmacdnr.tex libmactcp.tex Log Message: Remove some long-unsupported Mac OS modules. This closes SF patch #460737. Index: mac.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/mac/mac.tex,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** mac.tex 2001/06/20 21:37:34 1.8 --- mac.tex 2001/10/05 16:45:53 1.9 *************** *** 53,63 **** \input{libmac} \input{libctb} - %\input{libmacconsole} - \input{libmacdnr} \input{libmacfs} \input{libmacic} \input{libmacos} \input{libmacostools} - \input{libmactcp} \input{libmacspeech} \input{libmacui} --- 53,60 ---- --- libmacconsole.tex DELETED --- --- libmacdnr.tex DELETED --- --- libmactcp.tex DELETED --- From fdrake@users.sourceforge.net Fri Oct 5 17:49:37 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 09:49:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile.deps,1.75,1.76 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv21367 Modified Files: Makefile.deps Log Message: Remove some long-unsupported Mac OS modules. This closes SF patch #460737. Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.75 retrieving revision 1.76 diff -C2 -d -r1.75 -r1.76 *** Makefile.deps 2001/09/28 22:02:49 1.75 --- Makefile.deps 2001/10/05 16:49:31 1.76 *************** *** 294,302 **** mac/libaetypes.tex \ mac/libctb.tex \ - mac/libmacdnr.tex \ mac/libmacfs.tex \ mac/libmacos.tex \ mac/libmacostools.tex \ - mac/libmactcp.tex \ mac/libmacspeech.tex \ mac/libmacui.tex \ --- 294,300 ---- From gvanrossum@users.sourceforge.net Fri Oct 5 18:04:44 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 05 Oct 2001 10:04:44 -0700 Subject: [Python-checkins] CVS: python/dist/src README,1.127,1.128 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv27776 Modified Files: README Log Message: Remove false statement about running make in the Modules directory. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/README,v retrieving revision 1.127 retrieving revision 1.128 diff -C2 -d -r1.127 -r1.128 *** README 2001/10/04 17:00:07 1.127 --- README 2001/10/05 17:04:42 1.128 *************** *** 520,526 **** the file for information on what kind of edits are allowed. When you have edited Setup in the Modules directory, the interpreter will ! automatically be rebuilt the next time you run make in the toplevel ! directory. (When working inside the Modules directory, use "make ! Makefile; make".) Many useful modules can be built on any Unix system, but some optional --- 520,525 ---- the file for information on what kind of edits are allowed. When you have edited Setup in the Modules directory, the interpreter will ! automatically be rebuilt the next time you run make (in the toplevel ! directory). Many useful modules can be built on any Unix system, but some optional From bwarsaw@users.sourceforge.net Fri Oct 5 18:10:33 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 05 Oct 2001 10:10:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib smtpd.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv30165 Modified Files: smtpd.py Log Message: SMTPServer.__init__(): Print the start information on the DEBUGSTREAM so that it can be suppressed. Index: smtpd.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/smtpd.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** smtpd.py 2001/10/04 16:27:04 1.8 --- smtpd.py 2001/10/05 17:10:31 1.9 *************** *** 283,287 **** self.bind(localaddr) self.listen(5) ! print '%s started at %s\n\tLocal addr: %s\n\tRemote addr:%s' % ( self.__class__.__name__, time.ctime(time.time()), localaddr, remoteaddr) --- 283,288 ---- self.bind(localaddr) self.listen(5) ! print >> DEBUGSTREAM, \ ! '%s started at %s\n\tLocal addr: %s\n\tRemote addr:%s' % ( self.__class__.__name__, time.ctime(time.time()), localaddr, remoteaddr) From tim_one@users.sourceforge.net Fri Oct 5 21:06:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 05 Oct 2001 13:06:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libre.tex,1.67,1.68 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv12191/python/Doc/lib Modified Files: libre.tex Log Message: A regexp example was rendered as foo\d when it was clearly intended to render as foo$ Fred, is this a right way to fix it? If not, the earlier place in the same paragraph that does render as foo$ is also wrong. Index: libre.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libre.tex,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -d -r1.67 -r1.68 *** libre.tex 2001/08/28 12:50:03 1.67 --- libre.tex 2001/10/05 20:06:47 1.68 *************** *** 102,106 **** also matches before a newline. \regexp{foo} matches both 'foo' and 'foobar', while the regular expression \regexp{foo\$} matches only ! 'foo'. More interestingly, searching for \regexp{foo\e d} in 'foo1\textbackslash nfoo2\textbackslash n' matches 'foo2' normally, but 'foo1' in \constant{MULTILINE} mode. --- 102,106 ---- also matches before a newline. \regexp{foo} matches both 'foo' and 'foobar', while the regular expression \regexp{foo\$} matches only ! 'foo'. More interestingly, searching for \regexp{foo\$} in 'foo1\textbackslash nfoo2\textbackslash n' matches 'foo2' normally, but 'foo1' in \constant{MULTILINE} mode. From tim_one@users.sourceforge.net Fri Oct 5 21:21:06 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 05 Oct 2001 13:21:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.281,2.282 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv19085/python/Python Modified Files: ceval.c Log Message: Get rid of unique local ISSTRICTINT macro in favor of std PyInt_CheckExact. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.281 retrieving revision 2.282 diff -C2 -d -r2.281 -r2.282 *** ceval.c 2001/10/04 19:26:43 2.281 --- ceval.c 2001/10/05 20:21:03 2.282 *************** *** 550,556 **** #endif - /* Strict int check macros */ - #define ISSTRICTINT(v) ((v)->ob_type == &PyInt_Type) - /* Local variable macros */ --- 550,553 ---- *************** *** 947,951 **** w = POP(); v = POP(); ! if (ISSTRICTINT(v) && ISSTRICTINT(w)) { /* INLINE: int + int */ register long a, b, i; --- 944,948 ---- w = POP(); v = POP(); ! if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { /* INLINE: int + int */ register long a, b, i; *************** *** 970,974 **** w = POP(); v = POP(); ! if (ISSTRICTINT(v) && ISSTRICTINT(w)) { /* INLINE: int - int */ register long a, b, i; --- 967,971 ---- w = POP(); v = POP(); ! if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { /* INLINE: int - int */ register long a, b, i; *************** *** 993,997 **** w = POP(); v = POP(); ! if (v->ob_type == &PyList_Type && ISSTRICTINT(w)) { /* INLINE: list[int] */ long i = PyInt_AsLong(w); --- 990,994 ---- w = POP(); v = POP(); ! if (v->ob_type == &PyList_Type && PyInt_CheckExact(w)) { /* INLINE: list[int] */ long i = PyInt_AsLong(w); *************** *** 1130,1134 **** w = POP(); v = POP(); ! if (ISSTRICTINT(v) && ISSTRICTINT(w)) { /* INLINE: int + int */ register long a, b, i; --- 1127,1131 ---- w = POP(); v = POP(); ! if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { /* INLINE: int + int */ register long a, b, i; *************** *** 1153,1157 **** w = POP(); v = POP(); ! if (ISSTRICTINT(v) && ISSTRICTINT(w)) { /* INLINE: int - int */ register long a, b, i; --- 1150,1154 ---- w = POP(); v = POP(); ! if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { /* INLINE: int - int */ register long a, b, i; *************** *** 1760,1764 **** w = POP(); v = POP(); ! if (ISSTRICTINT(v) && ISSTRICTINT(w)) { /* INLINE: cmp(int, int) */ register long a, b; --- 1757,1761 ---- w = POP(); v = POP(); ! if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) { /* INLINE: cmp(int, int) */ register long a, b; From theller@users.sourceforge.net Fri Oct 5 21:38:13 2001 From: theller@users.sourceforge.net (Thomas Heller) Date: Fri, 05 Oct 2001 13:38:13 -0700 Subject: [Python-checkins] CVS: distutils/misc install.c,1.12,1.13 install.rc,1.6,1.7 resource.h,1.5,1.6 wininst.dsp,1.3,1.4 wininst.exe,1.10,1.11 Message-ID: Update of /cvsroot/python/distutils/misc In directory usw-pr-cvs1:/tmp/cvs-serv25279 Modified Files: install.c install.rc resource.h wininst.dsp wininst.exe Log Message: Reorganized the code which determines the install-scheme (sys.prefix os sys.prefix\lib\site-packages). Display a message if no usable Python versions are found instead of leaving the poor user staring at an empty listbox to select something from ;-) Additional text-field displaying the installation directory. (Code to browse for and use other Python versions except those found in the registry is commented out, because it is not yet complete.) Index: install.c =================================================================== RCS file: /cvsroot/python/distutils/misc/install.c,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** install.c 2001/09/05 12:55:53 1.12 --- install.c 2001/10/05 20:38:11 1.13 *************** *** 49,53 **** /* * To Do: ! * - install a help-button, which will display the above * text to the user * - should there be a possibility to display a README file --- 49,62 ---- /* * To Do: ! * ! * display some explanation when no python version is found ! * instead showing the user an empty listbox to select something from. ! * ! * Finish the code so that we can use other python installations ! * additionaly to those found in the registry, ! * and then #define USE_OTHER_PYTHON_VERSIONS ! * ! * - install a help-button, which will display something meaningful ! * to the poor user. * text to the user * - should there be a possibility to display a README file *************** *** 60,63 **** --- 69,73 ---- #include #include + #include #include "resource.h" *************** *** 98,102 **** DWORD arc_size; /* number of bytes in archive */ int exe_size; /* number of bytes for exe-file portion */ ! char install_dir[MAX_PATH]; char pythondll[MAX_PATH]; BOOL pyc_compile, pyo_compile; --- 108,112 ---- DWORD arc_size; /* number of bytes in archive */ int exe_size; /* number of bytes for exe-file portion */ ! char python_dir[MAX_PATH]; char pythondll[MAX_PATH]; BOOL pyc_compile, pyo_compile; *************** *** 118,121 **** --- 128,151 ---- static BOOL notify (int code, char *fmt, ...); + /* Note: If scheme.prefix is nonempty, it must end with a '\'! */ + /* Note: purelib must be the FIRST entry! */ + SCHEME old_scheme[] = { + { "PURELIB", "" }, + { "PLATLIB", "" }, + { "HEADERS", "" }, /* 'Include/dist_name' part already in archive */ + { "SCRIPTS", "Scripts\\" }, + { "DATA", "" }, + { NULL, NULL }, + }; + + SCHEME new_scheme[] = { + { "PURELIB", "Lib\\site-packages\\" }, + { "PLATLIB", "Lib\\site-packages\\" }, + { "HEADERS", "" }, /* 'Include/dist_name' part already in archive */ + { "SCRIPTS", "Scripts\\" }, + { "DATA", "" }, + { NULL, NULL }, + }; + static void unescape (char *dst, char *src, unsigned size) { *************** *** 221,224 **** --- 251,256 ---- void (__cdecl * Py_Finalize)(void); int (__cdecl * PyRun_SimpleString)(char *); + void* (__cdecl * PySys_GetObject)(char *); + int *Py_OptimizeFlag; int errors = 0; *************** *** 247,250 **** --- 279,285 ---- "Py_OptimizeFlag"); + PySys_GetObject = (void* (*)(char *))GetProcAddress + (hPython,"PySys_GetObject"); + *Py_OptimizeFlag = optimize_flag; Py_SetProgramName(modulename); *************** *** 610,614 **** --- 645,837 ---- } + #ifdef USE_OTHER_PYTHON_VERSIONS + /* These are really private variables used to communicate + * between StatusRoutine and CheckPythonExe + */ + char bound_image_dll[_MAX_PATH]; + int bound_image_major; + int bound_image_minor; + + static BOOL __stdcall StatusRoutine(IMAGEHLP_STATUS_REASON reason, + PSTR ImageName, + PSTR DllName, + ULONG Va, + ULONG Parameter) + { + char fname[_MAX_PATH]; + int int_version; + + switch(reason) { + case BindOutOfMemory: + case BindRvaToVaFailed: + case BindNoRoomInImage: + case BindImportProcedureFailed: + break; + + case BindImportProcedure: + case BindForwarder: + case BindForwarderNOT: + case BindImageModified: + case BindExpandFileHeaders: + case BindImageComplete: + case BindSymbolsNotUpdated: + case BindMismatchedSymbols: + case BindImportModuleFailed: + break; + + case BindImportModule: + if (1 == sscanf(DllName, "python%d", &int_version)) { + SearchPath(NULL, DllName, NULL, sizeof(fname), fname, NULL); + strcpy(bound_image_dll, fname); + bound_image_major = int_version / 10; + bound_image_minor = int_version % 10; + OutputDebugString("BOUND "); + OutputDebugString(fname); + OutputDebugString("\n"); + } + break; + } + return TRUE; + } + /* + */ + static LPSTR get_sys_prefix (LPSTR exe, LPSTR dll) + { + void (__cdecl * Py_Initialize)(void); + void (__cdecl * Py_SetProgramName)(char *); + void (__cdecl * Py_Finalize)(void); + void* (__cdecl * PySys_GetObject)(char *); + void (__cdecl * PySys_SetArgv)(int, char **); + char* (__cdecl * Py_GetPrefix)(void); + char* (__cdecl * Py_GetPath)(void); + HINSTANCE hPython; + LPSTR prefix = NULL; + int (__cdecl * PyRun_SimpleString)(char *); + + { + char Buffer[256]; + wsprintf(Buffer, "PYTHONHOME=%s", exe); + *strrchr(Buffer, '\\') = '\0'; + // MessageBox(GetFocus(), Buffer, "PYTHONHOME", MB_OK); + _putenv(Buffer); + _putenv("PYTHONPATH="); + } + + hPython = LoadLibrary (dll); + if (!hPython) + return NULL; + Py_Initialize = (void (*)(void))GetProcAddress + (hPython,"Py_Initialize"); + + PySys_SetArgv = (void (*)(int, char **))GetProcAddress + (hPython,"PySys_SetArgv"); + + PyRun_SimpleString = (int (*)(char *))GetProcAddress + (hPython,"PyRun_SimpleString"); + + Py_SetProgramName = (void (*)(char *))GetProcAddress + (hPython,"Py_SetProgramName"); + + PySys_GetObject = (void* (*)(char *))GetProcAddress + (hPython,"PySys_GetObject"); + + Py_GetPrefix = (char * (*)(void))GetProcAddress + (hPython,"Py_GetPrefix"); + + Py_GetPath = (char * (*)(void))GetProcAddress + (hPython,"Py_GetPath"); + + Py_Finalize = (void (*)(void))GetProcAddress (hPython, + "Py_Finalize"); + Py_SetProgramName(exe); + Py_Initialize (); + PySys_SetArgv(1, &exe); + + MessageBox(GetFocus(), Py_GetPrefix(), "PREFIX", MB_OK); + MessageBox(GetFocus(), Py_GetPath(), "PATH", MB_OK); + + Py_Finalize (); + FreeLibrary (hPython); + + return prefix; + } + + static BOOL CheckPythonExe(LPSTR pathname, LPSTR version, int *pmajor, int *pminor) + { + bound_image_dll[0] = '\0'; + if (!BindImageEx(BIND_NO_BOUND_IMPORTS | BIND_NO_UPDATE | BIND_ALL_IMAGES, + pathname, + NULL, + NULL, + StatusRoutine)) + return SystemError(0, "Could not bind image"); + if (bound_image_dll[0] == '\0') + return SystemError(0, "Does not seem to be a python executable"); + *pmajor = bound_image_major; + *pminor = bound_image_minor; + if (version && *version) { + char core_version[12]; + wsprintf(core_version, "%d.%d", bound_image_major, bound_image_minor); + if (strcmp (version, core_version)) + return SystemError(0, "Wrong Python version"); + } + get_sys_prefix(pathname, bound_image_dll); + return TRUE; + } + + /* + * Browse for other python versions. Insert it into the listbox specified + * by hwnd. version, if not NULL or empty, is the version required. + */ + static BOOL GetOtherPythonVersion(HWND hwnd, LPSTR version) + { + char vers_name[_MAX_PATH + 80]; + DWORD itemindex; + OPENFILENAME of; + char pathname[_MAX_PATH]; + DWORD result; + + strcpy(pathname, "python.exe"); + + memset(&of, 0, sizeof(of)); + of.lStructSize = sizeof(OPENFILENAME); + of.hwndOwner = GetParent(hwnd); + of.hInstance = NULL; + of.lpstrFilter = "python.exe\0python.exe\0"; + of.lpstrCustomFilter = NULL; + of.nMaxCustFilter = 0; + of.nFilterIndex = 1; + of.lpstrFile = pathname; + of.nMaxFile = sizeof(pathname); + of.lpstrFileTitle = NULL; + of.nMaxFileTitle = 0; + of.lpstrInitialDir = NULL; + of.lpstrTitle = "Python executable"; + of.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; + of.lpstrDefExt = "exe"; + + result = GetOpenFileName(&of); + if (result) { + int major, minor; + if (!CheckPythonExe(pathname, version, &major, &minor)) { + return FALSE; + } + *strrchr(pathname, '\\') = '\0'; + wsprintf (vers_name, "Python Version %d.%d in %s", + major, minor, pathname); + itemindex = SendMessage (hwnd, LB_INSERTSTRING, -1, + (LPARAM)(LPSTR)vers_name); + SendMessage(hwnd, LB_SETCURSEL, itemindex, 0); + SendMessage (hwnd, LB_SETITEMDATA, itemindex, + (LPARAM)(LPSTR)strdup (pathname)); + return TRUE; + } + return FALSE; + } + #endif /* USE_OTHER_PYTHON_VERSIONS */ + + + /* * Fill the listbox specified by hwnd with all python versions found * in the registry. version, if not NULL or empty, is the version *************** *** 660,663 **** --- 883,896 ---- } + /* Return the installation scheme depending on Python version number */ + SCHEME *GetScheme(int major, int minor) + { + if (major > 2) + return new_scheme; + else if((major == 2) && (minor >= 2)) + return new_scheme; + return old_scheme; + } + BOOL CALLBACK SelectPythonDlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) *************** *** 682,685 **** --- 915,931 ---- SendDlgItemMessage (hwnd, IDC_VERSIONS_LIST, LB_SETCURSEL, count-1, 0); + if (count == 0) { + char Buffer[4096]; + char *msg; + if (target_version && target_version[0]) { + wsprintf(Buffer, + "Python version %s required, which was not found" + " in the registry.", target_version); + msg = Buffer; + } else + msg = "No Python installation found in the registry."; + MessageBox(hwnd, msg, "Cannot install", + MB_OK | MB_ICONSTOP); + } } goto UpdateInstallDir; *************** *** 688,691 **** --- 934,944 ---- case WM_COMMAND: switch (LOWORD (wParam)) { + /* + case IDC_OTHERPYTHON: + if (GetOtherPythonVersion(GetDlgItem(hwnd, IDC_VERSIONS_LIST), + target_version)) + goto UpdateInstallDir; + break; + */ case IDC_VERSIONS_LIST: switch (HIWORD (wParam)) { *************** *** 702,706 **** PSWIZB_BACK); SetDlgItemText (hwnd, IDC_PATH, ""); ! strcpy (install_dir, ""); strcpy (pythondll, ""); } else { --- 955,960 ---- PSWIZB_BACK); SetDlgItemText (hwnd, IDC_PATH, ""); ! SetDlgItemText (hwnd, IDC_INSTALL_PATH, ""); ! strcpy (python_dir, ""); strcpy (pythondll, ""); } else { *************** *** 709,712 **** --- 963,967 ---- PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_BACK | PSWIZB_NEXT); + /* Get the python directory */ cp = (LPSTR)SendDlgItemMessage (hwnd, IDC_VERSIONS_LIST, *************** *** 714,719 **** id, 0); ! strcpy (install_dir, cp); ! SetDlgItemText (hwnd, IDC_PATH, install_dir); result = SendDlgItemMessage (hwnd, IDC_VERSIONS_LIST, LB_GETTEXTLEN, (WPARAM)id, 0); --- 969,975 ---- id, 0); ! strcpy (python_dir, cp); ! SetDlgItemText (hwnd, IDC_PATH, python_dir); ! /* retrieve the python version and pythondll to use */ result = SendDlgItemMessage (hwnd, IDC_VERSIONS_LIST, LB_GETTEXTLEN, (WPARAM)id, 0); *************** *** 732,735 **** --- 988,1001 ---- } else strcpy (pythondll, ""); + /* retrieve the scheme for this version */ + { + char install_path[_MAX_PATH]; + SCHEME *scheme = GetScheme(py_major, py_minor); + strcpy(install_path, python_dir); + if (install_path[strlen(install_path)-1] != '\\') + strcat(install_path, "\\"); + strcat(install_path, scheme[0].prefix); + SetDlgItemText (hwnd, IDC_INSTALL_PATH, install_path); + } } } *************** *** 865,887 **** } - /* Note: If scheme.prefix is nonempty, it must end with a '\'! */ - SCHEME old_scheme[] = { - { "PURELIB", "" }, - { "PLATLIB", "" }, - { "HEADERS", "" }, /* 'Include/dist_name' part already in archive */ - { "SCRIPTS", "Scripts\\" }, - { "DATA", "" }, - { NULL, NULL }, - }; - - SCHEME new_scheme[] = { - { "PURELIB", "Lib\\site-packages\\" }, - { "PLATLIB", "Lib\\site-packages\\" }, - { "HEADERS", "" }, /* 'Include/dist_name' part already in archive */ - { "SCRIPTS", "Scripts\\" }, - { "DATA", "" }, - { NULL, NULL }, - }; - BOOL CALLBACK InstallFilesDlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) --- 1131,1134 ---- *************** *** 935,944 **** /* Make sure the installation directory name ends in a */ /* backslash */ ! if (install_dir[strlen(install_dir)-1] != '\\') ! strcat (install_dir, "\\"); /* Strip the trailing backslash again */ ! install_dir[strlen(install_dir)-1] = '\0'; ! OpenLogfile(install_dir); /* --- 1182,1191 ---- /* Make sure the installation directory name ends in a */ /* backslash */ ! if (python_dir[strlen(python_dir)-1] != '\\') ! strcat (python_dir, "\\"); /* Strip the trailing backslash again */ ! python_dir[strlen(python_dir)-1] = '\0'; ! OpenLogfile(python_dir); /* *************** *** 961,974 **** } */ ! scheme = old_scheme; ! if (py_major > 2) ! scheme = new_scheme; ! else if((py_major == 2) && (py_minor >= 2)) ! scheme = new_scheme; /* Extract all files from the archive */ SetDlgItemText (hwnd, IDC_TITLE, "Installing files..."); success = unzip_archive (scheme, ! install_dir, arc_data, arc_size, notify); /* Compile the py-files */ --- 1208,1217 ---- } */ ! scheme = GetScheme(py_major, py_minor); /* Extract all files from the archive */ SetDlgItemText (hwnd, IDC_TITLE, "Installing files..."); success = unzip_archive (scheme, ! python_dir, arc_data, arc_size, notify); /* Compile the py-files */ *************** *** 1416,1420 **** { extern int __argc; ! extern char **argv; char *basename; --- 1659,1663 ---- { extern int __argc; ! extern char **__argv; char *basename; Index: install.rc =================================================================== RCS file: /cvsroot/python/distutils/misc/install.rc,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** install.rc 2001/04/10 18:55:07 1.6 --- install.rc 2001/10/05 20:38:11 1.7 *************** *** 87,91 **** STYLE WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Setup" ! FONT 8, "MS Sans Serif" BEGIN LTEXT "This Wizard will install %s on your computer. Click Next to continue or Cancel to exit the Setup Wizard.", --- 87,91 ---- STYLE WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Setup" ! FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN LTEXT "This Wizard will install %s on your computer. Click Next to continue or Cancel to exit the Setup Wizard.", *************** *** 104,114 **** BEGIN LTEXT "Select python installation to use:",IDC_TITLE,125,10, ! 247,31,NOT WS_GROUP ! EDITTEXT IDC_PATH,191,157,181,14,ES_AUTOHSCROLL | ES_READONLY ! LTEXT "Installation Directory:",IDC_STATIC,125,158,66,8 ! LISTBOX IDC_VERSIONS_LIST,125,41,247,100,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP CONTROL 110,IDC_BITMAP,"Static",SS_BITMAP | SS_CENTERIMAGE,6,8, 104,163,WS_EX_CLIENTEDGE END --- 104,119 ---- BEGIN LTEXT "Select python installation to use:",IDC_TITLE,125,10, ! 193,12,NOT WS_GROUP ! EDITTEXT IDC_PATH,191,136,181,14,ES_AUTOHSCROLL | ES_READONLY ! LTEXT "Python Directory:",IDC_STATIC,125,137,55,8 ! LISTBOX IDC_VERSIONS_LIST,125,24,247,106,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP CONTROL 110,IDC_BITMAP,"Static",SS_BITMAP | SS_CENTERIMAGE,6,8, 104,163,WS_EX_CLIENTEDGE + EDITTEXT IDC_INSTALL_PATH,191,157,181,14,ES_AUTOHSCROLL | + ES_READONLY + LTEXT "Installation Directory:",IDC_STATIC,125,158,66,8 + PUSHBUTTON "Find other ...",IDC_OTHERPYTHON,322,7,50,14,NOT + WS_VISIBLE END *************** *** 116,120 **** STYLE WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Setup" ! FONT 8, "MS Sans Serif" BEGIN LTEXT "Click Next to begin the installation. If you want to review or change any of your installation settings, click Back. Click Cancel to exit the Wizard.", --- 121,125 ---- STYLE WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Setup" ! FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN LTEXT "Click Next to begin the installation. If you want to review or change any of your installation settings, click Back. Click Cancel to exit the Wizard.", *************** *** 130,134 **** STYLE WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Setup" ! FONT 8, "MS Sans Serif" BEGIN LTEXT "Click the Finish button to exit the Setup wizard.", --- 135,139 ---- STYLE WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Setup" ! FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN LTEXT "Click the Finish button to exit the Setup wizard.", Index: resource.h =================================================================== RCS file: /cvsroot/python/distutils/misc/resource.h,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** resource.h 2001/02/19 09:19:07 1.5 --- resource.h 2001/10/05 20:38:11 1.6 *************** *** 18,21 **** --- 18,22 ---- #define IDC_PATH 1007 #define IDC_PYTHON16 1008 + #define IDC_INSTALL_PATH 1008 #define IDC_PYTHON20 1009 #define IDC_BROWSE 1010 *************** *** 24,27 **** --- 25,29 ---- #define IDC_BUILD_INFO 1024 #define IDC_BITMAP 1025 + #define IDC_OTHERPYTHON 1026 // Next default values for new objects *************** *** 31,35 **** #define _APS_NEXT_RESOURCE_VALUE 112 #define _APS_NEXT_COMMAND_VALUE 40001 ! #define _APS_NEXT_CONTROL_VALUE 1026 #define _APS_NEXT_SYMED_VALUE 101 #endif --- 33,37 ---- #define _APS_NEXT_RESOURCE_VALUE 112 #define _APS_NEXT_COMMAND_VALUE 40001 ! #define _APS_NEXT_CONTROL_VALUE 1027 #define _APS_NEXT_SYMED_VALUE 101 #endif Index: wininst.dsp =================================================================== RCS file: /cvsroot/python/distutils/misc/wininst.dsp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** wininst.dsp 2000/09/07 07:36:41 1.3 --- wininst.dsp 2001/10/05 20:38:11 1.4 *************** *** 54,58 **** 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 /subsystem:windows /machine:I386 ! # ADD LINK32 ole32.lib zlibstat.lib comctl32.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"LIBC" /libpath:"zlib\static32" # Begin Special Build Tool SOURCE="$(InputPath)" --- 54,58 ---- 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 /subsystem:windows /machine:I386 ! # ADD LINK32 imagehlp.lib comdlg32.lib ole32.lib zlibstat.lib comctl32.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"LIBC" /libpath:"zlib\static32" # Begin Special Build Tool SOURCE="$(InputPath)" *************** *** 84,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 /subsystem:windows /debug /machine:I386 /pdbtype:sept ! # ADD LINK32 ole32.lib zlibstat.lib comctl32.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /pdb:none /debug /machine:I386 /nodefaultlib:"LIBC" /out:"./wininst_d.exe" /libpath:"zlib\static32" !ENDIF --- 84,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 /subsystem:windows /debug /machine:I386 /pdbtype:sept ! # ADD LINK32 imagehlp.lib comdlg32.lib ole32.lib zlibstat.lib comctl32.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /pdb:none /debug /machine:I386 /nodefaultlib:"LIBC" /out:"./wininst_d.exe" /libpath:"zlib\static32" !ENDIF Index: wininst.exe =================================================================== RCS file: /cvsroot/python/distutils/misc/wininst.exe,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 Binary files /tmp/cvsrIc0Q6 and /tmp/cvsy5dLK5 differ From theller@users.sourceforge.net Fri Oct 5 21:40:50 2001 From: theller@users.sourceforge.net (Thomas Heller) Date: Fri, 05 Oct 2001 13:40:50 -0700 Subject: [Python-checkins] CVS: distutils/distutils/command bdist_wininst.py,1.23,1.24 Message-ID: Update of /cvsroot/python/distutils/distutils/command In directory usw-pr-cvs1:/tmp/cvs-serv29107 Modified Files: bdist_wininst.py Log Message: Explicitely list the metadata attributes to show in the gui. Updated to include the new exe-file. Index: bdist_wininst.py =================================================================== RCS file: /cvsroot/python/distutils/distutils/command/bdist_wininst.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** bdist_wininst.py 2001/09/05 13:00:40 1.23 --- bdist_wininst.py 2001/10/05 20:40:48 1.24 *************** *** 141,151 **** info = (metadata.long_description or '') + '\n' ! for name in dir(metadata): ! if (name != 'long_description'): ! data = getattr(metadata, name) ! if data: ! info = info + ("\n %s: %s" % \ ! (string.capitalize(name), data)) ! lines.append("%s=%s" % (name, repr(data)[1:-1])) # The [setup] section contains entries controlling --- 141,151 ---- info = (metadata.long_description or '') + '\n' ! for name in ["author", "author_email", "description", "maintainer", ! "maintainer_email", "name", "url", "version"]: ! data = getattr(metadata, name, "") ! if data: ! info = info + ("\n %s: %s" % \ ! (string.capitalize(name), data)) ! lines.append("%s=%s" % (name, repr(data)[1:-1])) # The [setup] section contains entries controlling *************** *** 232,242 **** ZGUuDQ0KJAAAAAAAAAA/SHa+eykY7XspGO17KRjtADUU7XkpGO0UNhLtcCkY7fg1Fu15KRjtFDYc 7XkpGO0ZNgvtcykY7XspGe0GKRjteykY7XYpGO19ChLteSkY7bwvHu16KRjtUmljaHspGO0AAAAA ! AAAAAAAAAAAAAAAAUEUAAEwBAwCMCZY7AAAAAAAAAADgAA8BCwEGAABAAAAAEAAAAKAAAADuAAAA ! sAAAAPAAAAAAQAAAEAAAAAIAAAQAAAAAAAAABAAAAAAAAAAAAAEAAAQAAAAAAAACAAAAAAAQAAAQ ! AAAAABAAABAAAAAAAAAQAAAAAAAAAAAAAAAw8QAAbAEAAADwAAAwAQAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVUFgwAAAAAACgAAAAEAAAAAAAAAAEAAAA ! AAAAAAAAAAAAAACAAADgVVBYMQAAAAAAQAAAALAAAABAAAAABAAAAAAAAAAAAAAAAAAAQAAA4C5y ! c3JjAAAAABAAAADwAAAABAAAAEQAAAAAAAAAAAAAAAAAAEAAAMAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --- 232,242 ---- ZGUuDQ0KJAAAAAAAAAA/SHa+eykY7XspGO17KRjtADUU7XkpGO0UNhLtcCkY7fg1Fu15KRjtFDYc 7XkpGO0ZNgvtcykY7XspGe0GKRjteykY7XYpGO19ChLteSkY7bwvHu16KRjtUmljaHspGO0AAAAA ! AAAAAAAAAAAAAAAAUEUAAEwBAwBWGr47AAAAAAAAAADgAA8BCwEGAABQAAAAEAAAAKAAAODuAAAA ! sAAAAAABAAAAQAAAEAAAAAIAAAQAAAAAAAAABAAAAAAAAAAAEAEAAAQAAAAAAAACAAAAAAAQAAAQ ! AAAAABAAABAAAAAAAAAQAAAAAAAAAAAAAAAwAQEAbAEAAAAAAQAwAQAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVUFgwAAAAAACgAAAAEAAAAAAAAAAEAAAA ! AAAAAAAAAAAAAACAAADgVVBYMQAAAAAAUAAAALAAAABCAAAABAAAAAAAAAAAAAAAAAAAQAAA4C5y ! c3JjAAAAABAAAAAAAQAABAAAAEYAAAAAAAAAAAAAAAAAAEAAAMAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA *************** *** 245,249 **** IHBhY2tlZCB3aXRoIHRoZSBVUFggZXhlY3V0YWJsZSBwYWNrZXIgaHR0cDovL3VweC50c3gub3Jn ICQKACRJZDogVVBYIDEuMDEgQ29weXJpZ2h0IChDKSAxOTk2LTIwMDAgdGhlIFVQWCBUZWFtLiBB ! bGwgUmlnaHRzIFJlc2VydmVkLiAkCgBVUFghDAkCCmxXYH6y1WEpVsgAAP49AAAAsAAAJgEAJv/b //9TVVaLdCQUhfZXdH2LbCQci3wMgD4AdHBqXFb/5vZv/xU0YUAAi/BZHVl0X4AmAFcRvGD9v/n+ 2IP7/3Unag+4hcB1E4XtdA9XaBBw/d/+vw1qBf/Vg8QM6wdXagEJWVn2wxB1HGi3ABOyna0ALbQp --- 245,249 ---- IHBhY2tlZCB3aXRoIHRoZSBVUFggZXhlY3V0YWJsZSBwYWNrZXIgaHR0cDovL3VweC50c3gub3Jn ICQKACRJZDogVVBYIDEuMDEgQ29weXJpZ2h0IChDKSAxOTk2LTIwMDAgdGhlIFVQWCBUZWFtLiBB ! bGwgUmlnaHRzIFJlc2VydmVkLiAkCgBVUFghDAkCCq3wArkET+QFVsgAAN0+AAAAsAAAJgEA4//b //9TVVaLdCQUhfZXdH2LbCQci3wMgD4AdHBqXFb/5vZv/xU0YUAAi/BZHVl0X4AmAFcRvGD9v/n+ 2IP7/3Unag+4hcB1E4XtdA9XaBBw/d/+vw1qBf/Vg8QM6wdXagEJWVn2wxB1HGi3ABOyna0ALbQp *************** *** 253,258 **** A41F9G4GAgx7n4UYQtB9/BIDvO7NNEioNBR1CQvIlgbTfTN/DlZqBFYQxBD7GlyEyHyJfg9hOIKz 3drmPOsmpSsCUyqs+b5tW1OnCCWLBDvGdRcnEMKGNuEoco4KM8BsC+3/5FvJOIN9EAhTi10IaUOS ! druwffI4k8jdUOjISxJFsnzb3AwvUMgIFEBqAcz+c7ftGF4G2CVoqFEq8VCJXdS/sLDtLSG81xw7 ! dGn/dChQaO72+b6QmBlLBCLcjnQTGnOd+5YNfIsEyYr2IR8byFn3IWw6Lh9kQ+2w0VoDxUUSPsge uu29U5eUjV7wzBTGxp3hw86B7Cjhq4tVEESN/9v/i0wC+o1cAupXn+ArQwwrwYPoFosb/5fb/8+B O1BLBQaJfejwbwKDZRQAZoN7CgAP/jf33Y5kDusJi03sP8zoi0QRKo00EQNts13eM/qBPgECMD6B --- 253,258 ---- A41F9G4GAgx7n4UYQtB9/BIDvO7NNEioNBR1CQvIlgbTfTN/DlZqBFYQxBD7GlyEyHyJfg9hOIKz 3drmPOsmpSsCUyqs+b5tW1OnCCWLBDvGdRcnEMKGNuEoco4KM8BsC+3/5FvJOIN9EAhTi10IaUOS ! druwffI4k8jdUOjITBJFsnzb3AwvUMgIFEBqAcz+c7ftGF4G2CVoqFEq8VCJXdS/sLDtLSK81xw7 ! dGn/dChQaO72+b6QmBlLBCPcjnQTGnOd+5YNfIsEyYr2IR8byFn3Imw6Lh9kQ+2w0VoDxUUSPsge uu29U5eUjV7wzBTGxp3hw86B7Cjhq4tVEESN/9v/i0wC+o1cAupXn+ArQwwrwYPoFosb/5fb/8+B O1BLBQaJfejwbwKDZRQAZoN7CgAP/jf33Y5kDusJi03sP8zoi0QRKo00EQNts13eM/qBPgECMD6B *************** *** 264,549 **** /02qNMiNHC5g7rHIlv9zBNaocQuz39xfGvIm9APIK9gZt/yATXIIehAq3kKXQDgvWZFPinYQ7G/b +TMFBC91AkBLU/baGZaCN1/gOqEEMLjxeF186wPusmAkBNL/fWsHETuEyXQLOgPGAFxAde+bNdn6 ! ckAMD3QXyhTU2JnN9U7YSAZt4Nv0jb06wFdQFNRj2KBdDAyz5f9m0GoKmVn3+TPJaJhxUQCVzzlu ! Hmi8sgmVYK621GxTMFBG1xo1HdtuthQVSL5AjwRW9FlQcHerbVYPAR4dOBj/02gH1sHLx/gbYCMK ugPvawEV06ksXzytmTNnn57M8Pnu23Zv8sIQANq4AAYAPSzh5NiahU7plIEJEBq+uwO3VqwMAH0I ! VyEHR6HYot7taNg8WSUUPGhyImgBBABf07kPfaRVBuxQKpPM5kL7xwQk4KAMnwDwpHG9YXwWGug1 ! 5Lwag+3+bmHoA0HWaKDqaP0MYB1vI5uiAARfrF7rJ3eBXFfg6XgIOAEZX35wHb9mvvfRdFzgKdWD ! PfWzbbjQPqtCCNh1OVbtjUS3yyQpqEWhHUALt279i1AKjUgOBlFS31FWRkRolu49ozAsDPxesUEa ! TvwQ3vCww2sVtgjXKNasxQVbA41WosKW9BErf+vbxtArflIP+CtV8GdSmSvC0fhhttVO7RW4xw2F ! TIwRGax1CPkT5cIFDU5Xet0B9myGD4XiTi3CfIlIaLhzLIUKKSgcvv4dZuVfLhS7l/gBwegQSHR5 ! 6R+ShsgKJZYQ04sttLoxV3JJHh48aEmAPcOHDsfVpAouhRs784/MLhYz7VVVaIsV0ztwAxOlxRZz ! TUhVJQ5utq6GFFp3VekOLwiJPIMSAEQ7EayIJaq5hqessExDKCi+AI5x2u0xwmjv8hUVDEChBVeQ ! WwSDCsCfB25IYDHla6sYaJktX7/Bbb0+UFUIJFVWkMmWWimKwmxDn4XJWOhZBlRVRtndHGSJaDBo ! yKIEIHL9NllgVaXczQJ1H/81ETNj7R4FHxCpe3edm9wjLVAJ6xBo3sXDaLgtj+tFxCDEDyP8oTjt ! M/9XVytonVbtwoZJRzN1BC/rAvAMJYyxV+9W45wYGieZvbyBmtHc24VvnPhTM9uaGQAMU2iMkjbG ! sbZ7/BoYYBcHMH4X7YZBC4ZTAOxTUI1FmMeybK5mOXAn+BzxGmcp7/XdyrvRanbluGFF7dE7wy+v ! 9dIHdBg4GP2NTZi31akz26FioDacU1DtXqRnc0j/ZHLW4xBbJy3UZMABrNfa6EpLmmcp+P44I2uz ! 2dli7McgqsZrb7MlNezw/U4AFuyNmWXwDAgQHxthd01DI3BZN+homnQeWBew9xj88oQbDl6s4KBS ! EkYOQ0tgFr8XeP0k08DoGbiUXi3xAhdc1zSbPbRjamXuAgQizBqUAE9yyDtz2AaCaOwQ5E4RrazD ! bXBhjA1tHc8BNRJySKfr2c4WyQGBySBoWPRyvmQrgVJ0bGvocfeHh0AIPTHsdCk9gBZC4Nlh+QNJ ! NeBPIzBT+75ViT3EoqMW7sNmgLg/EV0fwYKMRHhWHE1Pj52gFBHvoSRZNlkVKOy2x4DwK38LKZV7 ! HXQ/QAJ8BxMgGLuu1L3wHF3JU3SysWgmHzOc+D5joJ8FJAQuUrpFa7QCyYHoaDUci/DebVyj1F10 ! EmjEOuh1SHJ3+w1xWR40oRkTaKjAxG5WdRoFFGLw4bZZzSnjkAhN0BaetPF1Jw4aQHMPTNLhnbo1 ! 9kjncGz6t0+t+IVVBYPI/+tmUy+YYK7eyB262HNAxAccSefibAm48Qqkag8mzfSUNpjdtlHXYHmJ ! B1Uk0+L43RoYNg4dyaUS9FeXyiNLU5xeW1/rUAGt4OAtoaoxBkOhqRZbQBBVygbaxaPwfwRB6/YP ! t8HB4BBBIzAb47EIu1Q4U8TWJfvRHb2jVlUQQRS9g89Gv1GF9n+RhCQMkYEL//fYG8CD4BjAY73J ! uKu7EDb/BY28aAR0b8fIvXUPKAqUJHQvwXQE9jbbciYtdCo0aPxzLGZHGwcszQNSDyIEt2wCjYgs ! bQe4t4+LdgSUdYSLUo6Fd1ZvgcT9WADU0MUDm61bEhAA/E4MXKPDiy1tMXmRM7Izl52EAQbpAJvd ! 3JbtdHsCXiEPhf6hxKB0ngFnB5lHaHQDhlZo0k5e2wRJL0yGVgj0iZKdurOm1i5X9hCHutnXqDlx ! k4vU0syOlU0dEJ8ZajAb6aQTWt9HwHC89rOvEexzitCGTCDM9uqkZNhq2Q1gk8D7CRJHaEgfgnWf ! gv25Nh9oduuWfX8zWQmZsBuH6xtXNExiI9eLw+wzCAyMI/Awk3hBiQZpSxijfVmJRgQDIl58fq1S ! SyZW6hcKdDUsNMcXgk0IUFG8BYMRvNlZqEmMhhXgpCJLPuQzkGYSYptSBogdKJR0XwF2nSvwQRJW ! NODwFjibI2pfgLkbcoezacAxhUChBLzCrhdEYXRJqxV+oe0WcXRDBAH9aiNoRHWwDeaamKw4N9YY ! Bvv/VipWNAYHD5XBSYPhAkGLwaNCe2Dg/evHxwUH1wPsM72lXV3DagyQPGhAOKOnJ+gGXh1AGRxE ! K3GaLdzJNa6h2ajLJuTWbB8KZObMdcTIGwnEIignQePr2yolHOFsBxpnv9RLiCdY5LOEH+R0dg1w ! aLYzcElso9PvfZZcsCyEHYBoDwZzC7PTBYtALTgFZodI52MpVPoXjVjtGU1GLIUaXCwMczAReEhV ! DDxU2kQ/r864umGTRYw7UhkVJjQw3iA1yB+8pQnNYSUkFLkKmzBP5xSG/FBenhjWzlxQAIyCAK0W ! zM5dGxP6RKshMbJ1X6qvYM+CffABdRw9jOR1wjQzQGMzPiAESzghtdR1Vo7RsIfnGECJq8h1vWFm ! +Wr8FGQUINiAnGmoV2IleSBszph1sJR1BguYzVR8vPns0ZGlkW3NeOyNdKz1DrNANf4DiaUbsPcD ! HEC+WBeqVqbCsLIjVqJ5GA1lEpgMg1Y8G7F3cjX8bAU8iBkvJCP0ETaF7hVrRFy7JLQHxL7TXnTq ! yllnTiyeASWUSnVl1D3AEqGD1KoTmBZCrrt6No8cIRcC/wRdvN10SNV0VGoLWRGNfcTpRrdLLPOr ! BvSJK6urALaNfWho5gyrGpATjBtNtzDxvwAIF47AMP2JCUpRaC8vZjG3AwtbHNwcJMQb2HUhPri1 ! FgcGzGsn1psznTNBUSsSbCBPLhm79hdAGfRtjRvnySUn+G7OJLpzM2yfiY5cjDR8mGUzbQ7BBZQs ! Baxt2X67jH+QIJt1tAK8qA8UoTzQpARkKNnwhotlrx0/NcyibuItXVRsvRmAFFW72vBSr5I+vjB3 ! Yih3dyrtHlXXGBBqhCo+qTN34Bd2cxNBVbsFZLusIChVJ6BkO0GbIz2uKBQWkTrYey1UTjLdoZOx ! FdWjtxT0eTM0kHatRQposPr8lhzkdlvgoNx2B57s6WvQ16r7UKOUYkhlE2AVR1XacPG6hqE7Nm9b ! YDwDtPzqE4Bu8TjEBxErUwAQEm9NTeJWGld0b+XxP8LQEJUDZoP/AnZheXv7G0h1TopIAUAIMHxK ! BDN+Hi32f3ludAxydTtAxgYNRuszBgMsYaLxCkZPT6cNT1FfoydNYnw8CigfTyX6N8OIBtQG6wWI ! DkZAT6pYvV2hmaFrgCaocSgcSsIowd68jo/c+KhWK9gD3JoVQAA4ShmW5OADSbHg0dcCTIk/8J3D ! bMJlnVy+TGCFNWBr+Ni7cHtQIvgPH1tdsyX0ZncXH2QARGMwkDBPdtgMB7Kr71U4d1aNERt02ozQ ! ZdoRmjVXolKNBAstGaKB1kauuGJaoJ3pCuEKBAb4YbZicMIOYALoVaRsbYB5BLNTuHgmze2MpH6g ! /bzWyWAnCxG4bK3Zqdg3ZO2s2Vs7RjID77+gEDcRORDszd6E4BBFHV841jNoB6lqRCWoXlZTBjiI ! RGExZaprbqRd1J5OHFCF22z34rdTU0QqU2ZNH9sZuNg+qUOPpOfx7bXdAYjWag8YoC8KW5ztRbMN ! ZOBgNvdtI+wsyAjWLBNcujiEdzUjU0w0hbZ6fWpb2B/Y27J0X6DbwkNqXVMN+P8YuSr9PIAnAEcs ! aQkcskTrA4AXqQhTSzwISKVEMgQU0k2eYAhpXXKUHDI9LQjUKTZSLTpL313oZb51AlahmA5GgzgB ! fsJ88FJlvgZqNpSt7twXIRGLDZAJFYsJitM7acdWggiv0FbAXk88RQYCfHQUGhs0ko6yCMBulG2L ! ovgC9Ald/NFtE1zwCvEJU+9MebXqmtomPYtESAn/n+xnLEl+HjQeaDAboFE/YwisWTvDWQKCSU3X ! Oh8YU2lvZ8THAh7LaiiF+Cj7dQs6I+3eaAgiGR2Fi+z6atL0ootoqbPhLGY/oihbHxdZDO7lIUIE ! AxWENesazIYcCAgWGvf9jSUNQE7rxICkNUsAUr9ESYhDvIkEj0E7eMNbg02ECXwbgwqDwyhTszlm ! DpWzJI3GBhMHMq2FVbEzDZrkClwkdBpF13rU1C5VmEyMYdOmIjdr+HjYtHgmj9pMJaw/sUVLbheD ! +LpPjh8Pc9x3XUs8Akr48V8e/zBT7NiTEY+E6wAzixjQ3o2NEbakWNZqO8d1RTyUPvwuGyC7G//z ! jTchCeA4ftivoMzWIkDCL1KYkc1srloIjzH8sANyYF6QdBp4PJ8DOXgQGtCiHMiBvfTrQylkCA7k ! wP4Z/OsgS1AHUCi0R2ZZg+pLpWeNEblr8/5+WJ8FhAHtfWQUEbOQmYGNjez81yAKX1CqUa6dW27f ! zH0g+hTrGxYfHNgbhIclsUD0xBardsHgakVdGNjV0hUMNVOZBQxidemEnlnDV75tLQ68DwBWNP9V ! 4MTHiJ9HH6dZo8bPTg060w4IS7Tre/ELRmwNohLCIB/gXZDYYKPM0xAWPOthtkiP2KYoPgc5LKDp ! WPsMMA59G3AHP/iHBCdNRx9AdBxqBsKQDtdzZ7UwWYzCU6kAzQWREjijRw0qX1G0ZgCRopgzI8bo ! XNEIgOLAHwCmluKDaCtNag+gdFGAFfvUAQbgDEQECNIBbIobOQSjkosliNeWhAj3w0BiCEY3i1UI ! GnsB2Ch0TFErQRACNwBvRaEigTlLjTQQbN9QGwjDxD56VjQSC7dFqbnJOIyvAE7y1Yb6v9kNi9Yr ! VgQr0YkVCStG/dbGLqYQu1f+DICJASt+BJbYGWaYI7F0d1H8JXdGd5uIVlLq0rMTtmYW2vQ/hBvV ! mmugNp92yCLy91YgWGIISAx0LhdfEAxgV1A208zDbY0Qr+sz1EWijzcYC0bMAEvL9rf/M9I7wlZ0 ! M4tITsp0LIlQFAIIGG6/0P+LcQz33hv2UoPm24kxi0AcIBRRVOEE7EInPGCyDPsMsCq4nwiQAKt+ ! wRBtDPZ0OotG/+i2ZqEzGiQsPRQNCm9u2bXUPzVcCB4aKFBRzC3dFuckDccAAFSrBR8B5VYGLGwC ! tub3igENljrBHLZ/LYLnPHwkGDgK3IUtRuwdwzv3dQo/UWQ39Nb0IIl+GNIKYCDgRr9+KDnYlbfG ! fiSHDiQAR4FqGLa5ANdkhDMniYZ+qUm6PvxMmol4FItW/373FxfPiXoMfQy099nHQAwBePkIfFlr ! /3VvBA9/VB+4EdPgiUoQUtfT9n9hUTfaG9JQ99KB4rBFZVKB/3UB7ie8GWhBT1Y5ehR1+Ja9gA8T ! bg4ceLJZd5sLVhvJX7j65wlLRmkQcVNVDuVGlRDoBAR2wmbb3Qr5A6E+AAjwi1QjfQe9iYX6BL/7 ! oZXDS70F+PbQ/sHj+4lcGYkIyA0Ph8St8PAOHSSNADcZBLY929E2mohJHokN4kGLL41v41sFiw6K ! ERwENRYQ7m+U+gSD4Q9CtC4WdBXHAA1Vu2RecN1sGEx6deuiIsBu3L6LUBDB6SjBCF12GCRa28Dk ! OPMjHhcFXeHm+b0EEUgzyY5mCI9b07dAdoteHIlOBom9HwO/xFtsE4l5QwTBaQPB9/WFLube+9J0 ! IccDVpTR3V+5jU+eIGj2wSAlgWOO2LCzKQcmHNgVXD9adNoobGKkFIJ9b2X9dRijAlXza10EM1os ! RAKSIi612W0BT2kCc6AzjUg5F2mr7lIeEkS+2daxVAz5C9gMOeMIC+bMSy0CY+TtrvHW3OFK3MHh ! GEgLqiVbe+RJNAli7YbmoDODSEKJBjr+1hU2MdKQgUg34hADyolIIrlkwDkKvpJLhuQIC4TDjbnZ ! Nj85SDQSzRBhmTbr5TMCciCYWekIfsg2EKRoAnUJi8ecW7aDkcIIp2dyMgvt4GpjpBZQ4QF2Z0du ! xwEDORZIT1kabgk3igobUOEBcuRs0T5WAgQIYTLJDtIgpIQRdokosyHNdiEhH3hOMPMGuIZlJHv4 ! O2kszQqGgfiwcABvKyybJWoA/QxDuSVbkgEp/QaW3faLOAs3M0yuA6Q13pZNs2wdNlikJTSSls2y ! accBNTvcNugDSeBlW3/TgcPtxVf1ejyJQ3RiawtAtAQPBAXY4I3WT77rRyhSqVeBXW8dynUGdQ0+ ! V1Hq7cY7sj78KMfyAUY0ArYWBLYwDjjuUQgg68IBfHQO3bXQH0CytltgRzDAw9/OFYiv/G1qmmRj ! KPFFiSDBTPbbR4sLOcQKTyjkScAB1wIbGl9Z6YKh2Zd6VyiMkCL3GIPtw3JAOWgO299QKCgfn9bA ! udMrUR4uoja6VQ0SAk4D2EjMFt4eiV4svDjIBL3sxWJAqgCD7Ggtug+YOFNvOFj7ttbYGilDsmsS ! SC5LFt8K0f/tEDBWO8iz2vLv2lQKFURzBSvBSOsFLAc+ly/gHowDg/gJGQyFHK/1DQ5AfhiD/QNz ! WD3hemoByZYNxu//277kSIoPxxRMlIvRi83T4oPFCGN777ruC/JHMYk4iS9yzusEN6/UAr9VnAeL ! yNHotQEL3HTfdYlLGHeRY0SD7QMZAU3vvz3NHAfB7gPT7ivpP7MohTqqg65BSH1SGsTutlGdjQ0w ! UQ44Ukeva/jORgwkXCE0+N0HSrxdUQ8sUhDeEGe+At03DBSJrrXvXFjMjD1YcQZhFO7whhwD+P1Y ! zq2LtxTOIHMsqfr6oAbnsgUaP0wsT/Z8XGgzuEAnAPLUjYvOAu9KTYLhB3LqEDPRr7f29t+iOO2L ! wTvF+gSJbFxLJgFLDDtIi4kD6UzSsInObRe8KsccBYWddcN37RZ8GkQ71nUjv4t7KMJ3jXeOGYvX ! O7EVcwcrwkhXumPbhWQr8nOJNXVntEwcLlToQUgE+lM0KN0XWyu/B0cwatajTGgb3mY6MSvKSf9L ! LAeMfLfnBD5VdSBi99bb5OaD8k6LzsKLyKReDcOEO7ALBUP3BgvJdp3CO8EFwT4vUWhNFEQwJIEC ! 86Xh8Qvdi8otHN8DK9DzpNpcjba93SVEA1INS10VDJ3p2vArDBaJeBwpWLW5FgFoXWQYv5DHGMIH ! KpYOczgZ4yo5Mg6S0rE5ug8l/z8lyCCYH7HQt2yHHQbW0DzgTcHN3QiB+qAFE/IFmgWZ6BtsfR9G ! jYQIAj02ztLNdwNIKPlQYQxOvPF8jQUOSA7HQ24ae5sm8ATrCK5xUxca3WiSCBEKg2Itc2hU8jtP ! WTK+NAZHpIXJAywITrGlTLFEi/wYp31oDbYfxQSRYQgIA2H3MFeGamdymDC4E6G9Ntn7yHMhPDTH ! MWk73VzhNaA3IHLfcBoaLH1pJG9DEI1TUVI0zqbNGVfx41BRPxxtZtcAPPCFIfsI8BUWsuYFT2XQ ! t7Ng+DTiHzc1Al0Pg/Ho24l70lk76HMz4/fa2vtKOwXr+vlKmPbNDaG59PkH+i7B36Vj+c2LyaiN ! uRQjxho0197mVMEBjeY0drS13e62VRCXNHMbySvq0QxwDQuuRYQSinFApC/0u+03LnAjErnNdAMz ! 8oPo3CUejxLNWSsk+AtAHvaXH8ALO+lzO5ngBI0cWLcfMJ3pyb871x7sfHdViwyNqSPOWq29RiYO ! FGLUEU6N95Ab1xUct346l+GMCh4D0Dsqh6liKfd6ddMqORDMXahR6ZnwgpMVDZcK31zaHYr86wIA ! qAxBEtrDt0iZj/x19XeJXnptLxMHgoWYFUAkjJk+0CZRUECN3wksNVzr2CRRElI8NjtRwAT8P1FC ! BW9rPGsgss8UZQkHQAY9zrLDD0R8JB+jyZ00FUwkChkIJTTg2uw0z3c9nzwYAtv3ICsceVCkLWR5 ! 7k6EVwQEBsICD7ApSA9zXms86mKL1jCX2ATQKw5efN2dOANWTOjO6mvQak3u51FMmWdrdEmxe0B0 ! F2dXolZdtlQAHaLwgIsnTT4NQ8GZQSMYsSnMWgmkiSEYiUuygfnSACwAoV7bOJidz4smaJqWc6/t ! ttrplUxRd4XaFyGXBFqwkKEzHNqw2wYww+BRXHt0M21h/cszGMi5VQ+/OTc58uTXav0r0cMDZFcy ! 2OpQTktMjXMNy/Yxi2k5UdArAWaSkO0WYeovFVJROkPsW5slhTJqx0EYqIN+rLW3S0ZASEhRiXkE ! OMIQ5kZEGBFLIK7RJhzos6zyhDcIswinhBVSyMV7JLDGVMqJz2fAxADOOUEEk7i3oNCK1PcD7oMl ! ENwzUU/RWAVDSzC4RROfIRA+hM+eavxQlENKGgp5kISMFEgovM8rjjZ7I4EYnf11BlulLbKHUU9R ! qIRkHYM61yJolBTGCFtGfJ67uKxrVZFS3VAhzSAcBjXPaJBJcC/a/oH9LgRDrF8kTBywhXQQ7BhS ! RygLJIQ+CSVvpLA7XEhQUnq9ZyumBwxApk7o7vBm50FQVlN0Szb3HllT0XQ3oXvoIJW/fYQ3LolW ! BH9QK9WLbgi+lWxL4259PmYIR8Y4QBgxQy6LBq0WvsdMVlXFY0NLIU22S1aZOyAdQtKdmKAwhDAh ! lw0YNSHIJJFTT9hrrH2w/kVDSCpDbhvAU//EOMU5AzA6y2a5XFs7CjzxQD/nZtksl0NORJIoOUak ! mAGbqClAG+8Wgga4DKIMMVelKMABGEdYXICncGndi1hGKOD8XqMYDRgIVyywAxxj6U83YpBqt7vv ! 3XUKYoGeAezCDMNce8d37/nbD4bvEVWB+7AVmcNyBbgIxR938SvYgg+Moa3owe0U4rdo22EQihaD ! xhs55OxdrFbxA/kI8vPkkEMO9PX2kEMOOff4+UMOOeT6+/zbOeSQ/f7/A00rKsEGvGSfSUq9bZ0V ! FhJGE0h19LHu29jdDbnx8vfxTL8IizW27lbb9/fri/WHEzFdF1sSHF4iNV8LwQiflE3wY5UIUG5M ! xkAmaCFQCRod79J0SwTDDx8coUZHtKQ3pYpPeMddoaNFiFAQWgyISBFwB70RdQAAD0gYw17xcBjf ! FH8gdgUThhbOA0aS8Iu2BI1WyNpuDMEJVwubDDTBfsW8H2yfphDCRiwHiTNNFTegQDrf/gYLHdr4 ! bNhOTz0cGp3O2o5AzhAKCpJsKKvlD0ZGeiyJfjuMLS2wlSkrInut+bRUaluFiQZl3FU27Oi2CkWU ! VlIiTRFPVRB2Tx0Dd0ds6sijfhzOdK1kuEidKA1krBW4QK6cozDi/xoNcqV0E0n32RvJfrHVDcmD ! we9NYTeNVCvR52ZjELsS9dZYsbZFskVY+HNEc7HiYUBcBLoOtQCv2MXtMACyzn3JvY7P0+DQAMcI ! C8g2eWx0137gLEE/CixyvK6FsaW67/gjIAhWyEk8+hWCGCgU0+i4waVfI27BRSv4QIoBmi0Sb8UW ! i0mPlQgGuhs9Zq+oEHS74A+ui0kXayWvBSIfAi1R3TZAr0XDqO/j3JAzBycfB4LeZw7p2kIar0jc ! fMMC9nnQ59gIN3Pykb6LBEy5TQSutdbeA8jOrZGw1HJKVJuZA9fTfhIMhub1RcxlXhJGkRyWA0SA ! NEzCZAxEBMLNguGF8FJlDI0MwYiAPEAIQdgCcsghQwwMBaEABQZvfgMbcGzAaxXVdQPCnKlJvSs3 ! QNYfhleI9u0jlrFaKvH8qAHQhZcsLVDabJ+OdSE+MDvBER6cVGpULSkM+zh1RNgI6w9/Z4ZpEqWN ! FFKFcmLJkBkZPAxtYg12cgNdY2Eit0R2yF6PYp7bAfskjBCQQvMJiEr/EXuKnPtBSDtQCBIHTrA5 ! Op4MZklhzyiBDWkwN7AA48n4qEDgTQqKMLD3iApCSES99paBJ+DPFIsrCuKBAsfox0MfK80TF5NE ! yJoRqvQUEPhmusNKCTAYkHtAYuRH4A1QZWr9K81TNleYG1ZQSXjrtHmQhcqYiokDv/dDWT6D/wd2 ! FT88g+8zvFeCCJFMiUw3dSgsoVC2i7LsmAta6mKzTiA6/KVMbyttbjz5Uyv9i2sjrNAbZO+JC1v+ ! komERxJBAUUykS07/llut+qQpL5hSAM8ScAut82yfkr0EkwH501fTq8MgFkd3/nokUWQDCBRU6dj ! oXhsIPoTdhBVN4NEZ9jbdQnAj4+OoVtZdRyyVlXcQF0TSY26U+sgUlVflK4FpgEThT9ttWWizKLT ! /jcaJ2r/EltTUsdHGNyMilfx27sUNF1eTB77dAaDfRc13UabDB+4vsLCYmExMCnPdpX7e4Hs8KKM ! JPQG/LQk3QL9IPPtV89EA0g0TdM0TFBUWFzTNE3TYGRobHC5gDdNdHh8iawkcn6hxAYyAe9+XIRE ! jUS7QJfeA0NKibrtOQh1H3HRf+WrGIGUbsCJKYkqjC28CECPGpwXuTbQU18RjZg7QzkooBvAFz1B ! g8AEJnbz3Xh82nb5zXMGmmK6Dzf6P/YrtHg5LnUISoPuBDvVBTv6f5ttF6UsdiVU+r5RiTvT3dv/ ! jeavcxKNXIxEKzN4JVPDBNERcjNEaIPyb5WjhRwv0K1wDESNAyvxukB5EHUnm1ERogPO5Yjub23w ! LAv2Socz2wNMHEhJLML9buWMHBd1791AkYG+You0zf8CtsOtHBWMhBw9KHi8Het1jA2JXHhCiRES ! R3zTUHscCEM72XLFV2xk7HaL3/dCjBQ1lIkhTEOB010DcSTnTNH3HmHHCwAS+IjfTsQdPA+PgQIz ! NA9FotBlhw25Cm6B9wI7SYXS7Cs+IIPtvW39O00PjgdgFDjWsORmkSwt+Gxnov9fujgD3yvTRQPP ! O9fwJuioW6Ia1xwgScsz/T8JuI19ATvHdieDz//3GoDbsEQtx24YQQR3t7Cwrn2+xW3gHwcrxxLH ! lqVocu3NJL8754uRo75ssXwD+IH/iJ8+nLHY7yYgKyzCL42UONCDvYTYNok4i7nCrk/dP3Q4Q4hM ! oLSELDSx/SLWy4gFMb3GauHXS9eLSvzvi/XTwbobC99DK/CJFDt0n+sJShgVG957KODwBo//2xuO ! 0FqMborQCRwq04g9MQbe+HSLCAyRf3IHxg7fFd3GwOufNykMk/FzFIH+7C78R8kb0oPioPZgiHHr ! IO6bqq4gFA/mAooUMQx4t3ZAb4DCSzQxIfii5baxBPYOhyQTWxtZR7rivLQ7FYumamFzHrfFdDB3 ! O8Mxfok5jTzVpHEEhh1y5isTI3TVFHqNwjEIt/+CgYXCdAgz0NHoB3X4WELDobVKDihgjBxoH4w2 ! jQUxJE8j+ss/yn1XOl8Yg+gET4gmK98Tx7pgOTMII3XcdXV4YowVyEogK3w8TA3SwhxSkEBtvDp9 ! 68GaHk6Ru/qG6RtC1zv1dBeRLAGstZCldE37AQyGRcAFCiQPHmglBF+jYTiANPBYaBJkGMMJvDML ! X2Y0VXqcpIFkGDRS03IXiLfYaBhj15hiBKCWwA4VVVJwxAVm3GyF00U+OACZbLBYQ0woSDh3bifa ! exZMEGRRvwf2RlYeqFJRS3UkJ4M6GIDfWxYIgf1qdxM/J/CWAB2r5E+HLdksUYiNHvtZEHjIdR9s ! jeMjxYZ0H/x0DB5IL70Bg5EjSyRmYFAqgUJ+RSBJMBsjDwbRXlzfDbD83gPlLgDvobQKnIkCEMDD ! dzeUxwG4EccCuItAyFE2YON07Qxja9d7OLXVAMB2/cHrjbb9d3YDFSwRe+876Fhbh4Og6CcyIPcI ! lfgjDeogVhQrxQPV5r8EC7UwVpY4cA6LSzxVBNyoEAU2QzzEpHrcEs2L96Smf+VSfVnKpgPFF0ss ! A1vVdo79ogp1fkFEKDvdonMNkXUfczTqmskVtrAr7p8QhFcOciDLR1dWRzAWW6ixfM1e+IR7omDv ! tYLkjIq6YDj1YVooVIlRgiV8pXI1GF5uHHrxH8xZ+YtpoxYu3JxRIDtxMDc4Hap/OHY77lFBHDlz ! CSv1TlVLdRkqzkkxzaabUO6BNrQOHDSX+JIsIIP4PCKLSWKro05BEYulyNu9FFAa1wvWRx1y4lh/ ! g7fYolcwI8rIihzOjTTOeOe4ESyEjsIyTgHT6msicAUEZ7c5BIAfLEC+I2sMnZADu31gXgQ2A8s4 ! VdAF+wd0x4PjDyvDNDFOkWztKw2ryyOkD1vSTDIPIDScRsiRKTEFAQPwZsqUzzvDcytZHNBc2BiD ! +efVlviq/YfXQSaXcgc8rVFbzllO+s9wwXBF2Rzux/VIwYUgFNeUvEkoYP8OvhE793IXi/dFig5G ! iE3/BrFGNPiD6wLrAesnt1bg23EsHzvfdhOLHRwARc4MdvZGT3X2GCgQS575uS3Z6xm/BgQZcEVJ ! YkcU6IFhEnI6OWpXPw5yM/lHyLW/KtTWnBBJBBN0K/Mv1NscPqzwsq078w9N3rmIggctSseLdOzt ! As3ZxWXB6x7ZcwLexuoFejgr+TONFM2awlyCMTbEHPoWU0YIKxTeQerPiT4rZ1YN4dSsklbpc2JW ! pAB7IHRWV8+AXNhsWtuQMvK9dnI/EGb+9badlWqIaAMrQVgvsUG3QIsxQTl3X4lBpnc6eGea/Waf ! jGyN4v8lOIAFPESK3oyMSEzMzFE9fQtb8dYLcofpCy1uXRz7BIUBF3PsmMQMi+Ej200lYM9Qw8w9 ! UFwffKkwSGr/aIhTAHpLfZddZKGhUHQlB9R4KdgYaMuJZei+gI3oFgBqAslg2VzFDsQN3H8G4AB2 ! FNsU/LcNGDvy3Bq+CA0AYRShBAyXGiv6AKPkm0yYHfCt3YIcujfuXAZObaL+zAhhGNhoDKcIcKqB ! ep8n0qEQP/aUZru5JWMMDAmcUAOQ64iWiqBfEPgEMu8CMOQATqEUbn/3N6gwyIA+InU6RgiKBjrD ! dAQ82wPybQ3yEgQgdvLU0G1x12xOpLDB9kXQMxH/vL1V6tTrDisgdtjr9WoKWIqlokWV7mjrGtST ! jR7klDMYaxyB3vBF7FQJiU2Iy8xZEbYXXAou/3WIHyBjsaKRsSQFHAybNsyuvQMELC9NAqzDPbeE ! FZIAL/Rg8AUCsM8FDwAAeV5QlRX//xCabpCmERIIAwcJaZqmaQYKBQsEpmuapgwDDQI/Du3/QZoB ! DyBpbmZsYXRlIDEuAX/37f8zIENvcHlyaWdodA85OTUtBDggTWFyayD33pv9QWRsZXIgS1djb3ve ! e++9g397d2tfaZqm+6cTsxcbHyOmaZqmKzM7Q1OapmmaY3ODo8PjyC5CeAElAQNkSIZkAgMEnWZI ! hgUAcBJmyZZfRy9/mqb73vfzGT8hMUHXnaZpYYHBQIEDpmmaZgECAwQGCJqmaZoMEBggMEAb2Qpr ! YOfXx5KwhCMGp6uQbwkTr7MDCwcEGWQMDfYqg9ZFqqe+A4BUUTaqBvF/+U9DcmVhdGVEaWN0b3J5 ! ICglcyks2P8/kE1hcFZpZXdPZkZpbGUVKyxl794QHXBpbmcXEP/tJ8D6RW5kIBl0dXJucyAlZLCE ! BXNTFxQTeMDAfkluaXQyGDa//UG6HVxTb2Z0d2EgXE1pY3K39rfdb3MNXFc7ZG93c1xDMxdudDr2 ! y/9WZXJzaW9uXFVuc3RhbGw3kHE22Fa4X+KIB4AP3mTZDHhscWQqq+TJyS9QcVBxrf239kxpYlx2 ! wC1wYWNrYWdljrN37y3yREFUQalpcHQRC0NSSbz82/9QVFMASEVBREVSB1BMQVRMSUJVUkVrt7/9 ! VGltOyBSb21hbgtoaQrdwbYLbXruQHdpyCDQ7fbWChcW4CB5b/AgYykKf/vbcHV2ci4gQ2xpeSBO ! ZXh0IMEKha3gFwkudWTM67b31hlLY2VsFRxpHWgVDxisYVNhcFsug4dbobV5FjJwAS5kMpobhLFQ ! DyBMIBYCHWyWEH8gBkNvsu3ZzRGVXEmgUGEUAEPQHO22tShmsw2YEtnG1uJn3HRoKVMdH805U9/6 ! Y2ZXc0dYu33ELqtvLgAbY/CWzSKJHBQQDt2FIWKBbgxWLrj22rSli6hNSWa6VygcX3Y6LK52W9s+ ! mAVMY2gSZzMEecKFRXgqg0BzWnCMtd10dnMsKm9CEAkDCEOdiXeDao3GbfdfTycAEbYL3VZETGcP ! Ui1fUxBwtTFX2MBTK1QjRghfaniubCMLx1AGZ3JhbZg9zbZOAmVDQ2khESYc7pdvYWQE3xp0m3u3 ! AN8lY29Y0HQaX7MBa3hFJTsLLgeIH7ZNynInMCenMTAwAkNXW6xkEiY6JYiT22DXcAAyF/VcKw12 ! 3RhFi1sfmenGyRtPdgZ3ciEgsmHNudnpFiceewiFQxlNtz8AGwut/QpzPwoK/Ab4WRC2/cNFU1NB ! TFdBWQlvLlb6O/YsCnAtTk8sTkVWfys4VvpUQ0FOQ5dcU0vbcKNg50sHZHXreS6XHHFoA/f6XzcN ! QrJ1sCIVUmVt9srvcGdVZXhlIiAtFALfwrHCLfosLmzAIud3rfCQtWIDLgAwND8Q1rCVbpVEQkdV ! dT1bGWitCdtdAj1+Y7VJkyLcHWF5/Ter2JNshmQ7MktleTmwcNt0Cjd1bCBub/pjCu61I7Egax1L ! kr8KuGWT6SPbVG0QOs4hU+xjvyoA2pYwSiP2CnJKeO6/73dZLyVtL4BIOiVNICenZS5lj6P1E0dh ! KWw3Zh5zaEgrtjbJcGGrO/4WZK076dcVZgBuCgCRZxZBmmzWX3Z/D29j8haMYQ/o82J1aXjP1MFf ! iW8bBUMMi8BX3hoAMAc2ayA8XAAjzWeNpgemzYv5YTwMhh1mK8U3qWPGU+xDHH9mdQ8MDdvGF2dH ! b65wkcm+5+roZCYW8zoVgNE+HSMALmIOaxnbCaZhNCEbZMBBomuuoAkMZNEDsDG6aRJyWGQjbMJa ! kgoWH2Pz8SUrkD9Qk2SPZYaQpiITfstW1nsRJw4XE9ZsWUJTbgAC7wi0QW+Uc3UInSRO/BKHCnQv ! fwuJrRa9V20iJxbaWEtQY31lHnugmW7ecm3DGcdtQR0L46lyBGP3pGajQKwYG8vGMb5Xeq4gZB/H ! TwVXr13C1Wo3bG1iZEwJnBFzJL8rcJ+1COWuPHZhbFAOLTsRwaI34yJxkl7tWZVeT2J5SprVglRS ! GJtS0mtbJ2NEF9fGWjvQAuEfQsR+nR4utbkbZWXwYz9OD5vDGOfxct4gPbbsbQ7dCmuXFxFj2LCG ! g3IZxehuC5wGc0fKa3R3bjK4AxFoNVpQaA4u64tkL2Lugp8ehlYmFa3NW29vzZidaCdIGGr2wmbC ! 9yNYeU1vbHM/rXBwTHN/DZCFsWWHYC9jXxhXwITadHlajyym605obHujYAdQA0S5N2uaMCAIG+e1 ! X8lydE5ifCkLZnDfDLpm9WWeZ3MRh2E4WjdpYS0xljW0YSGfcm0vW8KRHXAbbg/oC1ihLX5dxwOG ! zTZHqQkv4h2aaBmJSwVgZAHXNGdHUAAHEFRzH2yQk01SHwBwMEBkkKYbwB9QCmAFoQYZIKDwMsgg ! gz+AQODIIIMNBh9YGMggTTeQf1M7eEjTDDI40FERIIMMMmgosIMMMsgIiEjwDDbIIARUBxQMMljT ! VeN/K3QyyCCDNMgNyCCDDGQkqCCDDDIEhEQZbLLJ6J9cHxwZpGkGmFRTfBuEQQY82J8X/2SQQQZs ! LLiQQQYZDIxMQQYZZPgDUgYZZJASoyNyGWSQQTLEC2SQQQZiIqSQQQYZAoJCQQYZZOQHWgYZZJAa ! lEN6GWSQQTrUE2SQQQZqKrSQQQYZCopKQQYZZPQFVkEGaZoWwAAzBhlkkHY2zA8ZZJBBZiasZJBB ! BgaGRpBBBhnsCV5BBhlkHpxjBhlkkH4+3BsbZJDBH24uvA9kkMEGDh+OTgZhSBr8/1H/EUGGpEGD ! /3FBhmSQMcJhBhlkkCGiAYGGZJBBQeJZhmSQQRmSeYZkkEE50mkZZJBBKbIJZJBBBolJ8ja9QYZV ! FRf/AgEGGeRCdTXKBhlkSGUlqhlkkEEFhUUZZEgG6l0dGWRIBpp9PRlkSAbabS1kkEEGug2NZEgG ! GU36U2RIBhkTw3NkSAYZM8ZjkEEGGSOmA0gGGWSDQ+ZIBhlkWxuWSAYZZHs71kEGGWRrK7YGGWSQ ! C4tL9ggZZEhXF0gGGWR3N85BBhlkZyeuBhlkkAeHR+4GGWRIXx+eBhlkSH8/3gYZZEhvL77IYJNN ! n48fTyVDJTH+/8GSg8QMoeEoGUqGkdGhkqFksfEZSoaSyanpkqFkKJnZKhlKhrn5oWQoGcWlGUqG ! kuWV1ZKhZCi19UqGkqHNraFkKBntnRlKhpLdvf1kKBkqw6NKhpKh45OhZCgZ07OGkqGS88urZCgZ ! SuubSoaSodu7KBkqGfvHhpKhZKfnl2QoGUrXt5KhkqH3zygZSoav74aSoWSf37876RtK/38Fn1cH ! 7mm6x+8PEVsQ3zTL03QPBVkEVUE93dnTXUA/Aw9YAp17ms6vDyFcIJ8PCTTN8jRaCFaBwIMMcvZg ! fwKBGXLIySEYBwaHnBxyYWAEA8jJIScxMA2HWHJyDMGvQDfCUA/dZHkbtYy46GljWgJyqd5EpWXV ! 1HN1YnN2YtkKe2JlZCdLjSwWEnYeRxCXIoEjYXR54Urxks0UGx6WLRsYo7MoX8pS9j1jHwMBNE3T ! NAMHDx8/0zRP03//AQMHU9E0TQ8fP3/VKkoeiF0BRBBhgwMOCCJZKIinoGluLEsEclvJJ0WgCQAA ! 5y6Xy+UA3gDWAL0AhABC5XK5XAA5ADEAKQAYJ7+VywAQAAg/3v8ApWPuCMoWZAA3gblZ4e9eBgAF ! uoRN2f8X/zcP/pUFzM0GCAUX9iaTvQ837wYAfGXLUhc3/7a/M+fa7QampggMDgs+sHdhF6YGN/tS ! W72xu/9K+lJBQloFWVJaC1sXA3svtifvCxEGN263iOf2ICalABWvBRQQkd1WcdjGF/7umw/svSYF ! Bjf6QEr7UbCva7cxUTFaBQBaC1oXtYUdG1oFEEpvYL9ua826dQVUFW4UBWV1G4s194amEBY3Fwsd ! Fm/u7bkhEdldA0dARgFONtZtBRHNWG/6C/lAmHvdyG+6FV15ATczuDcAEuhGCx15kA8wb0ExWEhS ! WH3mmjsQBYUNC0r6UZFP/pTfFGVkECUQFqamWDdzv2R1FZUXCwoAb2aHHQZDdUgLRvYN2RcxBTFv ! YJ5giIKzFaY3rBDMzwtZFwXOeAzZFN/7CiNawxwzdwMLOhecERJ2BUJXT3r+uMO6YZMIvwu2BdQR ! smWfb/D8b9hLsnL+DQMGpIUdZgTJbxGy2QuWBwUDdzNC9l4L9zf5soW9YQcF5w+zYRdS7+5JB94s ! IXwF9lcP+7P33sI3udkHBdmbJYT6xw8hb2avxQj5agcFW8YwzgMVQ5tvuyzYAFVvRwVTypYxm2+B ! ks1Mp/IBa2kYF5j7dRbnbxETbNKwpuxabwVvLWsI+UdRMQBb9npJmm91bwNvsm2MEfNZAltvFtjD ! tBeb370C2PfNcibfDcImfIFvSfz5PQNCIjlZb1r6t032Hi8J+2mH9toGKZDf61LXEbSylPG/Lzd1 ! oM6Y8YcVgGllK6NVnzfxSM6dMfNaCwwPOq0kAm9mFlJ7SesLDPdLBiv7C/434gmiLEbYC4dRQ4AG ! AVEL+ow2F8BICXsBsn0b0UYUU3R3cLruIFFIAU0TIANhRtS9jj1zCSFy+aXohdFmNlB9lU9ANKj3 ! yUv/3ec2qILbaCUxVwd665pucz81ZA13bAEgBxs7c59RdBkPJS1vFZpuc5sFeQeFcgljbdd1n+uP ! dSl5LhNDL2kZmc11XWsLThV4Gyl077nPnS9uC111G1FHfcm6sUPBYxFsKzlpkC17gztoK/+33HRP ! 2C7sBAiw7x+DAP24bJeNgRwCAw5QBh1e0GY/U6PDD0x3Ya0DfQACQ6NTwpsZZyMUnwUvyUQgHyeH ! Q/e6bANj/095Azth0k0JmWEZaTc/YV03f3M5OmCACIFQv7BAbVBBtf3vk3mykRPvngBCdqybwr6D ! SWdECXKdF0L2EL95bYMDAUJGbpqhKWQA/oPCQSElB/Zn6ZjIWKtigWcjhbCkbnv33mlI7kltG0mL ! xma6y01yP3YFd/V9sc9NY1UlZ1sJeYmEJSNjZu9i3XsP53QPQw0sUyPpucvRQi0JlSukBUhtYabZ ! MA9LgE/269fQfbhtfQ1sB1+XcvN9VN1IZ3MBMyNQR1bFkBUxEwIiw9x0U4kIAOyDE2Uc2WM6XwMs ! IURIx3VGM8IlV0avaWhlIbBON3XVdPkMkLWSd9spSWCV0IJn4W6MB16N42R3dRdqnxuEY3lmDTV5 ! jRYgiCRaAFxOUFHEAFRQYlfFEjhHQWl2XRFbgy4Gb7VJkYDa7W50QRZEZQnL24r4dwxSZXN1bWVU ! aMZkMRbFbWRTbwJ0ecq7SUAvQ3xDY2XsfPtgEk1vZHVESGFuZGjhIlWsIRlFCchVoz9iATkHqA1F ! ihewwUhBSYx0oniO55AJ8c2GBa0lH1PLts9BjwxUIXAwdA6gYRGYDUYoXDNRZFVf27WPlYaAY2Fs ! Rkw6bHOVYv9mWzVuMoRBZGRy0QgDC/YfpfEV9oYwCwobEpMDIcg8VGltSC2K1mJA/0og2rGNiklp ! QSxMYXywCRGADwTgJF9oD0F0nyp1dGVzkRAUhKSV2N2EvxNsb3OBclVubYNlP7ddRBxEMp9Ub6lx ! gBjYR4m0VMweGhlzZ2JzM2IvzEV4QRAlEA7OHhUDABBRvWGx1gi8DzGRYsJc7DAM8xxPVAxYi85d ! RTjNNitSDobeJAxfaMkeKz15U2hlppouYRPFEzLrMAR3w3ZmbEZPYmoFqO/wFtACQ29saAqTMFvG ! T3XxJU1vofAQTgyNSULWQjus45hCQmuUZRpTTMZptn9pZEJydXNodvXcNB3fCo1V2wdfc25w6XSX ! 7e5wClxuY3D8X3YUXzfXNX4VaWOdCmNwxmxmR/hSewuZAXB0X2i+cjMUDVtzESl4X9xfL/bmXucP ! CV9mbYcL1jaCdT1tDYZqjCtbsAbQZq83DmWaKxQe9BvWEXnNFZ7bynQQHDzVELbmHhW1OYhubrTO ! BdQIoA5YrjC9mHt3K5ETK8wNVqhscl82C9zvzQ525M0IY2g3c+8VKi70B4ggO80mB2F0B3MPGL/T ! Nyhmig1mdJHOhr3ZbXERWFlmUXLuEENmxL1Jx641wUFRMShmY24Ue1W4B2o4Z7OztE5s8GxbBXOE ! X+NhSHFzFfdwY2OpbJgdaXMJYW1i9MOstVsGYXgNoZPn9oXIDWWkUadEbGdJZzJtWtZtWUtEQ/wW ! iwDkrfwSCrPZi3FSaCE1QkF6sGU7CUJveP6CCchtbnXj8TSiW5e1/ihUk25zUutmBj0Sq0VHFF2x ! Z7nQZ3lzkzhjMXMEdT9C9x2F02vW82aL6UJ3gEDhsmtXUDskCN0p2VOoMxB3NAIH2iydUQ3MNMlg ! YBpGxPz14AQXJ7BVcGQcgN7Mch2MRZpNOiBGGP5OoFkrxAgOuEVi9gXaA0wwjAmWOxEU5b6jjw8B ! CwEGHOisqJNAbFvEYGLRezE5CwOfBJpsyQcX0JY6YNnZDBAHshCQpflLlGQAAIywEq+w3QqnDAIe ! LnT2BfsMbItNkOsQRbGANhcgLnL9XLaE2bQOUwMCQO80u9cuJjzoMnAH2OM2ZSfAT3Ny3esqVva9 ! 8yeQTwDKCLtULGcYxgAAAAAAAAAJ/wAAYL4AsEAAjb4AYP//V4PN/+sQkJCQkJCQigZGiAdHAdt1 ! B4seg+78Edty7bgBAAAAAdt1B4seg+78EdsRwAHbc+91CYseg+78Edtz5DHJg+gDcg3B4AiKBkaD ! 8P90dInFAdt1B4seg+78EdsRyQHbdQeLHoPu/BHbEcl1IEEB23UHix6D7vwR2xHJAdtz73UJix6D ! 7vwR23Pkg8ECgf0A8///g9EBjRQvg/38dg+KAkKIB0dJdffpY////5CLAoPCBIkHg8cEg+kEd/EB ! z+lM////Xon3ubQAAACKB0cs6DwBd/eAPwF18osHil8EZsHoCMHAEIbEKfiA6+gB8IkHg8cFidji ! 2Y2+AMAAAIsHCcB0PItfBI2EMDDhAAAB81CDxwj/lrzhAACVigdHCMB03In5V0jyrlX/lsDhAAAJ ! wHQHiQODwwTr4f+WxOEAAGHpGGz//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAgAAACAAAIAFAAAAYAAAgAAA - AAAAAAAAAAAAAAAAAQBuAAAAOAAAgAAAAAAAAAAAAAAAAAAAAQAAAAAAUAAAADCxAAAICgAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAQAawAAAJAAAIBsAAAAuAAAgG0AAADgAACAbgAAAAgBAIAAAAAA - AAAAAAAAAAAAAAEACQQAAKgAAAA4uwAAoAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAkEAADQ - AAAA2LwAAGIBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAJBAAA+AAAAEC+AABaAgAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAEACQQAACABAACgwAAAXAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9PEA - ALzxAAAAAAAAAAAAAAAAAAAB8gAAzPEAAAAAAAAAAAAAAAAAAA7yAADU8QAAAAAAAAAAAAAAAAAA - G/IAANzxAAAAAAAAAAAAAAAAAAAl8gAA5PEAAAAAAAAAAAAAAAAAADDyAADs8QAAAAAAAAAAAAAA - AAAAAAAAAAAAAAA68gAASPIAAFjyAAAAAAAAZvIAAAAAAAB08gAAAAAAAITyAAAAAAAAjvIAAAAA - AACU8gAAAAAAAEtFUk5FTDMyLkRMTABBRFZBUEkzMi5kbGwAQ09NQ1RMMzIuZGxsAEdESTMyLmRs - bABNU1ZDUlQuZGxsAFVTRVIzMi5kbGwAAExvYWRMaWJyYXJ5QQAAR2V0UHJvY0FkZHJlc3MAAEV4 - aXRQcm9jZXNzAAAAUmVnQ2xvc2VLZXkAAABQcm9wZXJ0eVNoZWV0QQAAVGV4dE91dEEAAGV4aXQA - AEdldERDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --- 264,540 ---- /02qNMiNHC5g7rHIlv9zBNaocQuz39xfGvIm9APIK9gZt/yATXIIehAq3kKXQDgvWZFPinYQ7G/b +TMFBC91AkBLU/baGZaCN1/gOqEEMLjxeF186wPusmAkBNL/fWsHETuEyXQLOgPGAFxAde+bNdn6 ! ckAMD3QXyhTU2JnN9U7YSAZt4Nv0jb06wFdQFNRj2KBdDAyz5f9m0GoKmVn3+TPJaJRxUQCVzzlu ! Hmi8sgmVYK621GxTMFBG1xo1HdtuthQVSL7gjwRW9FlQcHerbVYPAR4dOBj/02gH1sHLx/gbYCMK ugPvawEV06ksXzytmTNnn57M8Pnu23Zv8sIQANq4AAYAPSzh5NiahU7plIEJEBq+uwO3VqwMAH0I ! VyEHR6F0o97taNg8WSUUPGhyImgBBABf07kPfaRVBuxQKpPM5kL7xwQkgKEMnwDwoHG9YXwWGug1 ! 5LwawW7/bmHoA0HWaECQFmj9DI63kc3goQAEX6xe6yd3rivw9IF4CDgBGV9+cB1fM9970XRc4CnV ! g/rZNtw9bKerQgh0dTlW9kai28skKahFoR1AhVu3/otQCo1IDgZRUt9RVkY0S/eeRKMwLAz8Xtgg ! DSf8EN7wsMO1CluE1yjWrMWtgUarBaLClvQRv/Vt4yvQK35SD/grVfBnUpkrwtEw22qn+O0VuMcN ! v9yIjIWsdYN8An4GuOiP7QodwMOuDggCDH0FuFochL+4E7gMEZ6LhBBbF3DhCyc7Tlcuot0Pu5sC ! vCQgE4stfy3CAPQrYbO9hUi20houKL7+UdvNVqBm7xS9wegQHoQaIhe6vifpzwsezhB2z35I1bsw ! okA6U2g2gFY2w0Ea27gLLbwWAWe6NkBGSIsZO7iJR9UnqnRSSMJohtu7+2AV60OLwxkpgD1jryBk ! /FqBUzXEe3RyJFt40blKFRwiB0QXz4fuvWoQaDQecLSAHewDWDC6GQax0wCAoPQiyIgn1dlSVtiu ! TqUoQeSyxW64vpiO9GjvAxoI8NLFwB1gmwsKoAKL4AqPNXbpDXZHMxRomXi7PsvZZstXkCRTXynk ! YbpBLopAQFiDjL1z56oUdFpQHolooHPdp9AHZKMEHP4bIO39Ntky3N0CdR//NSEFhxAzYyIMrkQQ ! e4Vme0wMUOtA6809Dawtlzuz8ptEoS0ajYOPBArwRkOgKIeIfAQXICHQLVARExhrrRes2yoEExwO ! CoJMx7MJRO3rS4Yswsf4kLo7i7SxM/9XV6dsmPUxaGRWQK91BKQRLi2r690DV2BW3E67HCWVtoHE ! EZccpbO7gZmdm/hTUBa22zPbdxkADFMEcxvjCCx6/BkYYN4HNkNtIUO4C1MA62yGZn5TUI1FmMc5 ! oyf4Smcrshzu9dyVDQ0dPOS8Q4tFvvHBLtA7wy90GDgY1I1NmFHObI/G8mKfNpxTsZ7NrVDsSP/k ! ctbinLVRexBkvwGr10uaZwvZ6Cn4/riz2dlaImLsxyBvsyVrqsY17PD9To2ZZWsAFvAMCBB3TUPs ! HxspcFk36GiaWBewYXT3GPzyXqzgHoQboFgSRstgQiYNvhYs08FHd+gYuGJc13T9Xi3xAmk9pmNq ! ZcxKlDddAgQATnJz2A4izoFo7BDkqWtwO04SqmGMDnIURnJYp6wBNevZlRYBg8kSIGhXZCuDyXRz ! UXQt94++bFyGQAg9Mex5Bs9Sjz2JYOsDSBqDsRA1U/q+ch8Sf8yJPUSiZYC4XwuQkUoVXB4LVtKx ! M1gcoBQS7GEy8ZpSkrud4C88R1eJu1NmpKNoIyAznPh+KUCgBcT1IDObbiq1AslygDk1rL2jcPgi ! vHdIdBJoRDraZw6Q5O7Whh7UoRkTaCiEi92sZxoFFV/h5hIzmBrOF5SOTmh/0ld1GQ8XaHh0D6w1 ! Lybr8Og6S3CeJjb92/iFVQWDyP/rclMhmGCr0m1v5Gh0QFQH0fgKSCfNSXP8NPAk9DNR6DQUHTKj ! W4lWd2jAhIkJPAL4rWXYdO70DxrHhxB5ZKsSblCcXltfTLzlUulQAaG2AFVoqxUSTtkQUhT+L3TH ! BtgEQev2D7fBweAQTWM8FnohBbtSNlO+Ghhm0Cn/UVW3r3XJEEEUyVGFPYSR438QiQAy1vfYG8CD ! 4PQ64O56wGOJ7/82/wUYjkAyFr90bR3/lMAdKdfZL750BCZM2C12byo0aIwsLBiYTW3LA08QHwIc ! CW7ZGIgseYvL5d4KV5R1hItS9fPCGwGe/VUA1Nzogc3WWxAQAPxVDK7U4UUqbTF2kRnZmUubhAEG ! 6QCbbm7L9nR7Al4hD4X+oWShPk+CswWZRPh0EQzhgKEVTl7nAlZs0iGTBvGHprVkp+7WLlf0EKgM ! TnD2OW6TUP4ng9mxchGcGWowGyA9nXRCGsButPRzdPY1gorchtwgZGA2A5zWatYNYJ0E3l8PR2jY ! H4B1NvgU7M8faHPrln19MFlIyITdZ+sbV8QklnK1h+owCIE4Ag/Dk3g/iQZjtEvEaZJGBAMiXtVq ! aQl8Mlbn5vjCrxUKdDWCTQhQUbwFOxuVhYMRRoyGVWSJNxWu5EJsF5wwkE8GiB0oa8DOTJSdK/A+ ! Ei5mk+5WNOAj/MFsvRbEuR6iMeLFjtyFPaGQvi7EK+wIdEmrFW50Q7ndN9oEAfpqI2jUM2g8BJUK ! bIM31hgGVDR4//6/BgcPlcFJg+ECQYvBo0Lrx8cFB2nXHhjVAexdw2oM6clMbyA8aEDoBl4dnSZO ! 6kAWHCvcWapEK8M1zyPkzHWuodZsHwrEyBsJQeNk5sQi69sqBxooZyIcZb/Ss4ThbEuIJx3ktjNY ! 5AR3DQBJbBpycGij09HKhIXZ90aAaA/TBYtI587c0HYROAVjKVTtGWaH+hdNRiwMc41YhhowEdTa ! XCx4SFNEP45FpFx9Thi8BTDeYZNQGRWwNcgJzCYw8WH3MIPEpSSkduUU1s4Km4T8UF5cUACMzc6e ! GIAAXRsTQyJlTzSMX6jCzoL9g33wAXUcPYx0wmjmgEYzOyCh2WzCJWSOGeEdqWEPGECJK1h2e8PM ! 8mr8FGQUaUCwATk4V2JL8kDYzyh2sCR2VEGLE5suPEbFZGlkm93NeOyNdG29w2xANf4DiXUD9j6A ! pRxAvugXqlYYVnZkplaieaOhTEaVDINWPCP2Tg41/GwFPMYLyXMYd/QRNqF7xVpEXLsktASx73Re ! dOrKWWeLJ0HJS5RHdWXSHrBEKI9wp1oIuSW/SHo0hFwYYI/8BHbTIXFd4XRUagtZERvdLvGNfcQs ! 86sG9Ikpqzb2oaWrAGjkDKsakBPcyMTbjBu/AAgXfcAwoBWF1okvL2M7sLC1LhzcHCTEG+KDW3vY ! dRYHBsxrJ9ZM51xg1U4rEmxcMtboIBdBGfRtk0tOnowc+G7nZtjOyyWfiY5cjDRm2hx0fJjBBZQs ! BbL9dsusjH+QIJt1tAK8Qvmg26gPpARhKNkNF8sorR0/xFsa4jVoo1FsvRnDpV7dgBRVu/88vsBi ! qbR76Lh3YdcYEGqEKs7cgd8+GHNzE0FVC9qyprmwKA6jC9ps2CcjPavUwSbbKKR7LVSdjLWITDIV ! 1aNDCekOwxSEuW4gzzdFCmgwonRbsma+kYBssmAZqvMBtlafIaLLFkTiNdAkVYOhOw5oteE2b1v6 ! X/GIwXgTgAcOmprc4itTABDgVoWhJd4aV3Rv5RCW9pfiPwBmg/8CdmFFdU6KSAFACP/y8vYwfEoE ! M34ebnQMcnU7QMYGDUTjW+xG6zMGAwpGT0+nT5pYwg1PUWJ8PApvhr9GNB9PiAbUBusFiLtCW/QO ! RkBPp5mha4AmlISxeqhvKMG58VE43ryoVivYAzYsHR/cmhVAAOTgAwB/0dcCOLFKiT/wbMJl4Kmd ! XL5MYGAz/MOF2LsAeO8i+FtdszUNJfRmdxcf9DCQMA9N1E8HsqtjdtjvU8h3Vkt02gyNjNBl1xE1 ! V6IUT40EC6KB1potRq64Yp3pCjlX4QoEBvhicEKiYQtgAuhtgHm2VaQEsVPN7YxsuHikfqD9TGSw ! E5F4CxFIVOwb62ytZO082ZmB9+xmO78wEDcRvWBuIzkUEhBFx3oGgh1oB6lqRAcjwQslqF5W7xIx ! zY3UAGNd1J5Om+1edRxQ4LdTU0QqOwO3cFNmTdg+qUOPtjvgY6Tn8YbWag8YoLMdqr0vCrANZL5t ! ZIvgYOwsyAjWh/DO5iwTXDUjU1avTxdMNGpb2CDuG7TQ2Nvbv0NqXVMNV6Vflvj/PIAnAEcsdZZo ! HSMJA4AXqQgHAYlDU6VEuslziTIEYAhpXZJDhkI9LcVGSo4ILToLvaR6SLt1Alahzwf/u5gORoM4 ! AX4QD74GajaUWarVnfvrEYsNkAkViwmK02An7diCCK/QVsBeT5KnyEB8dBRUY4NGjrIIwMuNsi2f ! +AL0CV388Du6bYIK7wlT79x5Jj2LVCFcU0TYCfcVesaSfh7EHko06meMGwisWTvDWf8wqekaOh+o ! U2kNk/pYAB/Iaih4cDtnpN37+3ULaJgiGR6Ci+xfTZpeootoqbOcxexHoihbHxdZvTxEKAwEAxWE ! NevZkAPBGggWGr6/sYQNQE7rxICkNUsAtygJ8VJBuYkEb3hr8I9BO02ECXwbgwqDwyhTNsfMAZWz ! JI3GYOJAZq2FVbFEk1zBM1wkdOhap7oX0S9SmEyMYddUpKdriP5oRCan2kwtrD+xQktuF4P4uk+O ! Hw9z3HddSzwCSvjxXx7/MFPOBZMRjYTXFBsbI9iLGNC2NFjWaih9+L07x3VFLhwduxv/8xLAcXiN ! NH7Yr61FgEKgwi9Sm9lcmZhaCI8x/AfkwCJeIHQaPgdyYHgIEBvNyAN7eaL060Mp9HjkwP4MCBr5 ! 6yAh4Ci0xw4HS2NZg+pLjRG5UKVr8/5+WAHtfWefBWQUEbPQoI2EkOz8erXANTMKX51/3AMCS254 ! +hTrGxZ4WPLNHxxosUAXDL5B9FQWakVdYRhVYhnVW1CZl04oXQUMnlnDV77A+yBWbQBWNHyM2OL/ ! VaBFIKRZo9qgA07G0w4IeiNOfWZLtOt7aD0eILHjF8IhHGCjaNMescG7EBc562GmKEqx9m2RBzks ! DDAOfQleQNMcbQc/SkcdrvEPH0B0HGoGc2e1MLhShSFZABJqYBRKqpESiMQZnSdfUaLnojUJlTPR ! CBQfMUaA4sArgwCzPbVmK01XEYBIgKudEvsMQROwVAcEhxs2LpYgSASI15YDiY1KhAgIRmCp3A83 ! i1UIGnFMvBXtDU4rQRACnyKBOUdt3AFIjTQQCMPB5iazfT56VjQSC7c4jK8A6v8WpU7y2Q2L1itW ! BCvRiRUbu1U7BitGoxC7V/4MLUn0W4CJASt+BJOxdGeJQpFR/JuIa1ZyZ1ZS6tIW2gY6O2GEP4Qb ! Np0gAK25dsgi8l+A3VuBCEgMdC4XV1BCfEGQM9PMrywMtzXrM2RFov8j2GBGzABOM9I7wlZ0/7L9 ! 7TOLSFHKdCyJUBQCCBiLcQz33hu72y/09lKD5t6JMYtAHCAUUUUoPCxVeAFgtS24BMM+A6IIkAAa ! gF9wbQ/2dDqLRv8zi25rFh0kLD0UDQrX8eaWXT82XAgeGihQUcDc0m3qJA3HAABUvlrwEehWCS/3 ! wi5ga4oBDZY6wYXDdqPM59oYOArciMWIvYPGO/d1Cj9Uht6avmQgiX4Y1QpgIOBHwrvy1vh+KDl+ ! JIoOJABIgWoYNkPgGmeEMyeJLzVJ14Y+/EydiXgU3+/+wotWF8+Jegx9DLT32cdADAF4+e2/7u0I ! fFkED39UH7gR0+CJShBS2v4vbNdRN9ob0lD30oHisEZlUr+GwH2EKLwZaEFPVjnfskPwehR1DxNu ! DhxPNusOngtWG8lfuPo8YckIaRBxU1WhXKryELoEBHbYbLvbCvkDoT4ACPCLVO+gN1EjiPoEv/ui ! lcNLvd8e2r8FweP7iVwZiQjIDQ+HxBUe3gEgJI0AOBkEtjvaRrM9iEkeiQ3lQYvxbXxrLwWLDooR ! HAQ1Fv2NUr8QBIPhD0K3LhZ0FccADZfMC85V3WwY3Hp466LYjdt3IotQEMHpKMEIXXYYJGsbmBzI ! 9iQeFwUr3DxfvQQRSDPJjmZxa/q2CEB2i14ciVEGib0fl3iL7QMTiXxDBMFsA8HF3Hv/9/WF0nQh ! xwNWlNHdt/HJ01+waPbBICWBYxEbdjYpByYcgutHy9h32ilsZaRCsO+taP11GKMCVfPboGCGWiyx ! ApKpzW5bIgFPaQJzoDMu0gJwjUjuUh4Ss61jc0RUDPkL2Aw5zJmXfOMILQJj5OOtuRft4UrcweEY ! SEu29lwL5Ek0CWLthq/4UFaDSEKJBjr+1hU2MdKQgUg34hADyolIIrlkwDkKvpJLhuQIC4TDjbnZ ! Nj85SDQSzRBhmTbr5TMCciCYWemYfsg2EKRoAnUJi8ecW7aDlMIIp2dyMgvt4GpjpBZQ4QF2Z0du ! xwEDORZIT1kabgk3igobUOFAjixv0T5WAgQhTCY5DtIglDDCDokosyHZLiSEH3hOMPMGsIxkr7j4 ! O2mbFQzTLIhwACXfVlg2agD9DEMBc0u2JCn9Bjgsu+0XCzc0TK4DpDbeLJtm2R03WKQlNZIsm2XT ! xwE2O9w36AeSwMtbf9MCh9uLV/h6PIlDdMXWNoAnBA8EBbDBG61SvutHKFKsVwO73jrKdQZ1DT5X ! UerbjXdkP/wox/IBRjQCMGwtCGwOOO5RCCDWhQn4dA5guNAfgWRtt2BHMMDD3/ydaxBfbWqaZGMg ! UOKLEsRP9t4Cxxdyxw1PKGigSaHAAdceGl/Zl4NZ6YJ6VyiMkPDbIvcYw3JA4lAo0zloDigfnytR ! EtbAuR4uojbeulUNAk8D2B6JXixiSMwWvDjIBA+97MVDqgCD7Js4GmgtulNvOFv7KUMBt9bYsmsS ! SC5LNGtbfHM4EDBWO8i2VAoVgGvLv0RzBSvBSOsFLAceOPhcvowDg/gJGQyFHEBQvNY3fhiD/QNz ! WD37huupwJYNxuRIig/HFLq//29MlIvRi83T4oPFCGML8kcxiVbtves4iS9yzusEN6+ffVML/AeL ! yNHotQF4iUsYd5H2LHDTY0SD7QMZAc0cDja9/wfB7gPT7ivpP7MprkFGFeqoSIBSHaDhE7vbjQ0w ! UQ44Us5HDCR2Hb2uXCE0+OBRDyxSdB8o8RDeEDgMFIn2nPkKrrXvXFhxcmAxMwZhFAPeusMb+P1Y ! FM4gcyxoOLcuqfr6oAY/TOCeyxYsT/Z8QCc1caHNAPLUkIvOguF/C7wrB3LqEDPRr6I47YvBIN3a ! 2zvF+gSJbFxLJgGLty0x7IkD6UzSF7wqtcMmOsccBYWdFnze1Q3fGkQ71nUjv4t7KJEZi9c7Fwrf ! NbEVcwcrwkhXZCvyoeuObXOJNXVntExBSAStcLhQ/VM0KL8Hm3VfbEcwatajTDoxnqNteCvKSf9L ! LAcEPg8y8t1VdSBi99byTovubJObzsKLyKResCw0DBMLBcl2NQ3dG53CO8EFwT4URHS/RKEwJIEC ! 86WLyi0cdofHL98DK9DzpNpcJUQDazfa9lINS10V8CsMFlowdKaJeBwpAWgIY9XmXWQYwgcq5EAe ! Y5YOczgyPmSMqw6S0iX/P7LF5uglyCCYH4cdd8dC3wbW0DzgCIH6oAWwdQU3E/IFZgV9Hzdnom9G ! jYQIAkB3A0go89k4S/lQYQyNBZo48cYOSA7HQ27wBKNp7G3rCK5xU5IIETxdaHQKg2Itc2hZMiZT ! ye++NAYDEh2RFiwITrGL/Gw/NsUYqksMxQSRYQhhrtAaCAOGamey98PucpgwuBOhyHMhPDS5wntt ! xzFpNaA3+tJ2uiBy33AaJG9DEI1TmjM0WFFSNFfx4wGcSp1yilFk28yuP/CFIfsI5gXw4SssT2XQ ! NOIfE29nwTc1Al0Pg3vS9+PRt1k76HMz40o7Betz77W1+vlKmPb0+ceaG0IH+i75zYu9g79LyTiO ! uRQjxuZUwQGNbTVoruY0drRVEFxru92XNHMbySvq0QxFhNvhGhYSinFApDcvcCMeX+h3ErnNdAMz ! 8oPoEs0vuUs8WSsk+AsfwAs7boE87OlzO5ngBB89GjmwMJ3pyeyNfneufHdViwyNqSPOJu+1WnsO ! FGLUkBsuI5wa1xUc4YwK9W79dB4D0Dsqh6l1o8RS7tMqORDpmbmYu1DwgpMVDdpvLxW+HYr86wIA ! qAxBSJmP/HUOJLSH9XeJXnqChaDbXiaYFUAkJlGxGTN9UECN3wksJFH4a7jWElI8Njs/UUIFZKOA ! CXJrzxSHedZAZQkHQAYPaXqcZUV8JB8VTNlHkzskChkIJTTP72nAtXc9nzwgK9wxBLYceVCkToRX ! BGBbyPIEBilIrYUFHg9zXms8MJe61cUW2ATQK504A9UcvPhWTOjOTejU16Du51FMSUQzz9axe0B0 ! Vhcvzq5dtlQAHSeDROEBTT4NIxgTh4IzsSnMIfO1EkgYidIAMJdkAywAoZ1tvbZxz4smaJqW2um0 ! 5l7blUxRd4XaF7C3Qy4JkKEzBjDD2ji0YeBRXGH93KzxZsszGFh7P1VRYD/89vLk12r9K9HDA+pQ ! TtuTXclLTI0xi2k5UYTNNSzQKwFmkuovlkC2WxVSUTpDhd6yb20yasdBGDiDS5j7sdZGQEhIUYl5 ! BEZEcOAIQxgRSyDoIrhGm7Os8oSnwN4gzIQVUsjGARfvkVTKxABCJz6fzjlBBJOKz+Degtf3A+6D ! UU/BlEBw0Vi4RRAWDC0Tn8+eKIRA+Gr8UJR58A4paZAUjM8EUiChK44YRtnsjZ39dQZbpQy2yB5P ! Uag61xkRknUiaJQUfFUZI2yeu3Dgsq6RUt1QBt5ANoM1z/h62lghk+D+gf3pXAiGXyRMEEg4YAvs ! GFKEYY9QFj4JO1ZK3khcSFBSpuH1es8HDECmZueynNDdQVBWU3RLUwht7j3RdDehe+ggN5Yqf/su ! iVYEf1Ar1YtuCONugHwr2X0+Zgh8j4xxGDFDLovHTFZsDVotVcVjQ0tWpJdCmpk7nUJAOoSYoJdJ ! YAhhDRiR+2pCkFNPsP5Fp7DXWENIKkP/xLncNoA5yDoDMDtbPC6XzXIKPfFAQOdETkU2zbJZkig6 ! RqgpQXBJMQMb7wwDXIAMoqRWVxjhSlGAR1hpRrkAT92LWEYoGDjA+b0NGAhXY9VYYAfpT7cDbsQg ! u+/ddQrs3sUCPcIMxlz52w+G7+L3ju8RVYH7sBWZw3IFuAgr2NGKP+6CD4yhrejB7du7KMRvYRCK ! FoPGG6xW8RxyyNkD+Qjy8/RyyCGH9fb3yCGHHPj5+iGHHHL7/P0NtnPI/v8DTbw6A1WCZJ9JFRa7 ! lXrbEkYTSHX0sQ258fK23bex9/FMvwiLNff364tEbN2t9YcTMV0XW8ckOLw4XwvBCJ+VQiib4AhQ ! bk3GUO/SQN0fCHRMBMMPtKQaHR8coTddoUZTpYpPo0WIvRF4x1AQWgyISBF1AABwGHAHD0gYw98U ! hhZe8X8gds4DRgSNBROS8FbIC5uLttpuDMEMNMF+n6YJV8W8EMJGLKBAH2wHiTNNOtr4FTff/gZs ! 2E9PPY5ACx0cGp3OEAoPRs7aCpJsKEZ6sJWr5SyJfjuMKStqWy0tInut+YWJBui2tFRl3FUKRZRW ! Uh0DNuwiTRFPVRB3SGytZHZP6sijfhy4SBW4znSdKA1ArhoNZKyfozByG8R/gjETSffZG8nMg8/9 ! YqvB701hOI1mY2KpVqIQvhK2RcPqrbGyRVj4c0RAi+dixVwEug617XsBXrEwALKOz9Pg0P2c+5IA ! xwgLyDZ54CxB39norj8KLHK8roX4IwRjS3UgCFbISRhGePQrKxTT6Lhuwd6CS79FK/hAigHFFotJ ! zDRbJI+VCAavSnQ3eqgQdLvgD66Lr22SLtYFIh8CQK8O2qK6RcOo7+Mn0rkhZx8HgtpC7L3PHBqv ! SNx50CP5hgXn2Ai9b+bkvosETLlNBAPIzjNda62tkbDUcgPXzbWoNtN+9UU5JBgMzGVelgOEJYwi ! RGTDAWmYDEQEhfBSEISbBWUMjQzBiIYAeYBB2AIMDOSQQwwFgEMBCm9+A3o34NhrFdV1A8IrN+05 ! U5NA1h/tI1ENrxCWsVoBPlXi+dOFlywtjnUh1KC02T4wO8ERVLA9OKktKQz7COsbceqID39nhhRS ! MtIkSoVyYjwGkiEzDG1ikBvs5F1jYSJeIW6J7I9intsBkPf3SRhC8wmISv8RQUg7UDqe+wS6FHUH ! TgxmSWkwsDlhzyg3sACoQIEN47D3yfjgTQqICkJIRL0n4Iow9s8Ui8foloErCuLHQx8rzciagQIT ! FxGqZrqTRPQUw0oJMOANEPgYIHxAYlCYG+RHZWr9K81TVlBJhco2VwjrtJhDWXmQiokDPoNXgr/3 ! /wd2FT88g+8IkUwsoTO8iUw3ULYLWnUoi7LqYkxv7JizTiA6K21u0Bv8pTz5Uyv9i2tk74kLhEcj ! rFv+EkGRLZKJATu36kUy/pCkvmFJzbJZbgM8SsB+S/QSgFkut00H505fTx1FkK8M3/kMoXjokSBR ! U2wg/YNEp2MTdhBn2I+OVTfbdQmhW1l1XRfAjxyyVlVJjbpTrgXcQOsgUlWpAWWiX5QThUDMov8S ! bbXT/jcaW1NSx0cYbI27FCdqilc0XV5M3Ubx2x77dAaDfZ4MH0hhMRc1vsIwKft7wmLPgezwoowk ! 9Ab9IHaV/LQk9u1X0zTdAs9EA0hMUE3TNE1UWFxgZGg3TdM0bHB0eHyJrMQGuYAkdTIBl95+oe9+ ! XIREjUQDQ0qJuu055au7QAh1H3EYgZS8CNF/bsCJKYkqQ49TX4wtGpwXuRGNmMAXNtA7QzkoPUGD ! wAR82qAbJnbzdvnNcwY/9t14mmK6Dyu0eDkudQhKbRc3+oPuBDvVBTv6pSx2Jf+Nf5tU+r5RiTvT ! 5q9zEo1cjEQrM2iD3dt4JVPDBNERcvJvla1wM0SjhRwMRI0Dm1Ev0CvxukB5EBGibfB1JwPO5Ygs ! C/ZK/W7ub4cz2wNMHEhJ5YwcF3XvvmIswt1Di7TNw62Rgf8cFYyEHB3rArY9KHiMDYlc01B4vHhC ! iRESexwI7HZHfEM72XLFV4vf90KMFDWB02xklIkhXQPR90xDcSQeYcffTudMDgASxB08D4+BotD4 ! iAIzNGWH9wIPRQ25CjtJhdLsvW1ugSs+IP07TQ+OB2aRg+1gFDjWLP9fsOQt+Gy6OAPfK9NFA887 ! W6JnotfwJhrXHD8J6KggScu4jX0BO7BEM/3HdieDz//3Gi3HsLCA224YQQSufb7FpWh3t23gHwcr ! xxJy7dC+bMeWJL8754uxfAP4gf+csZGjiNjvJiCDvZ8+KyzCL42UhNg2iU/dONA4i7k/dDhDiP0i ! wq5MoLSELNbLiNdLNLEFMb3G14tK/O8L32rhi/XTwUMr8IkUO3Tee7obn+sJShgo4PCO0BUbBo// ! WoxuitD4dNsbCRwq04g9MYsIDJHdxgbef3IHxg7A6583KQz8R98Vk/FzFIH+yRvSg+Kgm67sLvZg ! iHHrICAUweZbOyD3AooUMQxygMJLNNFyW7wxIbEE9g6tjSx8hyRHuuK8tKK7sIk7FXMet8UAgzDO ! cIzfd4k5jTzVpHEEhh3KxAjdcubVFHqNwsLtv+AxgYXCdAgz0NHoB3X4WNBwaC1KDihgjNoHo40c ! jQUxJE8j+suPct8VOl8Yg+gET4gmxLEu2CvfOTMII3XcHZ4Y43UVyEogKx8PU0PSwhxSkEAbr04f ! 68GaHk6Rrr5hehtC1zv1dBeRay1k6SwBdE37AQxhEXABCiQPB1oJgV+jYSANPJY4aBJkGHAC7wwL ! X2Y0Hidp4FVkGDRS09wF4q3YaBhj2phiBKglsIMVVVJwcYEZN2+F00U+OAAmGywWRkwoSDid24l2 ! exZMEGTvgb3RUVYeqFJRS3UkJwbg99aDOhYIgf1qdxM/CbwlAB2r5GFLNstPURiOHmwIHPL7dR/8 ! 4yNsyAeP/HQC2C8ZMBhZI0u0BAYT2EKURQWSBLMjD99uEO3FDUD83gahRFPuAvAKnIkCEJQHPHx3 ! xwFIEccCSIxAyFHtYAM2Tgxja9d7j1NbDcB2/cF3ut5o23YDFSwRe+876FjosHWYCCcyIPcIW4k/ ! 0uogVhQrxQPV5jBW8UuwUJY4cA6LSzxVTcCNCgU2QzwSzUdMqseL96SmWfhXLtXKpgPFF0ssA/23 ! VW3nogp1fkFEKA270y06kXUfczTqmivunFxhC58QhFdH6yAHsldWRzB8a7GFGs1e+IR7gi8K9l7k ! jIphqguGU1ooVIlRL1jCV3I1GF4f7cahF8xZ+YtpnDdq4cJRIDtxMDc4HTvuofqHY1FBHDlzCSv1 ! Ti1etVSXzkkxzYFpugnlNrQOHCxEc4kvIIP4PCKLSSW2OupBEYulyBq93VsB1wvWRx1y4ljxN3iL ! olcwI8rIihzOjTTOgHeOGyyEjsIyTgHT6rQuAlcEZ7c5BAf4wQK+I2sMnWAAObDbXgQ2A8s4VQJd ! sH90x4PjDyvDNDFODRPJ1r6ryyOkDw+yJc0kIDScbIQcmTEFAZQ9AG+mzzvDcytZGM8BzYWD+efV ! h2yJr9rXQSaXcgc8WdEateVO+s9wwQFXlM3ux/VI1xtcCEKUvEkoETsP9u/g93IXi/dFig5GiE3/ ! BoPrAh1rRIPrAesncSx/awW+HzvfdhOLHRwARUZPdfbtzGBnGCgQS57rGZ6f25K/BgQZcEVJgSN2 ! RIFhEnI6Dp2jdvVyM/lIyLWcEPGrQm1JBBN0K/P4Qr3NPqzwsq078w+C3OSdiwctS8eLdNnH3i7Q ! xWXB6x7ZcwLeOCtjrF6g+TONFM2awsTEJRhjHPoWU0YIuULhHerPiT4rZ1YNF07NKlbpc2IgdGZF ! CrBWV88HyIXNWtsgciYj32s/EGb+9WvbWamIaAMrQVhA9xIbdIsxQTl3X4lBZ256p4Oa/Waf/yU4 ! yMjWKIMFPESv6M3ISEzMzFE92d+3sBULcofpCy0EheLWxbEBF3PsmMQMi+Ezst1UYM9Qw8w9UFz5 ! wZcKS2r/aIhTAF6tt9R3ZKGhUHQlBxjl/0vFaFOrZegz24ld/GoC/xX4Yjub+1mDDXijPwZ8FPye ! 29OOug2o8QgNAGGkrnB/R6EEDACjgCjrW/nuUpgdgBh1DGjuXU4In+3+mWEY2GgMcIIIcCfSoaAl ! qoF6P/mUZopmu7mcDAmcUAOQoOTriJZiEPsEMgCo7wIwTqEUbjBtf/c3y4A+InU6RgiKBjrDdAQ8 ! DfJs2wPyEgQgdvLU0E6kVW1x17DB9kXQMxFF/7y97dTrDisgdtjr9WoKWJOKpaKV8WiQ8Osa1B/h ! lzMYa0XsXByB3lQJiU2Iy8xZCrERthcu/3WIHyBjJAW9saKRHAyeAwQVNsyuLC9OAqzDks89t4QA ! L/Rg8AUPVKmqsgAA3Wu6zVMAEAMREgwDCDRN0zQHCQYKBdM0TdMLBAwDDQ/SNF0CPw4BDyBpbm// ! b/9mbGF0ZSAxLgEzIENvcHlyaWdodA85OTXe7P+7LQQ4IE1hcmsgQWRsZXIgS1d77733Y297g397 ! dzTd995rX6cTsxcb0zRN0x8jKzM7TdM0TUNTY3ODoxHW0zTD4wH4MiRDdgEDAgNDMiRDBAUAS7bs ! NHBfRy/d95Ywf/fzGT8hNE3TNDFBYYHB0zS77kCBAwECAwRN0zRNBggMEBggVljTNDBAYOclHNnI ! 18cGp0uYkISrr7PIIIN8AwsMDbQmGiD2qqe+A7JUVRmBBsv/oIpDcmVhdGVEaWP+/4n/dG9yeSAo ! JXMpj01hcFZpZXdPZkZpbGV792bBFSsQHXBpbmcXPwFmKRD6RW5kICyY+28ZdHVybnMgJWRTFxQG ! 9oMlE0luaXQyGAzSxQM2HFyM6wgoFW2ehAcsm8EGfA90aHFgPDlggwAvTHFMcfu3f5VTb2Z0d2GA ! XE1pY3Jvcw3/1v62XFebZG93c1xDkxdudFZlcnNp1t5++W9uXFVuc3RhbGxXaWJcErxb7N3/LXBh ! Y2thZ2VzrERBVEFPRWm3/+/ecHQRC0NSSVBUUwBIRUFERVIHUEx/+3n5QVRMSUJVUkVUaW07IFJv ! bWFuF9rWbgtoaQp5eoo8d2mtFYJtZCBsExZ87bfb7SB5b4wgYylwdXZyLiBDbK1szRX+ayBOZXh0 ! IL0XpS51vbdWKGDIGUtjZWwVYA1btxxpHWgVU11wWwqtfcAuf3kWMmxgY83dAS5kzo8PIOizuxHc ! IBa2AEtub3SJdtisfSdOVCoSYXZ4zVC6m2bxEmzBXmNrymfIdFBoV23H7pB2cx1xdXJkLOPCXttu ! 72NoBWETYkKDzZaQn0wGQ2w7u7lvEU9cSYdQiGhvYckuuVYoWFTB4BLZKVPzY37CQ8dH42bXc0gu ! L4scYe1vLgAbY4kXwls2HBSlYrWEMHOB4D2Lr+FwwajRSWbjEG4srXAwda52hdAlEliMt7VnMwR5 ! KgdAWNstXHPedHZzLCpvgDEMx0KUIQ2335Yxdwf3U3lzX0c/T2JrNHauagYPX0+7lCFd6LZS1Fxn ! D1I9X1P7ucK2EHDQUztkM19GCKWO51p8IwtbUDY9PUP7Z3JhbU4CPhPTaTDj8O8hD0xvYWQUc9vc ! u40qAO8lY39Y4HQaDVjDo1/ZNTsLLvyw7ZoHWnInMCe3MTAwGLraRjxkErY6NbzcBhdngAAyF4Va ! abBHbRhFu1uZdkzmHxtPhndytRvWnJsg2ekWJx6HUDgkKV3HP9Har7AAG3M/Cgr8BmHbP7wIWUVT ! Y0FMV0FZCW8urb9jDywKcC1OTyxORVYTY61PZStDQU5DK1xTDDcKhkv3Sxdkdfvi0ZadHZf3ChqE ! ZDnvpbAild/hbiVSZW1nZWV4ZSIgLYVjje0UAi0KLC5swOEha78i53diAy4AMDQ/YSvdWhCVREJX ! VXU9WhO2rVsZXQI9fvcmRbjRtR1hef1HJ9kMsz9kOzJLZUa66bB5OQpHdWxk92PBvXYMQSBrHUuS ! vwG3bFZ9I9uEDULHWSFT/GO/KtsSUqkAMwYKckrP/fddd1kvJW0vgEg6JU0gJ6fMpewUM/UTRyyF ! 7aZmHnNoSCvWJhkuYatL/hZ1J/3aZBVmAG4KAJFnpMmCtRZf/w9vY2/BGBYP6PNidWn3TE0sXxlv ! GwVDsAh8hd4aAMQHswbCw1wAI93oemBqZ927CWFg2GHWPCvFN2Y8xc7ZQxx/ZnXQsG08DxdnR2+u ! cOx7rs6R6GQ2FvM6FRjt05EjAC5iDmuxnWAKYTQhG2QsuuaawLAJDGRh9nGgFc39WGQjWEtyAAoW ! H2QFkk1j809QzBAyvpNkpiITynrvsX4RJw6aLWvZF0JTHYF2wm4AQW+kc3WJX0LgCK2HCnTDsdWC ! xRO9V21CG2shtktQY3000+3EZbLecm3DGWE8dQ/XbUFyBGP3iBWjY6RmG8sm0XIU1jEFM3C175XH ! TwVXajfE3Gu3AG1iZEwkv7lrAmcrcJ88dmFsRHAtQlAOojdXe8tedyJZlV61YJykT2J5VFLalpJm ! GJsnY0QOtJT0F9cC4UutsdYfQsR+uRtl5nCnh2XwYz8Y5/Gbg9PDct4gPe0Ka6yhLXuXFxGDchmn ! wRg2xehzR0CE2wLKa3R3bmjLugzuNVpQi2QvoRWag2L+giYVrSfap4fNW29vJ1iZcDNmGGr3MxyT ! vbBYeU1vbHM/c38hWCscDZCFL2OjdmzZXxh0eVpXM9oUMLz8e2u9pum68AfgA9TAsBc5utybG+e1 ! TmJ8Bt2vZCkLZmb1ZZ4cLbhvZ3MRN2mR2rDDMC0xIZ/IDssacm0vcBvQli3hbg/ofpujBaxdxwOp ! CS+MRMNm4h3bBbMjTbRg9AFQAAfJpmuaEFRzH1IfANMNNshwMEDAH1CDDDJICmAgoJDBglGAP4DB ! BhlkQOAGH6YbZJBYGJB/UwYZZJA7eDjQBhmkaVERaCgZZJBBsAiIZJBBBkjwBKxpBhtUBxRV43+Q ! QQYZK3Q0QQYZZMgNZAYZZJAkqASE2WSQQUTonzSDDDZcHxyYVCCDDNJTfDwggw3C2J8X/2yDDDLI ! LLgMjAwyyCBM+AMyyCCDUhKjyCCDDCNyMiCDDDLEC2KDDDLIIqQCggwyyCBC5AcyyCCDWhqUyCCD ! DEN6OiCDDDLUE2qDDDLIKrQKigwyyCBK9AU0zSCDVhbAADLIIIMzdjbIIIMMzA9mIIMMMiasBoMM ! MsiGRuwJDDLIIF4enDLIIINjfj7IYIMM3BsfbmCDDTIuvA8OHyQNMsiOTvz/0iCDMFH/EYP/Msgg ! Q3ExwjLIIENhIaLIIIMMAYFByCBDMuJZGcggQzKSeTnIIEMy0mkpIIMMMrIJiSBDMshJ8lVyIZve ! FRf/AgF1MiSDDDXKZcgggwwlqgUkgwwyhUXqJIMMMl0dmiSDDDJ9PdoggwwybS26gwwyyA2NTfqD ! DDIkUxPDgwwyJHMzxoMMMiRjI6YMMsggA4NDDDIkg+ZbGwwyJIOWezsMMiSD1msrMsggg7YLizIk ! gwxL9lcMMoQMF3c3DDIkg85nJzLIIIOuB4cyJIMMR+5fMiSDDB+efzYkgww/3m8fyWaDDC++D5+S ! GGSwjx9P/v9KhpKhwaGhZCgZ4ZFQ8gSS0bFDyVDJ8cmpMpQMJemZJUPJUNm5lAyVDPnFQ8lQMqXl ! lTKUDCXVtclQyVD1zZQMJUOt7UPJUDKd3b0MlQwl/cPJUDKUo+OUDCVDk9NQyVAys/MMJUPJy6vr ! yVAylJvblQwlQ7v7UDKUDMenDCVDyeeX18lQMpS39yVDyVDPr1AylAzvnw0lQ8nfv//d4530fwWf ! VwfvDxFpOvc0WxDfDwVZ7Gma5QRVQV1AP03nnu4DD1gCrw8hXHmazj0gnw8JWgg5e5pmVoHAYH8C ! 5JBBBoEZGA45OeQHBmFgkJNDTgQDMTk55OQwDQzBYahDLK8PRlygG91keehpY1qi0o1aEnJl1YW9 ! VW/Uc3VicwpiZWQnCwmxbEt2HpHARhZHI3hJiEthdHnNFA2McKUbHqMpe8uWsyg9Y2maL2UfAwED ! B6dpmqYPHz9//5qmaZoBAwcPHz8IhKFof+/sLFBFyQEDISECKDTNQQEobiwp+fsRuwQAAKAJALlc ! Lpf/AOcA3gDWAL2Xy+VyAIQAQgA5ADEAKVu5XC4AGAAQAAg/3mxBdvL/AKVj7gA3mxWOoO9eBgDY ! lB2YBf8X/zfA3KxLD/4GCAUy2VtZFw8377YsZW8GABc3rt3OV/+2vwampggMexc2cw4LF6YGN7v7 ! 7wP7UltK+lJBQloFWVJaC/di2xtbFyfvCxEGiXg+sDf2ICalcG0V53YVrwUUEEjGwN4b2Rf+7iYF ! Bje6drv5+kBK+1ExUTFaBQBa2LEB+wtaF1oFEEpvttZcW2C6dQVUFVhz/+tuFAVldYamEBY3Fwue ! G7KxHRZvEdldY93m3gNHQEYBBRHNWG/6143sZAv5QG+6FV2De4O5eQEAEuhG+QBzMwsdb0ExWK65 ! kwdIUlgQBYUN5E/ZZwtK+lHfFGVkECUQM/cb+RampmR1FZUXC9hhgHUKAG9Ddd+QbXZICxcxBTEJ ! Lmhkb/KzCsEM5hWmzwtZx5B9wxcFFN/7CjFz54wjWgMLIWE3zDoXBUJXT6wbxhl6/pMIvwshW4Y7 ! tgWfb70kSx3w/HL+Ddhh9oYDBgTJb71gSVoRBwVk7yWbA3cL9zfYGzYj+QcF53YhJVsP7+5JEsI3 ! GwcF9lfvLezND/s3udlZQjh7BwX6xw9ajJC9IW/5agzjbPYHBQMVQ4INsGWbb1VsGbPLb0cFm2/M ! dDqlgfIBa4G5L9lpdRbnbw1rinERE+xab4aQzyYFb0dRMQCXpNmyW291b8YYYa8Db/NZPUwr2wJb ! bxebgH1vgd/NcibfwhfYKw1vSfz5PZKTJWwDb1r67/EiJLcJ+2mQAtlkh/bf60sZr21S1xG/Lzfo ! jEkr8YcVtjJar/BVnzfcGZNW8fNaC0oigOQMD2+1l6TTZusLDLCybyH3C/43YoS9ZOIJC6xiIMqH ! AcHPaAc1h8BICXsBLUSRoLLtw3QOBrUQ53C4AU3d66jrEyADYT1zCSFyXhhtRGlmNlB9RINaigX3 ! OW6D+gFM/4JLaCXpNtd9MVcHej81ZA13M/e5rmwBIAdRdBkPNre5sSUtbxUFeQeFcve5rukJY22P ! dSl5LhNc13VdQy9pGWsLThV4G/vcmdkpdC9uC111G6wb+55RR0PBYxFsK7I32Jc5aTtoK//3hA3Z ! ty7sBAiw73bZyE0fgwD9gRwCAwVthssOUAY/U6MX1trhMw8DfQACvJnBdEOjZyMUDwQyJZ8IwQAM ! 3eu+JCdsA2P/T3k3JRwOAzuZYRl13YRJaTd/czk6tUX9hGCACIFQv2G1yUbCAm3vE+8J+07miQA3 ! doNQdWQPwbpEZXKRs3lh5KZ5IXcDAaEYagD+yFkqZIOnnQzIU8jwngBCSdEqSyEPs+Fn9x0lQgEH ! ADJvAgSAAEZhPoLxFA1veaEugUJa9gE1p3eQlOT2AB9LYg8UxpJeZ6shG6chuaeXSW276ZvpLnuL ! TXI/dgV3xT43SZVjVSVnWzKWjPUJeQNmj3XvfSSHdA9DDSys5y6LU9FCLQk1sBZgjQ0Bc9M8rEuA ! nQ4A62voPlxtfQVsB1+XcvM+qm6kZ3MBMzNQSCNjyBUxKSMtMlwz9uxTeyMR0pFjOgtfZCCQIwP3 ! MGMIIVf/4HRjfB1oZXXVdMBKhkCZd5XQDJB7KYJngwPJYIEtg05w3dO3c4ljAXlmCIPa5w01eY2C ! EIAFCgBswOVExABUUJhHFSg2VbFpdp7d3hWxBm8lSW50QRZEZX8XCagJywxSZXN1bWVURratiGg2 ! ZDFTb/RiUdwCdHk6Qw+2mwQcQ2NlEk1vZMXKzrd1REhhbmRoXBUuRpEZE3NQlIBDGA0bLBaQRUhB ! SeeoeAGMV5BYQA+Kea0MFN9sJR9T/xq2bPsMVCFwMBEHRecAGA1G1FiDwjVVX/aAtrVd+2NhbEZM ! OmxzlTVuMmAv9m+EQWRkctEfpbOAMLDxFQrMY28IGxKTVGltLTYQgkhA/6hYomhKkEmroh1b2UEs ! TGF8f/YAmxAE4EF0n0FI8oUqdXRlc6T4GwlBlRNsb3Pbhd1NgXJVbm2DRBxEgV32czKfVG+pR4mh ! EAeIJHlz9kLF7GdiPEV4QRAxMDcjJRAOa+3sUHAQUQi8D8XeGxYxkTAMtSgmzPMcTz6zFsWAXUXC ! DpaM02yG3iQeKzbB8IU9eVNoZabFE7qn6RIy6zBTlmOgCTOA1KiM3+ElgkNvbGgKT3XxnCZhtiVN ! bwwxQ+EhjUlC1kJC/3ZYx0JrlGUaU0xpZEJydXNoGo3TbHb13DRV4Tq+FdsHX3NucOl0Cvwu291c ! bmNw/F92FF8VaWP2bq5rnQpjcMZsZguZ5o7wpQFwdF9ovnIzESm9KBq2eF/cX1frXuzNDwlfZm2H ! Cz1tDaCtbQSGaowrZjy2YA0fNw5l9Lc1Vygb1hF5ynQQKporPBw81RCobc09JTmIbm4I92idCyAO ! WK53K0VhejGREysdmBus3HJfNgt2Ubjfm+TNCGNoNw7m3mue9AeIIGF0b3aaTQdzDyizMX6nZooN ! ZnSRbXEhnA17EVhZZkOCo+TcZsS9SUFRcI9dazEoZmNuB2kpdqraOE5s8MPOZmdsWwVzSDsIv8Zx ! cxX3cGNjaXMJt1LZMGFtYvQGYXgbhllrDaGT52WkrO0LkVGnRGxnSWdtWchl2rRLREP8reMsFgFs ! EgpSaLNgDxYrQm94LkK1RsJmT0iMfbWCCcjjYTT+BqJblxtUk25zPblS62YSq0U6FNB1XbFnZ3lz ! kzhjP0LWMXMEdx3zZouyhdNr6UJ3a1fZgEDhUDskU5ssCN0pMxB3NJ1gAgfaUQ3MATTJYBpGxMz8 ! 9eCHJ7BVcGRyOrwq3h38ICtFmk1GGP7ECNhOoFkOGEUDTKFi9q2QVhq+OxH/kxTlvg8BCwEGHEBs ! EeisqFzEYJnJItF7CwP/B9msmGwX0PYMeNkb2BAHBgCUZFggzoL/sPcSbLcCJIqnDAIewT7DKy50 ! bItOkKDNhX3rEEUgLnItYXYsbbQOUwPN7jWXAkAuJjyEM3C4Tdk7ByfAT3NylQ029t3rsCeQT4Dy ! vLUpJCxnAMYAAAAAAABAAv8AAABgvgCwQACNvgBg//9Xg83/6xCQkJCQkJCKBkaIB0cB23UHix6D ! 7vwR23LtuAEAAAAB23UHix6D7vwR2xHAAdtz73UJix6D7vwR23PkMcmD6ANyDcHgCIoGRoPw/3R0 ! icUB23UHix6D7vwR2xHJAdt1B4seg+78EdsRyXUgQQHbdQeLHoPu/BHbEckB23PvdQmLHoPu/BHb ! c+SDwQKB/QDz//+D0QGNFC+D/fx2D4oCQogHR0l19+lj////kIsCg8IEiQeDxwSD6QR38QHP6Uz/ ! //9eife5uwAAAIoHRyzoPAF394A/AXXyiweKXwRmwegIwcAQhsQp+IDr6AHwiQeDxwWJ2OLZjb4A ! wAAAiwcJwHQ8i18EjYQwMPEAAAHzUIPHCP+WvPEAAJWKB0cIwHTciflXSPKuVf+WwPEAAAnAdAeJ ! A4PDBOvh/5bE8QAAYek4bP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA *************** *** 551,555 **** AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAAAAAA """ --- 542,564 ---- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgACAAAAIAAAgAUAAABgAACAAAAA ! AAAAAAAAAAAAAAABAG4AAAA4AACAAAAAAAAAAAAAAAAAAAABAAAAAABQAAAAMLEAAAgKAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAABABrAAAAkAAAgGwAAAC4AACAbQAAAOAAAIBuAAAACAEAgAAAAAAA ! AAAAAAAAAAAAAQAJBAAAqAAAADi7AACgAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEACQQAANAA ! AADYvAAABAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAkEAAD4AAAA4L4AAFoCAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAQAJBAAAIAEAAEDBAABcAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAD0AQEA ! vAEBAAAAAAAAAAAAAAAAAAECAQDMAQEAAAAAAAAAAAAAAAAADgIBANQBAQAAAAAAAAAAAAAAAAAb ! AgEA3AEBAAAAAAAAAAAAAAAAACUCAQDkAQEAAAAAAAAAAAAAAAAAMAIBAOwBAQAAAAAAAAAAAAAA ! AAAAAAAAAAAAADoCAQBIAgEAWAIBAAAAAABmAgEAAAAAAHQCAQAAAAAAhAIBAAAAAACOAgEAAAAA ! AJQCAQAAAAAAS0VSTkVMMzIuRExMAEFEVkFQSTMyLmRsbABDT01DVEwzMi5kbGwAR0RJMzIuZGxs ! AE1TVkNSVC5kbGwAVVNFUjMyLmRsbAAATG9hZExpYnJhcnlBAABHZXRQcm9jQWRkcmVzcwAARXhp ! dFByb2Nlc3MAAABSZWdDbG9zZUtleQAAAFByb3BlcnR5U2hlZXRBAABUZXh0T3V0QQAAZXhpdAAA ! R2V0REMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAAAAA= """ From tim_one@users.sourceforge.net Fri Oct 5 21:41:40 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 05 Oct 2001 13:41:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include listobject.h,2.22,2.23 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv29254/python/Include Modified Files: listobject.h Log Message: Introduced the oddly-missing PyList_CheckExact(), and used it to replace a hard-coded type check. Index: listobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/listobject.h,v retrieving revision 2.22 retrieving revision 2.23 diff -C2 -d -r2.22 -r2.23 *** listobject.h 2001/08/02 04:15:00 2.22 --- listobject.h 2001/10/05 20:41:38 2.23 *************** *** 28,31 **** --- 28,32 ---- #define PyList_Check(op) PyObject_TypeCheck(op, &PyList_Type) + #define PyList_CheckExact(op) ((op)->ob_type == &PyList_Type) extern DL_IMPORT(PyObject *) PyList_New(int size); From tim_one@users.sourceforge.net Fri Oct 5 21:41:41 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 05 Oct 2001 13:41:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.282,2.283 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv29254/python/Python Modified Files: ceval.c Log Message: Introduced the oddly-missing PyList_CheckExact(), and used it to replace a hard-coded type check. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.282 retrieving revision 2.283 diff -C2 -d -r2.282 -r2.283 *** ceval.c 2001/10/05 20:21:03 2.282 --- ceval.c 2001/10/05 20:41:38 2.283 *************** *** 990,994 **** w = POP(); v = POP(); ! if (v->ob_type == &PyList_Type && PyInt_CheckExact(w)) { /* INLINE: list[int] */ long i = PyInt_AsLong(w); --- 990,994 ---- w = POP(); v = POP(); ! if (PyList_CheckExact(v) && PyInt_CheckExact(w)) { /* INLINE: list[int] */ long i = PyInt_AsLong(w); From theller@users.sourceforge.net Fri Oct 5 21:42:38 2001 From: theller@users.sourceforge.net (Thomas Heller) Date: Fri, 05 Oct 2001 13:42:38 -0700 Subject: [Python-checkins] CVS: distutils setup.py,1.30,1.31 Message-ID: Update of /cvsroot/python/distutils In directory usw-pr-cvs1:/tmp/cvs-serv29630 Modified Files: setup.py Log Message: With Andrew's blessing: distutils version number is now 1.0.3. Index: setup.py =================================================================== RCS file: /cvsroot/python/distutils/setup.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** setup.py 2001/04/20 18:28:59 1.30 --- setup.py 2001/10/05 20:42:36 1.31 *************** *** 12,16 **** setup (name = "Distutils", ! version = "1.0.2", description = "Python Distribution Utilities", author = "Greg Ward", --- 12,16 ---- setup (name = "Distutils", ! version = "1.0.3", description = "Python Distribution Utilities", author = "Greg Ward", From theller@users.sourceforge.net Fri Oct 5 21:43:11 2001 From: theller@users.sourceforge.net (Thomas Heller) Date: Fri, 05 Oct 2001 13:43:11 -0700 Subject: [Python-checkins] CVS: distutils/distutils __init__.py,1.21,1.22 Message-ID: Update of /cvsroot/python/distutils/distutils In directory usw-pr-cvs1:/tmp/cvs-serv29980 Modified Files: __init__.py Log Message: With Andrew's blessing: distutils version number is now 1.0.3. Index: __init__.py =================================================================== RCS file: /cvsroot/python/distutils/distutils/__init__.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** __init__.py 2001/04/23 17:13:03 1.21 --- __init__.py 2001/10/05 20:43:09 1.22 *************** *** 11,13 **** __revision__ = "$Id$" ! __version__ = "1.0.2" --- 11,13 ---- __revision__ = "$Id$" ! __version__ = "1.0.3" From gvanrossum@users.sourceforge.net Fri Oct 5 21:51:40 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 05 Oct 2001 13:51:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_gc.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv30886/Lib/test Modified Files: test_gc.py Log Message: Enable GC for new-style instances. This touches lots of files, since many types were subclassable but had a xxx_dealloc function that called PyObject_DEL(self) directly instead of deferring to self->ob_type->tp_free(self). It is permissible to set tp_free in the type object directly to _PyObject_Del, for non-GC types, or to _PyObject_GC_Del, for GC types. Still, PyObject_DEL was a tad faster, so I'm fearing that our pystone rating is going down again. I'm not sure if doing something like void xxx_dealloc(PyObject *self) { if (PyXxxCheckExact(self)) PyObject_DEL(self); else self->ob_type->tp_free(self); } is any faster than always calling the else branch, so I haven't attempted that -- however those types whose own dealloc is fancier (int, float, unicode) do use this pattern. Index: test_gc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_gc.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** test_gc.py 2001/10/02 21:24:57 1.10 --- test_gc.py 2001/10/05 20:51:38 1.11 *************** *** 74,77 **** --- 74,95 ---- expect_nonzero(gc.collect(), "instance") + def test_newinstance(): + class A(object): + pass + a = A() + a.a = a + gc.collect() + del a + expect_nonzero(gc.collect(), "newinstance") + class B(list): + pass + class C(B, A): + pass + a = C() + a.a = a + gc.collect() + del a + expect_nonzero(gc.collect(), "newinstance(2)") + def test_method(): # Tricky: self.__init__ is a bound method, it references the instance. *************** *** 171,174 **** --- 189,193 ---- run_test("dynamic classes", test_dynamicclass) run_test("instances", test_instance) + run_test("new instances", test_newinstance) run_test("methods", test_method) run_test("functions", test_function) From gvanrossum@users.sourceforge.net Fri Oct 5 21:51:41 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 05 Oct 2001 13:51:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects complexobject.c,2.49,2.50 dictobject.c,2.113,2.114 fileobject.c,2.131,2.132 floatobject.c,2.100,2.101 funcobject.c,2.45,2.46 listobject.c,2.101,2.102 longobject.c,1.110,1.111 moduleobject.c,2.38,2.39 stringobject.c,2.136,2.137 tupleobject.c,2.60,2.61 typeobject.c,2.89,2.90 unicodeobject.c,2.117,2.118 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv30886/Objects Modified Files: complexobject.c dictobject.c fileobject.c floatobject.c funcobject.c listobject.c longobject.c moduleobject.c stringobject.c tupleobject.c typeobject.c unicodeobject.c Log Message: Enable GC for new-style instances. This touches lots of files, since many types were subclassable but had a xxx_dealloc function that called PyObject_DEL(self) directly instead of deferring to self->ob_type->tp_free(self). It is permissible to set tp_free in the type object directly to _PyObject_Del, for non-GC types, or to _PyObject_GC_Del, for GC types. Still, PyObject_DEL was a tad faster, so I'm fearing that our pystone rating is going down again. I'm not sure if doing something like void xxx_dealloc(PyObject *self) { if (PyXxxCheckExact(self)) PyObject_DEL(self); else self->ob_type->tp_free(self); } is any faster than always calling the else branch, so I haven't attempted that -- however those types whose own dealloc is fancier (int, float, unicode) do use this pattern. Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.49 retrieving revision 2.50 diff -C2 -d -r2.49 -r2.50 *** complexobject.c 2001/09/27 20:30:07 2.49 --- complexobject.c 2001/10/05 20:51:38 2.50 *************** *** 266,270 **** complex_dealloc(PyObject *op) { ! PyObject_DEL(op); } --- 266,270 ---- complex_dealloc(PyObject *op) { ! op->ob_type->tp_free(op); } *************** *** 971,974 **** --- 971,975 ---- 0, /* tp_alloc */ complex_new, /* tp_new */ + _PyObject_Del, /* tp_free */ }; Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.113 retrieving revision 2.114 diff -C2 -d -r2.113 -r2.114 *** dictobject.c 2001/09/14 00:25:33 2.113 --- dictobject.c 2001/10/05 20:51:38 2.114 *************** *** 706,710 **** if (mp->ma_table != mp->ma_smalltable) PyMem_DEL(mp->ma_table); ! PyObject_GC_Del(mp); Py_TRASHCAN_SAFE_END(mp) } --- 706,710 ---- if (mp->ma_table != mp->ma_smalltable) PyMem_DEL(mp->ma_table); ! mp->ob_type->tp_free((PyObject *)mp); Py_TRASHCAN_SAFE_END(mp) } *************** *** 1770,1773 **** --- 1770,1774 ---- PyType_GenericAlloc, /* tp_alloc */ dict_new, /* tp_new */ + _PyObject_GC_Del, /* tp_free */ }; Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.131 retrieving revision 2.132 diff -C2 -d -r2.131 -r2.132 *** fileobject.c 2001/09/23 04:06:05 2.131 --- fileobject.c 2001/10/05 20:51:38 2.132 *************** *** 209,213 **** Py_XDECREF(f->f_name); Py_XDECREF(f->f_mode); ! PyObject_DEL(f); } --- 209,213 ---- Py_XDECREF(f->f_name); Py_XDECREF(f->f_mode); ! f->ob_type->tp_free((PyObject *)f); } *************** *** 1509,1514 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | ! Py_TPFLAGS_BASETYPE, /* tp_flags */ file_doc, /* tp_doc */ 0, /* tp_traverse */ --- 1509,1513 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ file_doc, /* tp_doc */ 0, /* tp_traverse */ *************** *** 1529,1532 **** --- 1528,1532 ---- PyType_GenericAlloc, /* tp_alloc */ file_new, /* tp_new */ + _PyObject_Del, /* tp_free */ }; Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.100 retrieving revision 2.101 diff -C2 -d -r2.100 -r2.101 *** floatobject.c 2001/09/19 01:25:15 2.100 --- floatobject.c 2001/10/05 20:51:38 2.101 *************** *** 183,188 **** float_dealloc(PyFloatObject *op) { ! op->ob_type = (struct _typeobject *)free_list; ! free_list = op; } --- 183,192 ---- float_dealloc(PyFloatObject *op) { ! if (PyFloat_CheckExact(op)) { ! op->ob_type = (struct _typeobject *)free_list; ! free_list = op; ! } ! else ! op->ob_type->tp_free((PyObject *)op); } Index: funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.45 retrieving revision 2.46 diff -C2 -d -r2.45 -r2.46 *** funcobject.c 2001/09/20 21:45:26 2.45 --- funcobject.c 2001/10/05 20:51:38 2.46 *************** *** 462,466 **** { Py_XDECREF(cm->cm_callable); ! PyObject_DEL(cm); } --- 462,466 ---- { Py_XDECREF(cm->cm_callable); ! cm->ob_type->tp_free((PyObject *)cm); } *************** *** 532,535 **** --- 532,536 ---- PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ + _PyObject_Del, /* tp_free */ }; *************** *** 572,576 **** { Py_XDECREF(sm->sm_callable); ! PyObject_DEL(sm); } --- 573,577 ---- { Py_XDECREF(sm->sm_callable); ! sm->ob_type->tp_free((PyObject *)sm); } *************** *** 642,645 **** --- 643,647 ---- PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ + _PyObject_Del, /* tp_free */ }; Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.101 retrieving revision 2.102 diff -C2 -d -r2.101 -r2.102 *** listobject.c 2001/08/30 06:15:32 2.101 --- listobject.c 2001/10/05 20:51:38 2.102 *************** *** 209,213 **** PyMem_FREE(op->ob_item); } ! PyObject_GC_Del(op); Py_TRASHCAN_SAFE_END(op) } --- 209,213 ---- PyMem_FREE(op->ob_item); } ! op->ob_type->tp_free((PyObject *)op); Py_TRASHCAN_SAFE_END(op) } *************** *** 1708,1711 **** --- 1708,1712 ---- PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ + _PyObject_GC_Del, /* tp_free */ }; Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.110 retrieving revision 1.111 diff -C2 -d -r1.110 -r1.111 *** longobject.c 2001/09/30 05:09:37 1.110 --- longobject.c 2001/10/05 20:51:38 1.111 *************** *** 1228,1232 **** long_dealloc(PyObject *v) { ! PyObject_DEL(v); } --- 1228,1232 ---- long_dealloc(PyObject *v) { ! v->ob_type->tp_free(v); } *************** *** 2342,2344 **** --- 2342,2345 ---- 0, /* tp_alloc */ long_new, /* tp_new */ + _PyObject_Del, /* tp_free */ }; Index: moduleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/moduleobject.c,v retrieving revision 2.38 retrieving revision 2.39 diff -C2 -d -r2.38 -r2.39 *** moduleobject.c 2001/09/20 20:46:19 2.38 --- moduleobject.c 2001/10/05 20:51:39 2.39 *************** *** 152,156 **** Py_DECREF(m->md_dict); } ! PyObject_GC_Del(m); } --- 152,156 ---- Py_DECREF(m->md_dict); } ! m->ob_type->tp_free((PyObject *)m); } *************** *** 226,228 **** --- 226,229 ---- PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ + _PyObject_GC_Del, /* tp_free */ }; Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.136 retrieving revision 2.137 diff -C2 -d -r2.136 -r2.137 *** stringobject.c 2001/10/02 21:32:07 2.136 --- stringobject.c 2001/10/05 20:51:39 2.137 *************** *** 482,486 **** string_dealloc(PyObject *op) { ! PyObject_DEL(op); } --- 482,486 ---- string_dealloc(PyObject *op) { ! op->ob_type->tp_free(op); } *************** *** 2747,2750 **** --- 2747,2751 ---- 0, /* tp_alloc */ string_new, /* tp_new */ + _PyObject_Del, /* tp_free */ }; Index: tupleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.60 retrieving revision 2.61 diff -C2 -d -r2.60 -r2.61 *** tupleobject.c 2001/09/11 19:48:03 2.60 --- tupleobject.c 2001/10/05 20:51:39 2.61 *************** *** 158,162 **** #endif } ! PyObject_GC_Del(op); done: Py_TRASHCAN_SAFE_END(op) --- 158,162 ---- #endif } ! op->ob_type->tp_free((PyObject *)op); done: Py_TRASHCAN_SAFE_END(op) *************** *** 583,586 **** --- 583,587 ---- 0, /* tp_alloc */ tuple_new, /* tp_new */ + _PyObject_GC_Del, /* tp_free */ }; Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.89 retrieving revision 2.90 diff -C2 -d -r2.89 -r2.90 *** typeobject.c 2001/10/04 19:46:06 2.89 --- typeobject.c 2001/10/05 20:51:39 2.90 *************** *** 230,235 **** } ! /* Helper for subtyping */ static void subtype_dealloc(PyObject *self) --- 230,264 ---- } ! /* Helpers for subtyping */ ! ! static int ! subtype_traverse(PyObject *self, visitproc visit, void *arg) ! { ! PyTypeObject *type, *base; ! traverseproc f; ! int err; ! ! /* Find the nearest base with a different tp_traverse */ ! type = self->ob_type; ! base = type->tp_base; ! while ((f = base->tp_traverse) == subtype_traverse) { ! base = base->tp_base; ! assert(base); ! } + if (type->tp_dictoffset != base->tp_dictoffset) { + PyObject **dictptr = _PyObject_GetDictPtr(self); + if (dictptr && *dictptr) { + err = visit(*dictptr, arg); + if (err) + return err; + } + } + + if (f) + return f(self, visit, arg); + return 0; + } + static void subtype_dealloc(PyObject *self) *************** *** 969,977 **** type->tp_dealloc = subtype_dealloc; /* Always override allocation strategy to use regular heap */ type->tp_alloc = PyType_GenericAlloc; if (type->tp_flags & Py_TPFLAGS_HAVE_GC) { type->tp_free = _PyObject_GC_Del; ! type->tp_traverse = base->tp_traverse; type->tp_clear = base->tp_clear; } --- 998,1011 ---- type->tp_dealloc = subtype_dealloc; + /* Enable GC unless there are really no instance variables possible */ + if (!(type->tp_basicsize == sizeof(PyObject) && + type->tp_itemsize == 0)) + type->tp_flags |= Py_TPFLAGS_HAVE_GC; + /* Always override allocation strategy to use regular heap */ type->tp_alloc = PyType_GenericAlloc; if (type->tp_flags & Py_TPFLAGS_HAVE_GC) { type->tp_free = _PyObject_GC_Del; ! type->tp_traverse = subtype_traverse; type->tp_clear = base->tp_clear; } *************** *** 1098,1102 **** Py_XDECREF(type->tp_mro); Py_XDECREF(type->tp_defined); - /* XXX more? */ Py_XDECREF(et->name); Py_XDECREF(et->slots); --- 1132,1135 ---- *************** *** 1292,1301 **** } - static void - object_free(PyObject *self) - { - PyObject_Del(self); - } - static PyObject * object_get_class(PyObject *self, void *closure) --- 1325,1328 ---- *************** *** 1447,1451 **** PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ ! object_free, /* tp_free */ }; --- 1474,1478 ---- PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ ! _PyObject_Del, /* tp_free */ }; Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.117 retrieving revision 2.118 diff -C2 -d -r2.117 -r2.118 *** unicodeobject.c 2001/09/21 15:38:17 2.117 --- unicodeobject.c 2001/10/05 20:51:39 2.118 *************** *** 225,230 **** static ! void _PyUnicode_Free(register PyUnicodeObject *unicode) { if (unicode_freelist_size < MAX_UNICODE_FREELIST_SIZE) { /* Keep-Alive optimization */ --- 225,234 ---- static ! void unicode_dealloc(register PyUnicodeObject *unicode) { + if (!PyUnicode_CheckExact(unicode)) { + unicode->ob_type->tp_free((PyObject *)unicode); + return; + } if (unicode_freelist_size < MAX_UNICODE_FREELIST_SIZE) { /* Keep-Alive optimization */ *************** *** 5694,5698 **** 0, /* tp_itemsize */ /* Slots */ ! (destructor)_PyUnicode_Free, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ --- 5698,5702 ---- 0, /* tp_itemsize */ /* Slots */ ! (destructor)unicode_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ *************** *** 5728,5731 **** --- 5732,5736 ---- 0, /* tp_alloc */ unicode_new, /* tp_new */ + _PyObject_Del, /* tp_free */ }; From gvanrossum@users.sourceforge.net Fri Oct 5 22:22:23 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 05 Oct 2001 14:22:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib multifile.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv15457 Modified Files: multifile.py Log Message: Martijn Pieters convinced me that when readline() strips the trailing newline from a multifile part, it should also strip a trailing \r\n. Index: multifile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/multifile.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** multifile.py 2001/09/18 14:34:06 1.19 --- multifile.py 2001/10/05 21:22:21 1.20 *************** *** 77,82 **** if line: self.readahead = self._readline() ! if not self.readahead and line[-1:] == "\n": ! line = line[:-1] return line --- 77,85 ---- if line: self.readahead = self._readline() ! if not self.readahead: ! if line[-2:] == "\r\n": ! line = line[:-2] ! elif line[-1:] == "\n": ! line = line[:-1] return line From fdrake@users.sourceforge.net Fri Oct 5 22:50:10 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 14:50:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python exceptions.c,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv24355/Python Modified Files: exceptions.c Log Message: weakref.ReferenceError becomes a built-in exception now that weak ref objects are moving into the core; with these changes, it will be possible for the exception to be raised without the weakref module ever being imported. Index: exceptions.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/exceptions.c,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** exceptions.c 2001/08/23 02:55:39 1.26 --- exceptions.c 2001/10/05 21:50:08 1.27 *************** *** 98,101 **** --- 98,102 ---- | | +-- UnicodeError\n\ | |\n\ + | +-- ReferenceError\n\ | +-- SystemError\n\ | +-- MemoryError\n\ *************** *** 890,893 **** --- 891,897 ---- static char + ReferenceError__doc__[] = "Weak ref proxy used after referent went away."; + + static char MemoryError__doc__[] = "Out of memory."; *************** *** 957,960 **** --- 961,965 ---- PyObject *PyExc_IndentationError; PyObject *PyExc_TabError; + PyObject *PyExc_ReferenceError; PyObject *PyExc_SystemError; PyObject *PyExc_SystemExit; *************** *** 1045,1048 **** --- 1050,1054 ---- {"ValueError", &PyExc_ValueError, 0, ValueError__doc__}, {"UnicodeError", &PyExc_UnicodeError, &PyExc_ValueError, UnicodeError__doc__}, + {"ReferenceError", &PyExc_ReferenceError, 0, ReferenceError__doc__}, {"SystemError", &PyExc_SystemError, 0, SystemError__doc__}, {"MemoryError", &PyExc_MemoryError, 0, MemoryError__doc__}, From fdrake@users.sourceforge.net Fri Oct 5 22:50:10 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 14:50:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include pyerrors.h,2.49,2.50 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv24355/Include Modified Files: pyerrors.h Log Message: weakref.ReferenceError becomes a built-in exception now that weak ref objects are moving into the core; with these changes, it will be possible for the exception to be raised without the weakref module ever being imported. Index: pyerrors.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pyerrors.h,v retrieving revision 2.49 retrieving revision 2.50 diff -C2 -d -r2.49 -r2.50 *** pyerrors.h 2001/08/23 02:56:07 2.49 --- pyerrors.h 2001/10/05 21:50:08 2.50 *************** *** 49,52 **** --- 49,53 ---- extern DL_IMPORT(PyObject *) PyExc_IndentationError; extern DL_IMPORT(PyObject *) PyExc_TabError; + extern DL_IMPORT(PyObject *) PyExc_ReferenceError; extern DL_IMPORT(PyObject *) PyExc_SystemError; extern DL_IMPORT(PyObject *) PyExc_SystemExit; From fdrake@users.sourceforge.net Fri Oct 5 22:52:28 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 14:52:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include weakrefobject.h,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv25223/Include Added Files: weakrefobject.h Log Message: The weak reference implementation, separated from the weakref module. --- NEW FILE: weakrefobject.h --- /* Weak references objects for Python. */ #ifndef Py_WEAKREFOBJECT_H #define Py_WEAKREFOBJECT_H #ifdef __cplusplus extern "C" { #endif typedef struct _PyWeakReference PyWeakReference; struct _PyWeakReference { PyObject_HEAD PyObject *wr_object; PyObject *wr_callback; long hash; PyWeakReference *wr_prev; PyWeakReference *wr_next; }; extern DL_IMPORT(PyTypeObject) _PyWeakref_RefType; extern DL_IMPORT(PyTypeObject) _PyWeakref_ProxyType; extern DL_IMPORT(PyTypeObject) _PyWeakref_CallableProxyType; extern DL_IMPORT(PyObject *) PyErr_ReferenceError; #define PyWeakref_CheckRef(op) \ ((op)->ob_type == &_PyWeakref_RefType) #define PyWeakref_CheckProxy(op) \ (((op)->ob_type == &_PyWeakref_ProxyType) || \ ((op)->ob_type == &_PyWeakref_CallableProxyType)) #define PyWeakref_Check(op) \ (PyWeakref_CheckRef(op) || PyWeakref_CheckProxy(op)) extern DL_IMPORT(PyObject *) PyWeakref_NewRef(PyObject *ob, PyObject *callback); extern DL_IMPORT(PyObject *) PyWeakref_NewProxy(PyObject *ob, PyObject *callback); extern DL_IMPORT(PyObject *) PyWeakref_GetObject(PyObject *ref); extern DL_IMPORT(long) _PyWeakref_GetWeakrefCount(PyWeakReference *head); #define PyWeakref_GET_OBJECT(ref) (((PyWeakReference *)(ref))->wr_object) #ifdef __cplusplus } #endif #endif /* !Py_WEAKREFOBJECT_H */ From fdrake@users.sourceforge.net Fri Oct 5 22:52:28 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 14:52:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects weakrefobject.c,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv25223/Objects Added Files: weakrefobject.c Log Message: The weak reference implementation, separated from the weakref module. --- NEW FILE: weakrefobject.c --- #include "Python.h" #include "structmember.h" #define GET_WEAKREFS_LISTPTR(o) \ ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o)) static PyWeakReference * free_list = NULL; long _PyWeakref_GetWeakrefCount(PyWeakReference *head) { long count = 0; while (head != NULL) { ++count; head = head->wr_next; } return count; } static PyWeakReference * new_weakref(void) { PyWeakReference *result; if (free_list != NULL) { result = free_list; free_list = result->wr_next; result->ob_type = &_PyWeakref_RefType; _Py_NewReference((PyObject *)result); } else { result = PyObject_GC_New(PyWeakReference, &_PyWeakref_RefType); } if (result) result->hash = -1; return result; } /* This function clears the passed-in reference and removes it from the * list of weak references for the referent. This is the only code that * removes an item from the doubly-linked list of weak references for an * object; it is also responsible for clearing the callback slot. */ static void clear_weakref(PyWeakReference *self) { PyObject *callback = self->wr_callback; if (PyWeakref_GET_OBJECT(self) != Py_None) { PyWeakReference **list = GET_WEAKREFS_LISTPTR( PyWeakref_GET_OBJECT(self)); if (*list == self) *list = self->wr_next; self->wr_object = Py_None; self->wr_callback = NULL; if (self->wr_prev != NULL) self->wr_prev->wr_next = self->wr_next; if (self->wr_next != NULL) self->wr_next->wr_prev = self->wr_prev; self->wr_prev = NULL; self->wr_next = NULL; Py_XDECREF(callback); } } static void weakref_dealloc(PyWeakReference *self) { PyObject_GC_UnTrack((PyObject *)self); clear_weakref(self); self->wr_next = free_list; free_list = self; } static int gc_traverse(PyWeakReference *self, visitproc visit, void *arg) { if (self->wr_callback != NULL) return visit(self->wr_callback, arg); return 0; } static int gc_clear(PyWeakReference *self) { clear_weakref(self); return 0; } static PyObject * weakref_call(PyWeakReference *self, PyObject *args, PyObject *kw) { static char *argnames[] = {NULL}; if (PyArg_ParseTupleAndKeywords(args, kw, ":__call__", argnames)) { PyObject *object = PyWeakref_GET_OBJECT(self); Py_INCREF(object); return (object); } return NULL; } static long weakref_hash(PyWeakReference *self) { if (self->hash != -1) return self->hash; if (PyWeakref_GET_OBJECT(self) == Py_None) { PyErr_SetString(PyExc_TypeError, "weak object has gone away"); return -1; } self->hash = PyObject_Hash(PyWeakref_GET_OBJECT(self)); return self->hash; } static PyObject * weakref_repr(PyWeakReference *self) { char buffer[256]; if (PyWeakref_GET_OBJECT(self) == Py_None) { sprintf(buffer, "", (long)(self)); } else { sprintf(buffer, "", (long)(self), PyWeakref_GET_OBJECT(self)->ob_type->tp_name, (long)(PyWeakref_GET_OBJECT(self))); } return PyString_FromString(buffer); } /* Weak references only support equality, not ordering. Two weak references are equal if the underlying objects are equal. If the underlying object has gone away, they are equal if they are identical. */ static PyObject * weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op) { if (op != Py_EQ || self->ob_type != other->ob_type) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } if (PyWeakref_GET_OBJECT(self) == Py_None || PyWeakref_GET_OBJECT(other) == Py_None) { PyObject *res = self==other ? Py_True : Py_False; Py_INCREF(res); return res; } return PyObject_RichCompare(PyWeakref_GET_OBJECT(self), PyWeakref_GET_OBJECT(other), op); } PyTypeObject _PyWeakref_RefType = { PyObject_HEAD_INIT(&PyType_Type) 0, "weakref", sizeof(PyWeakReference), 0, (destructor)weakref_dealloc,/*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ (reprfunc)weakref_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)weakref_hash, /*tp_hash*/ (ternaryfunc)weakref_call, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_RICHCOMPARE, 0, /*tp_doc*/ (traverseproc)gc_traverse, /*tp_traverse*/ (inquiry)gc_clear, /*tp_clear*/ (richcmpfunc)weakref_richcompare, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ }; static int proxy_checkref(PyWeakReference *proxy) { if (PyWeakref_GET_OBJECT(proxy) == Py_None) { PyErr_SetString(PyExc_ReferenceError, "weakly-referenced object no longer exists"); return 0; } return 1; } #define WRAP_UNARY(method, generic) \ static PyObject * \ method(PyWeakReference *proxy) { \ if (!proxy_checkref(proxy)) { \ return NULL; \ } \ return generic(PyWeakref_GET_OBJECT(proxy)); \ } #define WRAP_BINARY(method, generic) \ static PyObject * \ method(PyWeakReference *proxy, PyObject *v) { \ if (!proxy_checkref(proxy)) { \ return NULL; \ } \ return generic(PyWeakref_GET_OBJECT(proxy), v); \ } #define WRAP_TERNARY(method, generic) \ static PyObject * \ method(PyWeakReference *proxy, PyObject *v, PyObject *w) { \ if (!proxy_checkref(proxy)) { \ return NULL; \ } \ return generic(PyWeakref_GET_OBJECT(proxy), v, w); \ } /* direct slots */ WRAP_BINARY(proxy_getattr, PyObject_GetAttr) WRAP_UNARY(proxy_str, PyObject_Str) WRAP_TERNARY(proxy_call, PyEval_CallObjectWithKeywords) static int proxy_print(PyWeakReference *proxy, FILE *fp, int flags) { if (!proxy_checkref(proxy)) return -1; return PyObject_Print(PyWeakref_GET_OBJECT(proxy), fp, flags); } static PyObject * proxy_repr(PyWeakReference *proxy) { char buf[160]; sprintf(buf, "", proxy, PyWeakref_GET_OBJECT(proxy)->ob_type->tp_name, PyWeakref_GET_OBJECT(proxy)); return PyString_FromString(buf); } static int proxy_setattr(PyWeakReference *proxy, PyObject *name, PyObject *value) { if (!proxy_checkref(proxy)) return -1; return PyObject_SetAttr(PyWeakref_GET_OBJECT(proxy), name, value); } static int proxy_compare(PyWeakReference *proxy, PyObject *v) { if (!proxy_checkref(proxy)) return -1; return PyObject_Compare(PyWeakref_GET_OBJECT(proxy), v); } /* number slots */ WRAP_BINARY(proxy_add, PyNumber_Add) WRAP_BINARY(proxy_sub, PyNumber_Subtract) WRAP_BINARY(proxy_mul, PyNumber_Multiply) WRAP_BINARY(proxy_div, PyNumber_Divide) WRAP_BINARY(proxy_mod, PyNumber_Remainder) WRAP_BINARY(proxy_divmod, PyNumber_Divmod) WRAP_TERNARY(proxy_pow, PyNumber_Power) WRAP_UNARY(proxy_neg, PyNumber_Negative) WRAP_UNARY(proxy_pos, PyNumber_Positive) WRAP_UNARY(proxy_abs, PyNumber_Absolute) WRAP_UNARY(proxy_invert, PyNumber_Invert) WRAP_BINARY(proxy_lshift, PyNumber_Lshift) WRAP_BINARY(proxy_rshift, PyNumber_Rshift) WRAP_BINARY(proxy_and, PyNumber_And) WRAP_BINARY(proxy_xor, PyNumber_Xor) WRAP_BINARY(proxy_or, PyNumber_Or) WRAP_UNARY(proxy_int, PyNumber_Int) WRAP_UNARY(proxy_long, PyNumber_Long) WRAP_UNARY(proxy_float, PyNumber_Float) WRAP_BINARY(proxy_iadd, PyNumber_InPlaceAdd) WRAP_BINARY(proxy_isub, PyNumber_InPlaceSubtract) WRAP_BINARY(proxy_imul, PyNumber_InPlaceMultiply) WRAP_BINARY(proxy_idiv, PyNumber_InPlaceDivide) WRAP_BINARY(proxy_imod, PyNumber_InPlaceRemainder) WRAP_TERNARY(proxy_ipow, PyNumber_InPlacePower) WRAP_BINARY(proxy_ilshift, PyNumber_InPlaceLshift) WRAP_BINARY(proxy_irshift, PyNumber_InPlaceRshift) WRAP_BINARY(proxy_iand, PyNumber_InPlaceAnd) WRAP_BINARY(proxy_ixor, PyNumber_InPlaceXor) WRAP_BINARY(proxy_ior, PyNumber_InPlaceOr) static int proxy_nonzero(PyWeakReference *proxy) { PyObject *o = PyWeakref_GET_OBJECT(proxy); if (!proxy_checkref(proxy)) return 1; if (o->ob_type->tp_as_number && o->ob_type->tp_as_number->nb_nonzero) return (*o->ob_type->tp_as_number->nb_nonzero)(o); else return 1; } /* sequence slots */ static PyObject * proxy_slice(PyWeakReference *proxy, int i, int j) { if (!proxy_checkref(proxy)) return NULL; return PySequence_GetSlice(PyWeakref_GET_OBJECT(proxy), i, j); } static int proxy_ass_slice(PyWeakReference *proxy, int i, int j, PyObject *value) { if (!proxy_checkref(proxy)) return -1; return PySequence_SetSlice(PyWeakref_GET_OBJECT(proxy), i, j, value); } static int proxy_contains(PyWeakReference *proxy, PyObject *value) { if (!proxy_checkref(proxy)) return -1; return PySequence_Contains(PyWeakref_GET_OBJECT(proxy), value); } /* mapping slots */ static int proxy_length(PyWeakReference *proxy) { if (!proxy_checkref(proxy)) return -1; return PyObject_Length(PyWeakref_GET_OBJECT(proxy)); } WRAP_BINARY(proxy_getitem, PyObject_GetItem) static int proxy_setitem(PyWeakReference *proxy, PyObject *key, PyObject *value) { if (!proxy_checkref(proxy)) return -1; return PyObject_SetItem(PyWeakref_GET_OBJECT(proxy), key, value); } static PyNumberMethods proxy_as_number = { (binaryfunc)proxy_add, /*nb_add*/ (binaryfunc)proxy_sub, /*nb_subtract*/ (binaryfunc)proxy_mul, /*nb_multiply*/ (binaryfunc)proxy_div, /*nb_divide*/ (binaryfunc)proxy_mod, /*nb_remainder*/ (binaryfunc)proxy_divmod, /*nb_divmod*/ (ternaryfunc)proxy_pow, /*nb_power*/ (unaryfunc)proxy_neg, /*nb_negative*/ (unaryfunc)proxy_pos, /*nb_positive*/ (unaryfunc)proxy_abs, /*nb_absolute*/ (inquiry)proxy_nonzero, /*nb_nonzero*/ (unaryfunc)proxy_invert, /*nb_invert*/ (binaryfunc)proxy_lshift, /*nb_lshift*/ (binaryfunc)proxy_rshift, /*nb_rshift*/ (binaryfunc)proxy_and, /*nb_and*/ (binaryfunc)proxy_xor, /*nb_xor*/ (binaryfunc)proxy_or, /*nb_or*/ (coercion)0, /*nb_coerce*/ (unaryfunc)proxy_int, /*nb_int*/ (unaryfunc)proxy_long, /*nb_long*/ (unaryfunc)proxy_float, /*nb_float*/ (unaryfunc)0, /*nb_oct*/ (unaryfunc)0, /*nb_hex*/ (binaryfunc)proxy_iadd, /*nb_inplace_add*/ (binaryfunc)proxy_isub, /*nb_inplace_subtract*/ (binaryfunc)proxy_imul, /*nb_inplace_multiply*/ (binaryfunc)proxy_idiv, /*nb_inplace_divide*/ (binaryfunc)proxy_imod, /*nb_inplace_remainder*/ (ternaryfunc)proxy_ipow, /*nb_inplace_power*/ (binaryfunc)proxy_ilshift, /*nb_inplace_lshift*/ (binaryfunc)proxy_irshift, /*nb_inplace_rshift*/ (binaryfunc)proxy_iand, /*nb_inplace_and*/ (binaryfunc)proxy_ixor, /*nb_inplace_xor*/ (binaryfunc)proxy_ior, /*nb_inplace_or*/ }; static PySequenceMethods proxy_as_sequence = { (inquiry)proxy_length, /*sq_length*/ 0, /*sq_concat*/ 0, /*sq_repeat*/ 0, /*sq_item*/ (intintargfunc)proxy_slice, /*sq_slice*/ 0, /*sq_ass_item*/ (intintobjargproc)proxy_ass_slice, /*sq_ass_slice*/ (objobjproc)proxy_contains, /* sq_contains */ }; static PyMappingMethods proxy_as_mapping = { (inquiry)proxy_length, /*mp_length*/ (binaryfunc)proxy_getitem, /*mp_subscript*/ (objobjargproc)proxy_setitem, /*mp_ass_subscript*/ }; PyTypeObject _PyWeakref_ProxyType = { PyObject_HEAD_INIT(&PyType_Type) 0, "weakproxy", sizeof(PyWeakReference), 0, /* methods */ (destructor)weakref_dealloc,/*tp_dealloc*/ (printfunc)proxy_print, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ (cmpfunc)proxy_compare, /*tp_compare*/ (unaryfunc)proxy_repr, /*tp_repr*/ &proxy_as_number, /*tp_as_number*/ &proxy_as_sequence, /*tp_as_sequence*/ &proxy_as_mapping, /*tp_as_mapping*/ 0, /*tp_hash*/ (ternaryfunc)0, /*tp_call*/ (unaryfunc)proxy_str, /*tp_str*/ (getattrofunc)proxy_getattr,/*tp_getattro*/ (setattrofunc)proxy_setattr,/*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |Py_TPFLAGS_CHECKTYPES, /*tp_flags*/ 0, /*tp_doc*/ (traverseproc)gc_traverse, /*tp_traverse*/ (inquiry)gc_clear, /*tp_clear*/ }; PyTypeObject _PyWeakref_CallableProxyType = { PyObject_HEAD_INIT(&PyType_Type) 0, "weakcallableproxy", sizeof(PyWeakReference), 0, /* methods */ (destructor)weakref_dealloc,/*tp_dealloc*/ (printfunc)proxy_print, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ (cmpfunc)proxy_compare, /*tp_compare*/ (unaryfunc)proxy_repr, /*tp_repr*/ &proxy_as_number, /*tp_as_number*/ &proxy_as_sequence, /*tp_as_sequence*/ &proxy_as_mapping, /*tp_as_mapping*/ 0, /*tp_hash*/ (ternaryfunc)proxy_call, /*tp_call*/ (unaryfunc)proxy_str, /*tp_str*/ (getattrofunc)proxy_getattr,/*tp_getattro*/ (setattrofunc)proxy_setattr,/*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |Py_TPFLAGS_CHECKTYPES, /*tp_flags*/ 0, /*tp_doc*/ (traverseproc)gc_traverse, /*tp_traverse*/ (inquiry)gc_clear, /*tp_clear*/ }; /* Given the head of an object's list of weak references, extract the * two callback-less refs (ref and proxy). Used to determine if the * shared references exist and to determine the back link for newly * inserted references. */ static void get_basic_refs(PyWeakReference *head, PyWeakReference **refp, PyWeakReference **proxyp) { *refp = NULL; *proxyp = NULL; if (head != NULL && head->wr_callback == NULL) { if (head->ob_type == &_PyWeakref_RefType) { *refp = head; head = head->wr_next; } if (head != NULL && head->wr_callback == NULL) { *proxyp = head; head = head->wr_next; } } } /* Insert 'newref' in the list after 'prev'. Both must be non-NULL. */ static void insert_after(PyWeakReference *newref, PyWeakReference *prev) { newref->wr_prev = prev; newref->wr_next = prev->wr_next; if (prev->wr_next != NULL) prev->wr_next->wr_prev = newref; prev->wr_next = newref; } /* Insert 'newref' at the head of the list; 'list' points to the variable * that stores the head. */ static void insert_head(PyWeakReference *newref, PyWeakReference **list) { PyWeakReference *next = *list; newref->wr_prev = NULL; newref->wr_next = next; if (next != NULL) next->wr_prev = newref; *list = newref; } PyObject * PyWeakref_NewRef(PyObject *ob, PyObject *callback) { PyWeakReference *result = NULL; PyWeakReference **list; PyWeakReference *ref, *proxy; if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) { PyErr_Format(PyExc_TypeError, "'%s' objects are not weakly referencable", ob->ob_type->tp_name); return NULL; } list = GET_WEAKREFS_LISTPTR(ob); get_basic_refs(*list, &ref, &proxy); if (callback == NULL || callback == Py_None) /* return existing weak reference if it exists */ result = ref; if (result != NULL) Py_XINCREF(result); else { result = new_weakref(); if (result != NULL) { Py_XINCREF(callback); result->wr_callback = callback; result->wr_object = ob; if (callback == NULL) { insert_head(result, list); } else { PyWeakReference *prev = (proxy == NULL) ? ref : proxy; if (prev == NULL) insert_head(result, list); else insert_after(result, prev); } PyObject_GC_Track(result); } } return (PyObject *) result; } PyObject * PyWeakref_NewProxy(PyObject *ob, PyObject *callback) { PyWeakReference *result = NULL; PyWeakReference **list; PyWeakReference *ref, *proxy; if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) { PyErr_Format(PyExc_TypeError, "'%s' objects are not weakly referencable", ob->ob_type->tp_name); return NULL; } list = GET_WEAKREFS_LISTPTR(ob); get_basic_refs(*list, &ref, &proxy); if (callback == NULL) /* attempt to return an existing weak reference if it exists */ result = proxy; if (result != NULL) Py_XINCREF(result); else { result = new_weakref(); if (result != NULL) { PyWeakReference *prev; if (PyCallable_Check(ob)) result->ob_type = &_PyWeakref_CallableProxyType; else result->ob_type = &_PyWeakref_ProxyType; result->wr_object = ob; Py_XINCREF(callback); result->wr_callback = callback; if (callback == NULL) prev = ref; else prev = (proxy == NULL) ? ref : proxy; if (prev == NULL) insert_head(result, list); else insert_after(result, prev); PyObject_GC_Track(result); } } return (PyObject *) result; } PyObject * PyWeakref_GetObject(PyObject *ref) { if (ref == NULL || !PyWeakref_Check(ref)) { PyErr_BadInternalCall(); return NULL; } return PyWeakref_GET_OBJECT(ref); } /* This is the implementation of the PyObject_ClearWeakRefs() function; it * is installed in the init_weakref() function. It is called by the * tp_dealloc handler to clear weak references. * * This iterates through the weak references for 'object' and calls callbacks * for those references which have one. It returns when all callbacks have * been attempted. */ void PyObject_ClearWeakRefs(PyObject *object) { PyWeakReference **list; if (object == NULL || !PyType_SUPPORTS_WEAKREFS(object->ob_type) || object->ob_refcnt != 0) { PyErr_BadInternalCall(); return; } list = GET_WEAKREFS_LISTPTR(object); /* Remove the callback-less basic and proxy references */ if (*list != NULL && (*list)->wr_callback == NULL) { clear_weakref(*list); if (*list != NULL && (*list)->wr_callback == NULL) clear_weakref(*list); } if (*list != NULL) { int count = _PyWeakref_GetWeakrefCount(*list); if (count == 1) { PyWeakReference *current = *list; PyObject *callback = current->wr_callback; PyObject *cbresult; Py_INCREF(callback); clear_weakref(current); cbresult = PyObject_CallFunction(callback, "O", current); if (cbresult == NULL) PyErr_WriteUnraisable(callback); else Py_DECREF(cbresult); Py_DECREF(callback); } else { PyObject *tuple = PyTuple_New(count * 2); PyWeakReference *current = *list; int i = 0; for (i = 0; i < count; ++i) { PyWeakReference *next = current->wr_next; Py_INCREF(current); PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current); PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback); current->wr_callback = NULL; next = current->wr_next; clear_weakref(current); current = next; } for (i = 0; i < count; ++i) { PyObject *current = PyTuple_GET_ITEM(tuple, i * 2); PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1); PyObject *cbresult = PyObject_CallFunction(callback, "O", current); if (cbresult == NULL) PyErr_WriteUnraisable(callback); else Py_DECREF(cbresult); } Py_DECREF(tuple); } } } From fdrake@users.sourceforge.net Fri Oct 5 22:54:11 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 14:54:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib weakref.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv25875/Lib Modified Files: weakref.py Log Message: ReferenceError is now built-in, so pick it up from the right place. It still needs to be here to preserve the API. Index: weakref.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/weakref.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** weakref.py 2001/09/28 19:01:26 1.13 --- weakref.py 2001/10/05 21:54:09 1.14 *************** *** 17,24 **** ref, \ proxy, \ - ReferenceError, \ CallableProxyType, \ ProxyType, \ ReferenceType ProxyTypes = (ProxyType, CallableProxyType) --- 17,26 ---- ref, \ proxy, \ CallableProxyType, \ ProxyType, \ ReferenceType + + from exceptions import ReferenceError + ProxyTypes = (ProxyType, CallableProxyType) From fdrake@users.sourceforge.net Fri Oct 5 22:55:22 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 14:55:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include Python.h,2.38,2.39 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv26335/Include Modified Files: Python.h Log Message: Include the weakref object interface. Index: Python.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/Python.h,v retrieving revision 2.38 retrieving revision 2.39 diff -C2 -d -r2.38 -r2.39 *** Python.h 2001/08/02 04:15:00 2.38 --- Python.h 2001/10/05 21:55:19 2.39 *************** *** 91,94 **** --- 91,95 ---- #include "iterobject.h" #include "descrobject.h" + #include "weakrefobject.h" #include "codecs.h" From fdrake@users.sourceforge.net Fri Oct 5 22:56:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 14:56:04 -0700 Subject: [Python-checkins] CVS: python/dist/src Makefile.pre.in,1.61,1.62 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv26540 Modified Files: Makefile.pre.in Log Message: Add dependencies for the weakref object. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -d -r1.61 -r1.62 *** Makefile.pre.in 2001/09/29 00:42:19 1.61 --- Makefile.pre.in 2001/10/05 21:56:02 1.62 *************** *** 266,269 **** --- 266,270 ---- Objects/tupleobject.o \ Objects/typeobject.o \ + Objects/weakrefobject.o \ $(UNICODE_OBJS) *************** *** 471,474 **** --- 472,476 ---- Include/tupleobject.h \ Include/unicodeobject.h \ + Include/weakrefobject.h \ pyconfig.h From fdrake@users.sourceforge.net Fri Oct 5 22:58:13 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 14:58:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.93,2.94 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv27456/Include Modified Files: object.h Log Message: PyObject_ClearWeakRefs() is now a real function instead of a function pointer; the implementation is in Objects/weakrefobject.c. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.93 retrieving revision 2.94 diff -C2 -d -r2.93 -r2.94 *** object.h 2001/10/02 21:24:56 2.93 --- object.h 2001/10/05 21:58:11 2.94 *************** *** 346,350 **** extern DL_IMPORT(int) PyNumber_CoerceEx(PyObject **, PyObject **); ! extern DL_IMPORT(void) (*PyObject_ClearWeakRefs)(PyObject *); /* A slot function whose address we need to compare */ --- 346,350 ---- extern DL_IMPORT(int) PyNumber_CoerceEx(PyObject **, PyObject **); ! extern DL_IMPORT(void) PyObject_ClearWeakRefs(PyObject *); /* A slot function whose address we need to compare */ From fdrake@users.sourceforge.net Fri Oct 5 22:58:13 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 14:58:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.152,2.153 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv27456/Objects Modified Files: object.c Log Message: PyObject_ClearWeakRefs() is now a real function instead of a function pointer; the implementation is in Objects/weakrefobject.c. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.152 retrieving revision 2.153 diff -C2 -d -r2.152 -r2.153 *** object.c 2001/09/27 20:30:07 2.152 --- object.c 2001/10/05 21:58:11 2.153 *************** *** 1842,1860 **** - /* Hook to clear up weak references only once the _weakref module is - imported. We use a dummy implementation to simplify the code at each - call site instead of requiring a test for NULL. - */ - - static void - empty_clear_weak_refs(PyObject *o) - { - return; - } - - void (*PyObject_ClearWeakRefs)(PyObject *) = empty_clear_weak_refs; - - - /* These methods are used to control infinite recursion in repr, str, print, etc. Container objects that may recursively contain themselves, --- 1842,1845 ---- From fdrake@users.sourceforge.net Fri Oct 5 23:00:27 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 15:00:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _weakref.c,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv28385/Modules Modified Files: _weakref.c Log Message: Adjust the _weakref module to use the public API for the weak reference objects. This is now simply a shim to give weakref.py access to the underlying implementation. Index: _weakref.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_weakref.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** _weakref.c 2001/08/29 23:50:02 1.13 --- _weakref.c 2001/10/05 22:00:24 1.14 *************** *** 1,503 **** #include "Python.h" - #include "structmember.h" - - - typedef struct _PyWeakReference PyWeakReference; - struct _PyWeakReference { - PyObject_HEAD - PyObject *wr_object; - PyObject *wr_callback; - long hash; - PyWeakReference *wr_prev; - PyWeakReference *wr_next; - }; - #define GET_WEAKREFS_LISTPTR(o) \ ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o)) - static PyObject * - ReferenceError; - - static PyWeakReference * - free_list = NULL; - - staticforward PyTypeObject - PyWeakReference_Type; - - static PyWeakReference * - new_weakref(void) - { - PyWeakReference *result; - - if (free_list != NULL) { - result = free_list; - free_list = result->wr_next; - result->ob_type = &PyWeakReference_Type; - _Py_NewReference((PyObject *)result); - } - else { - result = PyObject_GC_New(PyWeakReference, &PyWeakReference_Type); - } - if (result) - result->hash = -1; - return result; - } - - - /* This function clears the passed-in reference and removes it from the - * list of weak references for the referent. This is the only code that - * removes an item from the doubly-linked list of weak references for an - * object; it is also responsible for clearing the callback slot. - */ - static void - clear_weakref(PyWeakReference *self) - { - PyObject *callback = self->wr_callback; - - if (self->wr_object != Py_None) { - PyWeakReference **list = GET_WEAKREFS_LISTPTR(self->wr_object); - - if (*list == self) - *list = self->wr_next; - self->wr_object = Py_None; - self->wr_callback = NULL; - if (self->wr_prev != NULL) - self->wr_prev->wr_next = self->wr_next; - if (self->wr_next != NULL) - self->wr_next->wr_prev = self->wr_prev; - self->wr_prev = NULL; - self->wr_next = NULL; - Py_XDECREF(callback); - } - } - - - static void - weakref_dealloc(PyWeakReference *self) - { - PyObject_GC_UnTrack((PyObject *)self); - clear_weakref(self); - self->wr_next = free_list; - free_list = self; - } - - - static int - gc_traverse(PyWeakReference *self, visitproc visit, void *arg) - { - if (self->wr_callback != NULL) - return visit(self->wr_callback, arg); - return 0; - } - - - static int - gc_clear(PyWeakReference *self) - { - clear_weakref(self); - return 0; - } - - - static PyObject * - weakref_call(PyWeakReference *self, PyObject *args, PyObject *kw) - { - static char *argnames[] = {NULL}; - - if (PyArg_ParseTupleAndKeywords(args, kw, ":__call__", argnames)) { - PyObject *object = self->wr_object; - Py_INCREF(object); - return (object); - } - return NULL; - } - - - static long - weakref_hash(PyWeakReference *self) - { - if (self->hash != -1) - return self->hash; - if (self->wr_object == Py_None) { - PyErr_SetString(PyExc_TypeError, "weak object has gone away"); - return -1; - } - self->hash = PyObject_Hash(self->wr_object); - return self->hash; - } - - - static PyObject * - weakref_repr(PyWeakReference *self) - { - char buffer[256]; - if (self->wr_object == Py_None) { - sprintf(buffer, "", - (long)(self)); - } - else { - sprintf(buffer, "", - (long)(self), self->wr_object->ob_type->tp_name, - (long)(self->wr_object)); - } - return PyString_FromString(buffer); - } - - /* Weak references only support equality, not ordering. Two weak references - are equal if the underlying objects are equal. If the underlying object has - gone away, they are equal if they are identical. */ - - static PyObject * - weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op) - { - if (op != Py_EQ || self->ob_type != other->ob_type) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - if (self->wr_object == Py_None || other->wr_object == Py_None) { - PyObject *res = self==other ? Py_True : Py_False; - Py_INCREF(res); - return res; - } - return PyObject_RichCompare(self->wr_object, other->wr_object, op); - } - - - statichere PyTypeObject - PyWeakReference_Type = { - PyObject_HEAD_INIT(NULL) - 0, - "weakref", - sizeof(PyWeakReference), - 0, - (destructor)weakref_dealloc,/*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - (reprfunc)weakref_repr, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)weakref_hash, /*tp_hash*/ - (ternaryfunc)weakref_call, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_RICHCOMPARE, - 0, /*tp_doc*/ - (traverseproc)gc_traverse, /*tp_traverse*/ - (inquiry)gc_clear, /*tp_clear*/ - (richcmpfunc)weakref_richcompare, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - }; - - - static int - proxy_checkref(PyWeakReference *proxy) - { - if (proxy->wr_object == Py_None) { - PyErr_SetString(ReferenceError, - "weakly-referenced object no longer exists"); - return 0; - } - return 1; - } - - - #define WRAP_UNARY(method, generic) \ - static PyObject * \ - method(PyWeakReference *proxy) { \ - if (!proxy_checkref(proxy)) { \ - return NULL; \ - } \ - return generic(proxy->wr_object); \ - } - - #define WRAP_BINARY(method, generic) \ - static PyObject * \ - method(PyWeakReference *proxy, PyObject *v) { \ - if (!proxy_checkref(proxy)) { \ - return NULL; \ - } \ - return generic(proxy->wr_object, v); \ - } - - #define WRAP_TERNARY(method, generic) \ - static PyObject * \ - method(PyWeakReference *proxy, PyObject *v, PyObject *w) { \ - if (!proxy_checkref(proxy)) { \ - return NULL; \ - } \ - return generic(proxy->wr_object, v, w); \ - } - - - /* direct slots */ - - WRAP_BINARY(proxy_getattr, PyObject_GetAttr) - WRAP_UNARY(proxy_str, PyObject_Str) - WRAP_TERNARY(proxy_call, PyEval_CallObjectWithKeywords) - - static int - proxy_print(PyWeakReference *proxy, FILE *fp, int flags) - { - if (!proxy_checkref(proxy)) - return -1; - return PyObject_Print(proxy->wr_object, fp, flags); - } - - static PyObject * - proxy_repr(PyWeakReference *proxy) - { - char buf[160]; - sprintf(buf, "", proxy, - proxy->wr_object->ob_type->tp_name, proxy->wr_object); - return PyString_FromString(buf); - } - - - static int - proxy_setattr(PyWeakReference *proxy, PyObject *name, PyObject *value) - { - if (!proxy_checkref(proxy)) - return -1; - return PyObject_SetAttr(proxy->wr_object, name, value); - } - - static int - proxy_compare(PyWeakReference *proxy, PyObject *v) - { - if (!proxy_checkref(proxy)) - return -1; - return PyObject_Compare(proxy->wr_object, v); - } - - /* number slots */ - WRAP_BINARY(proxy_add, PyNumber_Add) - WRAP_BINARY(proxy_sub, PyNumber_Subtract) - WRAP_BINARY(proxy_mul, PyNumber_Multiply) - WRAP_BINARY(proxy_div, PyNumber_Divide) - WRAP_BINARY(proxy_mod, PyNumber_Remainder) - WRAP_BINARY(proxy_divmod, PyNumber_Divmod) - WRAP_TERNARY(proxy_pow, PyNumber_Power) - WRAP_UNARY(proxy_neg, PyNumber_Negative) - WRAP_UNARY(proxy_pos, PyNumber_Positive) - WRAP_UNARY(proxy_abs, PyNumber_Absolute) - WRAP_UNARY(proxy_invert, PyNumber_Invert) - WRAP_BINARY(proxy_lshift, PyNumber_Lshift) - WRAP_BINARY(proxy_rshift, PyNumber_Rshift) - WRAP_BINARY(proxy_and, PyNumber_And) - WRAP_BINARY(proxy_xor, PyNumber_Xor) - WRAP_BINARY(proxy_or, PyNumber_Or) - WRAP_UNARY(proxy_int, PyNumber_Int) - WRAP_UNARY(proxy_long, PyNumber_Long) - WRAP_UNARY(proxy_float, PyNumber_Float) - WRAP_BINARY(proxy_iadd, PyNumber_InPlaceAdd) - WRAP_BINARY(proxy_isub, PyNumber_InPlaceSubtract) - WRAP_BINARY(proxy_imul, PyNumber_InPlaceMultiply) - WRAP_BINARY(proxy_idiv, PyNumber_InPlaceDivide) - WRAP_BINARY(proxy_imod, PyNumber_InPlaceRemainder) - WRAP_TERNARY(proxy_ipow, PyNumber_InPlacePower) - WRAP_BINARY(proxy_ilshift, PyNumber_InPlaceLshift) - WRAP_BINARY(proxy_irshift, PyNumber_InPlaceRshift) - WRAP_BINARY(proxy_iand, PyNumber_InPlaceAnd) - WRAP_BINARY(proxy_ixor, PyNumber_InPlaceXor) - WRAP_BINARY(proxy_ior, PyNumber_InPlaceOr) - - static int - proxy_nonzero(PyWeakReference *proxy) - { - PyObject *o = proxy->wr_object; - if (!proxy_checkref(proxy)) - return 1; - if (o->ob_type->tp_as_number && - o->ob_type->tp_as_number->nb_nonzero) - return (*o->ob_type->tp_as_number->nb_nonzero)(o); - else - return 1; - } - - /* sequence slots */ - - static PyObject * - proxy_slice(PyWeakReference *proxy, int i, int j) - { - if (!proxy_checkref(proxy)) - return NULL; - return PySequence_GetSlice(proxy->wr_object, i, j); - } - - static int - proxy_ass_slice(PyWeakReference *proxy, int i, int j, PyObject *value) - { - if (!proxy_checkref(proxy)) - return -1; - return PySequence_SetSlice(proxy->wr_object, i, j, value); - } - - static int - proxy_contains(PyWeakReference *proxy, PyObject *value) - { - if (!proxy_checkref(proxy)) - return -1; - return PySequence_Contains(proxy->wr_object, value); - } - - - /* mapping slots */ - - static int - proxy_length(PyWeakReference *proxy) - { - if (!proxy_checkref(proxy)) - return -1; - return PyObject_Length(proxy->wr_object); - } - - WRAP_BINARY(proxy_getitem, PyObject_GetItem) - - static int - proxy_setitem(PyWeakReference *proxy, PyObject *key, PyObject *value) - { - if (!proxy_checkref(proxy)) - return -1; - return PyObject_SetItem(proxy->wr_object, key, value); - } - - - static PyNumberMethods proxy_as_number = { - (binaryfunc)proxy_add, /*nb_add*/ - (binaryfunc)proxy_sub, /*nb_subtract*/ - (binaryfunc)proxy_mul, /*nb_multiply*/ - (binaryfunc)proxy_div, /*nb_divide*/ - (binaryfunc)proxy_mod, /*nb_remainder*/ - (binaryfunc)proxy_divmod, /*nb_divmod*/ - (ternaryfunc)proxy_pow, /*nb_power*/ - (unaryfunc)proxy_neg, /*nb_negative*/ - (unaryfunc)proxy_pos, /*nb_positive*/ - (unaryfunc)proxy_abs, /*nb_absolute*/ - (inquiry)proxy_nonzero, /*nb_nonzero*/ - (unaryfunc)proxy_invert, /*nb_invert*/ - (binaryfunc)proxy_lshift, /*nb_lshift*/ - (binaryfunc)proxy_rshift, /*nb_rshift*/ - (binaryfunc)proxy_and, /*nb_and*/ - (binaryfunc)proxy_xor, /*nb_xor*/ - (binaryfunc)proxy_or, /*nb_or*/ - (coercion)0, /*nb_coerce*/ - (unaryfunc)proxy_int, /*nb_int*/ - (unaryfunc)proxy_long, /*nb_long*/ - (unaryfunc)proxy_float, /*nb_float*/ - (unaryfunc)0, /*nb_oct*/ - (unaryfunc)0, /*nb_hex*/ - (binaryfunc)proxy_iadd, /*nb_inplace_add*/ - (binaryfunc)proxy_isub, /*nb_inplace_subtract*/ - (binaryfunc)proxy_imul, /*nb_inplace_multiply*/ - (binaryfunc)proxy_idiv, /*nb_inplace_divide*/ - (binaryfunc)proxy_imod, /*nb_inplace_remainder*/ - (ternaryfunc)proxy_ipow, /*nb_inplace_power*/ - (binaryfunc)proxy_ilshift, /*nb_inplace_lshift*/ - (binaryfunc)proxy_irshift, /*nb_inplace_rshift*/ - (binaryfunc)proxy_iand, /*nb_inplace_and*/ - (binaryfunc)proxy_ixor, /*nb_inplace_xor*/ - (binaryfunc)proxy_ior, /*nb_inplace_or*/ - }; - - static PySequenceMethods proxy_as_sequence = { - (inquiry)proxy_length, /*sq_length*/ - 0, /*sq_concat*/ - 0, /*sq_repeat*/ - 0, /*sq_item*/ - (intintargfunc)proxy_slice, /*sq_slice*/ - 0, /*sq_ass_item*/ - (intintobjargproc)proxy_ass_slice, /*sq_ass_slice*/ - (objobjproc)proxy_contains, /* sq_contains */ - }; - - static PyMappingMethods proxy_as_mapping = { - (inquiry)proxy_length, /*mp_length*/ - (binaryfunc)proxy_getitem, /*mp_subscript*/ - (objobjargproc)proxy_setitem, /*mp_ass_subscript*/ - }; - - - static PyTypeObject - PyWeakProxy_Type = { - PyObject_HEAD_INIT(NULL) - 0, - "weakproxy", - sizeof(PyWeakReference), - 0, - /* methods */ - (destructor)weakref_dealloc,/*tp_dealloc*/ - (printfunc)proxy_print, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - (cmpfunc)proxy_compare, /*tp_compare*/ - (unaryfunc)proxy_repr, /*tp_repr*/ - &proxy_as_number, /*tp_as_number*/ - &proxy_as_sequence, /*tp_as_sequence*/ - &proxy_as_mapping, /*tp_as_mapping*/ - 0, /*tp_hash*/ - (ternaryfunc)0, /*tp_call*/ - (unaryfunc)proxy_str, /*tp_str*/ - (getattrofunc)proxy_getattr,/*tp_getattro*/ - (setattrofunc)proxy_setattr,/*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC - |Py_TPFLAGS_CHECKTYPES, /*tp_flags*/ - 0, /*tp_doc*/ - (traverseproc)gc_traverse, /*tp_traverse*/ - (inquiry)gc_clear, /*tp_clear*/ - }; - - static PyTypeObject - PyWeakCallableProxy_Type = { - PyObject_HEAD_INIT(NULL) - 0, - "weakcallableproxy", - sizeof(PyWeakReference), - 0, - /* methods */ - (destructor)weakref_dealloc,/*tp_dealloc*/ - (printfunc)proxy_print, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - (cmpfunc)proxy_compare, /*tp_compare*/ - (unaryfunc)proxy_repr, /*tp_repr*/ - &proxy_as_number, /*tp_as_number*/ - &proxy_as_sequence, /*tp_as_sequence*/ - &proxy_as_mapping, /*tp_as_mapping*/ - 0, /*tp_hash*/ - (ternaryfunc)proxy_call, /*tp_call*/ - (unaryfunc)proxy_str, /*tp_str*/ - (getattrofunc)proxy_getattr,/*tp_getattro*/ - (setattrofunc)proxy_setattr,/*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC - |Py_TPFLAGS_CHECKTYPES, /*tp_flags*/ - 0, /*tp_doc*/ - (traverseproc)gc_traverse, /*tp_traverse*/ - (inquiry)gc_clear, /*tp_clear*/ - }; - - - static long - getweakrefcount(PyWeakReference *head) - { - long count = 0; - - while (head != NULL) { - ++count; - head = head->wr_next; - } - return count; - } - - static char weakref_getweakrefcount__doc__[] = "getweakrefcount(object) -- return the number of weak references\n" --- 1,9 ---- *************** *** 512,516 **** PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); ! result = PyInt_FromLong(getweakrefcount(*list)); } else --- 18,22 ---- PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); ! result = PyInt_FromLong(_PyWeakref_GetWeakrefCount(*list)); } else *************** *** 532,536 **** if (PyType_SUPPORTS_WEAKREFS(object->ob_type)) { PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); ! long count = getweakrefcount(*list); result = PyList_New(count); --- 38,42 ---- if (PyType_SUPPORTS_WEAKREFS(object->ob_type)) { PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); ! long count = _PyWeakref_GetWeakrefCount(*list); result = PyList_New(count); *************** *** 552,606 **** - /* Given the head of an object's list of weak references, extract the - * two callback-less refs (ref and proxy). Used to determine if the - * shared references exist and to determine the back link for newly - * inserted references. - */ - static void - get_basic_refs(PyWeakReference *head, - PyWeakReference **refp, PyWeakReference **proxyp) - { - *refp = NULL; - *proxyp = NULL; - - if (head != NULL && head->wr_callback == NULL) { - if (head->ob_type == &PyWeakReference_Type) { - *refp = head; - head = head->wr_next; - } - if (head != NULL && head->wr_callback == NULL) { - *proxyp = head; - head = head->wr_next; - } - } - } - - /* Insert 'newref' in the list after 'prev'. Both must be non-NULL. */ - static void - insert_after(PyWeakReference *newref, PyWeakReference *prev) - { - newref->wr_prev = prev; - newref->wr_next = prev->wr_next; - if (prev->wr_next != NULL) - prev->wr_next->wr_prev = newref; - prev->wr_next = newref; - } - - /* Insert 'newref' at the head of the list; 'list' points to the variable - * that stores the head. - */ - static void - insert_head(PyWeakReference *newref, PyWeakReference **list) - { - PyWeakReference *next = *list; - - newref->wr_prev = NULL; - newref->wr_next = next; - if (next != NULL) - next->wr_prev = newref; - *list = newref; - } - - static char weakref_ref__doc__[] = "new(object[, callback]) -- create a weak reference to 'object';\n" --- 58,61 ---- *************** *** 613,657 **** PyObject *object; PyObject *callback = NULL; ! PyWeakReference *result = NULL; ! ! if (PyArg_ParseTuple(args, "O|O:new", &object, &callback)) { ! PyWeakReference **list; ! PyWeakReference *ref, *proxy; ! ! if (!PyType_SUPPORTS_WEAKREFS(object->ob_type)) { ! PyErr_Format(PyExc_TypeError, ! "'%s' objects are not weakly referencable", ! object->ob_type->tp_name); ! return NULL; ! } ! list = GET_WEAKREFS_LISTPTR(object); ! get_basic_refs(*list, &ref, &proxy); ! if (callback == NULL) { ! /* return existing weak reference if it exists */ ! result = ref; ! Py_XINCREF(result); ! } ! if (result == NULL) { ! result = new_weakref(); ! if (result != NULL) { ! Py_XINCREF(callback); ! result->wr_callback = callback; ! result->wr_object = object; ! if (callback == NULL) { ! insert_head(result, list); ! } ! else { ! PyWeakReference *prev = (proxy == NULL) ? ref : proxy; ! if (prev == NULL) ! insert_head(result, list); ! else ! insert_after(result, prev); ! } ! PyObject_GC_Track(result); ! } ! } } ! return (PyObject *) result; } --- 68,77 ---- PyObject *object; PyObject *callback = NULL; ! PyObject *result = NULL; ! if (PyArg_ParseTuple(args, "O|O:ref", &object, &callback)) { ! result = PyWeakref_NewRef(object, callback); } ! return result; } *************** *** 667,790 **** PyObject *object; PyObject *callback = NULL; ! PyWeakReference *result = NULL; if (PyArg_ParseTuple(args, "O|O:new", &object, &callback)) { ! PyWeakReference **list; ! PyWeakReference *ref, *proxy; ! ! if (!PyType_SUPPORTS_WEAKREFS(object->ob_type)) { ! PyErr_Format(PyExc_TypeError, ! "'%s' objects are not weakly referencable", ! object->ob_type->tp_name); ! return NULL; ! } ! list = GET_WEAKREFS_LISTPTR(object); ! get_basic_refs(*list, &ref, &proxy); ! if (callback == NULL) { ! /* attempt to return an existing weak reference if it exists */ ! result = proxy; ! Py_XINCREF(result); ! } ! if (result == NULL) { ! result = new_weakref(); ! if (result != NULL) { ! PyWeakReference *prev; ! ! if (PyCallable_Check(object)) ! result->ob_type = &PyWeakCallableProxy_Type; ! else ! result->ob_type = &PyWeakProxy_Type; ! result->wr_object = object; ! Py_XINCREF(callback); ! result->wr_callback = callback; ! if (callback == NULL) ! prev = ref; ! else ! prev = (proxy == NULL) ? ref : proxy; ! ! if (prev == NULL) ! insert_head(result, list); ! else ! insert_after(result, prev); ! PyObject_GC_Track(result); ! } ! } ! } ! return (PyObject *) result; ! } ! ! ! /* This is the implementation of the PyObject_ClearWeakRefs() function; it ! * is installed in the init_weakref() function. It is called by the ! * tp_dealloc handler to clear weak references. ! * ! * This iterates through the weak references for 'object' and calls callbacks ! * for those references which have one. It returns when all callbacks have ! * been attempted. ! */ ! static void ! cleanup_helper(PyObject *object) ! { ! PyWeakReference **list; ! ! if (object == NULL ! || !PyType_SUPPORTS_WEAKREFS(object->ob_type) ! || object->ob_refcnt != 0) { ! PyErr_BadInternalCall(); ! return; ! } ! list = GET_WEAKREFS_LISTPTR(object); ! /* Remove the callback-less basic and proxy references */ ! if (*list != NULL && (*list)->wr_callback == NULL) { ! clear_weakref(*list); ! if (*list != NULL && (*list)->wr_callback == NULL) ! clear_weakref(*list); ! } ! if (*list != NULL) { ! int count = getweakrefcount(*list); ! ! if (count == 1) { ! PyWeakReference *current = *list; ! PyObject *callback = current->wr_callback; ! PyObject *cbresult; ! ! Py_INCREF(callback); ! clear_weakref(current); ! cbresult = PyObject_CallFunction(callback, "O", current); ! if (cbresult == NULL) ! PyErr_WriteUnraisable(callback); ! else ! Py_DECREF(cbresult); ! Py_DECREF(callback); ! } ! else { ! PyObject *tuple = PyTuple_New(count * 2); ! PyWeakReference *current = *list; ! int i = 0; ! ! for (i = 0; i < count; ++i) { ! PyWeakReference *next = current->wr_next; ! ! Py_INCREF(current); ! PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current); ! PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback); ! current->wr_callback = NULL; ! next = current->wr_next; ! clear_weakref(current); ! current = next; ! } ! for (i = 0; i < count; ++i) { ! PyObject *current = PyTuple_GET_ITEM(tuple, i * 2); ! PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1); ! PyObject *cbresult = PyObject_CallFunction(callback, "O", ! current); ! if (cbresult == NULL) ! PyErr_WriteUnraisable(callback); ! else ! Py_DECREF(cbresult); ! } ! Py_DECREF(tuple); ! } } } --- 87,96 ---- PyObject *object; PyObject *callback = NULL; ! PyObject *result = NULL; if (PyArg_ParseTuple(args, "O|O:new", &object, &callback)) { ! result = PyWeakref_NewProxy(object, callback); } + return result; } *************** *** 809,832 **** PyObject *m; - PyWeakReference_Type.ob_type = &PyType_Type; - PyWeakProxy_Type.ob_type = &PyType_Type; - PyWeakCallableProxy_Type.ob_type = &PyType_Type; m = Py_InitModule3("_weakref", weakref_functions, "Weak-reference support module."); if (m != NULL) { ! PyObject_ClearWeakRefs = cleanup_helper; ! Py_INCREF(&PyWeakReference_Type); PyModule_AddObject(m, "ReferenceType", ! (PyObject *) &PyWeakReference_Type); ! Py_INCREF(&PyWeakProxy_Type); PyModule_AddObject(m, "ProxyType", ! (PyObject *) &PyWeakProxy_Type); ! Py_INCREF(&PyWeakCallableProxy_Type); PyModule_AddObject(m, "CallableProxyType", ! (PyObject *) &PyWeakCallableProxy_Type); ! ReferenceError = PyErr_NewException("weakref.ReferenceError", ! PyExc_RuntimeError, NULL); ! if (ReferenceError != NULL) ! PyModule_AddObject(m, "ReferenceError", ReferenceError); } } --- 115,130 ---- PyObject *m; m = Py_InitModule3("_weakref", weakref_functions, "Weak-reference support module."); if (m != NULL) { ! Py_INCREF(&_PyWeakref_RefType); PyModule_AddObject(m, "ReferenceType", ! (PyObject *) &_PyWeakref_RefType); ! Py_INCREF(&_PyWeakref_ProxyType); PyModule_AddObject(m, "ProxyType", ! (PyObject *) &_PyWeakref_ProxyType); ! Py_INCREF(&_PyWeakref_CallableProxyType); PyModule_AddObject(m, "CallableProxyType", ! (PyObject *) &_PyWeakref_CallableProxyType); } } From fdrake@users.sourceforge.net Fri Oct 5 23:04:00 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 15:04:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.152,1.153 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv29523/api Modified Files: api.tex Log Message: Add documentation for the public API for weak reference objects. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.152 retrieving revision 1.153 diff -C2 -d -r1.152 -r1.153 *** api.tex 2001/10/03 21:52:51 1.152 --- api.tex 2001/10/05 22:03:58 1.153 *************** *** 1100,1103 **** --- 1100,1104 ---- \lineiii{PyExc_OSError}{\exception{OSError}}{} \lineiii{PyExc_OverflowError}{\exception{OverflowError}}{} + \lineiii{PyExc_ReferenceError}{\exception{ReferenceError}}{(2)} \lineiii{PyExc_RuntimeError}{\exception{RuntimeError}}{} \lineiii{PyExc_SyntaxError}{\exception{SyntaxError}}{} *************** *** 1106,1110 **** \lineiii{PyExc_TypeError}{\exception{TypeError}}{} \lineiii{PyExc_ValueError}{\exception{ValueError}}{} ! \lineiii{PyExc_WindowsError}{\exception{WindowsError}}{(2)} \lineiii{PyExc_ZeroDivisionError}{\exception{ZeroDivisionError}}{} \end{tableiii} --- 1107,1111 ---- \lineiii{PyExc_TypeError}{\exception{TypeError}}{} \lineiii{PyExc_ValueError}{\exception{ValueError}}{} ! \lineiii{PyExc_WindowsError}{\exception{WindowsError}}{(3)} \lineiii{PyExc_ZeroDivisionError}{\exception{ZeroDivisionError}}{} \end{tableiii} *************** *** 1117,1120 **** --- 1118,1124 ---- \item[(2)] + This is the same as \exception{weakref.ReferenceError}. + + \item[(3)] Only defined on Windows; protect code that uses this by testing that the preprocessor macro \code{MS_WINDOWS} is defined. *************** *** 4500,4503 **** --- 4504,4572 ---- \begin{cfuncdesc}{int}{PySlice_GetIndices}{PySliceObject *slice, int length, int *start, int *stop, int *step} + \end{cfuncdesc} + + + \subsection{Weak Reference Objects \label{weakref-objects}} + + Python supports \emph{weak references} as first-class objects. There + are two specific object types which directly implement weak + references. The first is a simple reference object, and the second + acts as a proxy for the original object as much as it can. + + \begin{cfuncdesc}{int}{PyWeakref_Check}{ob} + Return true if \var{ob} is either a reference or proxy object. + \versionadded{2.2} + \end{cfuncdesc} + + \begin{cfuncdesc}{int}{PyWeakref_CheckRef}{ob} + Return true if \var{ob} is a reference object. + \versionadded{2.2} + \end{cfuncdesc} + + \begin{cfuncdesc}{int}{PyWeakref_CheckProxy}{ob} + Return true if \var{ob} is a proxy object. + \versionadded{2.2} + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyWeakref_NewRef}{PyObject *ob, + PyObject *callback} + Return a weak reference object for the object \var{ob}. This will + always return a new reference, but is not guaranteed to create a new + object; an existing reference object may be returned. The second + parameter, \var{callback}, can be a callable object that receives + notification when \var{ob} is garbage collected; it should accept a + single paramter, which will be the weak reference object itself. + \var{callback} may also be \code{None} or \NULL. If \var{ob} + is not a weakly-referencable object, or if \var{callback} is not + callable, \code{None}, or \NULL, this will return \NULL{} and + raise \exception{TypeError}. + \versionadded{2.2} + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyWeakref_NewProxy}{PyObject *ob, + PyObject *callback} + Return a weak reference proxy object for the object \var{ob}. This + will always return a new reference, but is not guaranteed to create + a new object; an existing proxy object may be returned. The second + parameter, \var{callback}, can be a callable object that receives + notification when \var{ob} is garbage collected; it should accept a + single paramter, which will be the weak reference object itself. + \var{callback} may also be \code{None} or \NULL. If \var{ob} is not + a weakly-referencable object, or if \var{callback} is not callable, + \code{None}, or \NULL, this will return \NULL{} and raise + \exception{TypeError}. + \versionadded{2.2} + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyWeakref_GetObject}{PyObject *ref} + Returns the referenced object from a weak reference, \var{ref}. If + the referent is no longer live, returns \NULL. + \versionadded{2.2} + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyWeakref_GET_OBJECT}{PyObject *ref} + Similar to \cfunction{PyWeakref_GetObject()}, but implemented as a + macro that does no error checking. + \versionadded{2.2} \end{cfuncdesc} From fdrake@users.sourceforge.net Fri Oct 5 23:06:47 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 15:06:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include weakrefobject.h,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv30874/Include Modified Files: weakrefobject.h Log Message: Remove bogus declaration. Index: weakrefobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/weakrefobject.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** weakrefobject.h 2001/10/05 21:52:26 1.1 --- weakrefobject.h 2001/10/05 22:06:45 1.2 *************** *** 23,28 **** extern DL_IMPORT(PyTypeObject) _PyWeakref_CallableProxyType; - extern DL_IMPORT(PyObject *) PyErr_ReferenceError; - #define PyWeakref_CheckRef(op) \ ((op)->ob_type == &_PyWeakref_RefType) --- 23,26 ---- From tim_one@users.sourceforge.net Fri Oct 5 23:14:47 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 05 Oct 2001 15:14:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild pythoncore.dsp,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv2081/python/PCbuild Modified Files: pythoncore.dsp Log Message: Teach Windows how to build the new weakref module. Index: pythoncore.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pythoncore.dsp,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** pythoncore.dsp 2001/09/27 16:28:15 1.23 --- pythoncore.dsp 2001/10/05 22:14:45 1.24 *************** *** 1738,1741 **** --- 1738,1756 ---- # Begin Source File + SOURCE=..\Objects\weakrefobject.c + + !IF "$(CFG)" == "pythoncore - Win32 Release" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Release" + + !ENDIF + + # End Source File + # Begin Source File + SOURCE=..\Modules\xreadlinesmodule.c From tim_one@users.sourceforge.net Sat Oct 6 00:15:13 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 05 Oct 2001 16:15:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv28558/python/Lib Modified Files: profile.py Log Message: The fix to profile semantics broke the miserable but advertised way to derive Profile subclasses. This patch repairs that, restoring negative tuple indices. Yuck? You bet. Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** profile.py 2001/10/04 00:58:24 1.33 --- profile.py 2001/10/05 23:15:10 1.34 *************** *** 110,128 **** used to write into the frames local dictionary!!) Derived classes can change the definition of some entries, as long as they leave ! [3:] intact. ! [0] = Time that needs to be charged to the parent frame's function. ! It is used so that a function call will not have to access the ! timing data for the parent frame. ! [1] = Total time spent in this frame's function, excluding time in ! subfunctions ! [2] = Cumulative time spent in this frame's function, including time in ! all subfunctions to this frame (but excluding this frame!). ! [3] = Name of the function that corresponds to this frame. ! [4] = Actual frame that we correspond to (used to sync exception handling) ! [5] = Our parent 6-tuple (corresponds to frame.f_back) Timing data for each function is stored as a 5-tuple in the dictionary ! self.timings[]. The index is always the name stored in self.cur[4]. The following are the definitions of the members: --- 110,129 ---- used to write into the frames local dictionary!!) Derived classes can change the definition of some entries, as long as they leave ! [-2:] intact (frame and previous tuple). In case an internal error is ! detected, the -3 element is used as the function name. ! [ 0] = Time that needs to be charged to the parent frame's function. ! It is used so that a function call will not have to access the ! timing data for the parent frame. ! [ 1] = Total time spent in this frame's function, excluding time in ! subfunctions ! [ 2] = Cumulative time spent in this frame's function, including time in ! all subfunctions to this frame. ! [-3] = Name of the function that corresponds to this frame. ! [-2] = Actual frame that we correspond to (used to sync exception handling) ! [-1] = Our parent 6-tuple (corresponds to frame.f_back) Timing data for each function is stored as a 5-tuple in the dictionary ! self.timings[]. The index is always the name stored in self.cur[-3]. The following are the definitions of the members: *************** *** 249,253 **** def trace_dispatch_call(self, frame, t): ! if self.cur and frame.f_back is not self.cur[4]: rt, rtt, rct, rfn, rframe, rcur = self.cur if not isinstance(rframe, Profile.fake_frame): --- 250,254 ---- def trace_dispatch_call(self, frame, t): ! if self.cur and frame.f_back is not self.cur[-2]: rt, rtt, rct, rfn, rframe, rcur = self.cur if not isinstance(rframe, Profile.fake_frame): *************** *** 255,262 **** print rframe, rframe.f_back print frame, frame.f_back ! raise "Bad call", self.cur[3] self.trace_dispatch_return(rframe, 0) ! if self.cur and frame.f_back is not self.cur[4]: ! raise "Bad call[2]", self.cur[3] fcode = frame.f_code fn = (fcode.co_filename, fcode.co_firstlineno, fcode.co_name) --- 256,263 ---- print rframe, rframe.f_back print frame, frame.f_back ! raise "Bad call", self.cur[-3] self.trace_dispatch_return(rframe, 0) ! if self.cur and frame.f_back is not self.cur[-2]: ! raise "Bad call[2]", self.cur[-3] fcode = frame.f_code fn = (fcode.co_filename, fcode.co_firstlineno, fcode.co_name) *************** *** 271,279 **** def trace_dispatch_return(self, frame, t): ! if frame is not self.cur[4]: ! if frame is self.cur[4].f_back: ! self.trace_dispatch_return(self.cur[4], 0) else: ! raise "Bad return", self.cur[3] # Prefix "r" means part of the Returning or exiting frame --- 272,280 ---- def trace_dispatch_return(self, frame, t): ! if frame is not self.cur[-2]: ! if frame is self.cur[-2].f_back: ! self.trace_dispatch_return(self.cur[-2], 0) else: ! raise "Bad return", self.cur[-3] # Prefix "r" means part of the Returning or exiting frame *************** *** 318,322 **** def set_cmd(self, cmd): ! if self.cur[5]: return # already set self.cmd = cmd self.simulate_call(cmd) --- 319,323 ---- def set_cmd(self, cmd): ! if self.cur[-1]: return # already set self.cmd = cmd self.simulate_call(cmd) *************** *** 340,344 **** code = self.fake_code('profile', 0, name) if self.cur: ! pframe = self.cur[4] else: pframe = None --- 341,345 ---- code = self.fake_code('profile', 0, name) if self.cur: ! pframe = self.cur[-2] else: pframe = None *************** *** 353,360 **** get_time = self.get_time t = get_time() - self.t ! while self.cur[5]: # We *can* cause assertion errors here if # dispatch_trace_return checks for a frame match! ! a = self.dispatch['return'](self, self.cur[4], t) t = 0 self.t = get_time() - t --- 354,361 ---- get_time = self.get_time t = get_time() - self.t ! while self.cur[-1]: # We *can* cause assertion errors here if # dispatch_trace_return checks for a frame match! ! a = self.dispatch['return'](self, self.cur[-2], t) t = 0 self.t = get_time() - t From fdrake@users.sourceforge.net Sat Oct 6 07:10:56 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 05 Oct 2001 23:10:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libexcs.tex,1.41,1.42 libweakref.tex,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv24028/lib Modified Files: libexcs.tex libweakref.tex Log Message: Update the documentation to reflect the changes to ReferenceError. Index: libexcs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libexcs.tex,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** libexcs.tex 2001/09/21 21:12:30 1.41 --- libexcs.tex 2001/10/06 06:10:54 1.42 *************** *** 238,241 **** --- 238,252 ---- \end{excdesc} + \begin{excdesc}{ReferenceError} + This exception is raised when a weak reference proxy, created by the + \function{\refmodule{weakref}.proxy()} function, is used to access + an attribute of the referent after it has been garbage collected. + For more information on weak references, see the \refmodule{weakref} + module. + \versionadded[Previously known as the + \exception{\refmodule{weakref}.ReferenceError} + exception]{2.2} + \end{excdesc} + \begin{excdesc}{RuntimeError} Raised when an error is detected that doesn't fall in any of the Index: libweakref.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libweakref.tex,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** libweakref.tex 2001/08/03 03:50:28 1.11 --- libweakref.tex 2001/10/06 06:10:54 1.12 *************** *** 112,116 **** \begin{excdesc}{ReferenceError} Exception raised when a proxy object is used but the underlying ! object has been collected. \end{excdesc} --- 112,117 ---- \begin{excdesc}{ReferenceError} Exception raised when a proxy object is used but the underlying ! object has been collected. This is the same as the standard ! \exception{ReferenceError} exception. \end{excdesc} From tim_one@users.sourceforge.net Sat Oct 6 09:03:22 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 01:03:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules gcmodule.c,2.19,2.20 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv13468/python/Modules Modified Files: gcmodule.c Log Message: _PyObject_GC_Malloc(): split a complicated line in two. As is, there was no way to talk the debugger into showing me how many bytes were being allocated. Index: gcmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/gcmodule.c,v retrieving revision 2.19 retrieving revision 2.20 diff -C2 -d -r2.19 -r2.20 *** gcmodule.c 2001/08/30 00:05:51 2.19 --- gcmodule.c 2001/10/06 08:03:20 2.20 *************** *** 803,808 **** PyObject *op; #ifdef WITH_CYCLE_GC ! PyGC_Head *g = PyObject_MALLOC(_PyObject_VAR_SIZE(tp, size) + ! sizeof(PyGC_Head)); if (g == NULL) return (PyObject *)PyErr_NoMemory(); --- 803,809 ---- PyObject *op; #ifdef WITH_CYCLE_GC ! const size_t nbytes = sizeof(PyGC_Head) + ! (size_t)_PyObject_VAR_SIZE(tp, size); ! PyGC_Head *g = PyObject_MALLOC(nbytes); if (g == NULL) return (PyObject *)PyErr_NoMemory(); From tim_one@users.sourceforge.net Sat Oct 6 18:45:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 10:45:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.153,2.154 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv10405/python/Objects Modified Files: object.c Log Message: _PyObject_GetDictPtr(): + Use the _PyObject_VAR_SIZE macro to compute object size. + Break the computation into lines convenient for debugger inspection. + Speed the round-up-to-pointer-size computation. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.153 retrieving revision 2.154 diff -C2 -d -r2.153 -r2.154 *** object.c 2001/10/05 21:58:11 2.153 --- object.c 2001/10/06 17:45:17 2.154 *************** *** 1158,1170 **** return NULL; if (dictoffset < 0) { ! dictoffset += tp->tp_basicsize; ! dictoffset += tp->tp_itemsize * ((PyVarObject *)obj)->ob_size; assert(dictoffset > 0); /* Sanity check */ ! /* Round up, if necessary */ ! if (dictoffset % PTRSIZE != 0) { ! dictoffset /= PTRSIZE; ! dictoffset += 1; ! dictoffset *= PTRSIZE; ! } } return (PyObject **) ((char *)obj + dictoffset); --- 1158,1174 ---- return NULL; if (dictoffset < 0) { ! /* dictoffset is positive by the time we're ready to round ! it, and compilers can generate faster rounding code if ! they know that. */ ! unsigned long udo; /* unsigned dictoffset */ ! const long nitems = ((PyVarObject *)obj)->ob_size; ! const long size = _PyObject_VAR_SIZE(tp, nitems); ! ! dictoffset += size; assert(dictoffset > 0); /* Sanity check */ ! /* Round up to multiple of PTRSIZE. */ ! udo = (unsigned long)dictoffset; ! udo = ((udo + PTRSIZE-1) / PTRSIZE) * PTRSIZE; ! dictoffset = (long)udo; } return (PyObject **) ((char *)obj + dictoffset); From tim_one@users.sourceforge.net Sat Oct 6 20:04:03 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 12:04:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include objimpl.h,2.39,2.40 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv24971/python/Include Modified Files: objimpl.h Log Message: Repaired the debug Windows deaths in test_descr, by allocating enough pad memory to properly align the __dict__ pointer in all cases. gcmodule.c/objimpl.h, _PyObject_GC_Malloc: + Added a "padding" argument so that this flavor of malloc can allocate enough bytes for alignment padding (it can't know this is needed, but its callers do). typeobject.c, PyType_GenericAlloc: + Allocated enough bytes to align the __dict__ pointer. + Sped and simplified the round-up-to-PTRSIZE logic. + Added blank lines so I could parse the if/else blocks <0.7 wink>. Index: objimpl.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/objimpl.h,v retrieving revision 2.39 retrieving revision 2.40 diff -C2 -d -r2.39 -r2.40 *** objimpl.h 2001/10/02 21:24:57 2.39 --- objimpl.h 2001/10/06 19:04:00 2.40 *************** *** 231,235 **** ((o)->ob_type->tp_is_gc == NULL || (o)->ob_type->tp_is_gc(o))) ! extern DL_IMPORT(PyObject *) _PyObject_GC_Malloc(PyTypeObject *, int); extern DL_IMPORT(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, int); --- 231,236 ---- ((o)->ob_type->tp_is_gc == NULL || (o)->ob_type->tp_is_gc(o))) ! extern DL_IMPORT(PyObject *) _PyObject_GC_Malloc(PyTypeObject *, ! int nitems, size_t padding); extern DL_IMPORT(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, int); From tim_one@users.sourceforge.net Sat Oct 6 20:04:03 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 12:04:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.90,2.91 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv24971/python/Objects Modified Files: typeobject.c Log Message: Repaired the debug Windows deaths in test_descr, by allocating enough pad memory to properly align the __dict__ pointer in all cases. gcmodule.c/objimpl.h, _PyObject_GC_Malloc: + Added a "padding" argument so that this flavor of malloc can allocate enough bytes for alignment padding (it can't know this is needed, but its callers do). typeobject.c, PyType_GenericAlloc: + Allocated enough bytes to align the __dict__ pointer. + Sped and simplified the round-up-to-PTRSIZE logic. + Added blank lines so I could parse the if/else blocks <0.7 wink>. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.90 retrieving revision 2.91 diff -C2 -d -r2.90 -r2.91 *** typeobject.c 2001/10/05 20:51:39 2.90 --- typeobject.c 2001/10/06 19:04:01 2.91 *************** *** 193,222 **** #define PTRSIZE (sizeof(PyObject *)) ! int size; PyObject *obj; ! /* Inline PyObject_New() so we can zero the memory */ ! size = _PyObject_VAR_SIZE(type, nitems); ! /* Round up size, if necessary, so we fully zero out __dict__ */ ! if (type->tp_itemsize % PTRSIZE != 0) { ! size += PTRSIZE - 1; ! size /= PTRSIZE; ! size *= PTRSIZE; ! } ! if (PyType_IS_GC(type)) { ! obj = _PyObject_GC_Malloc(type, nitems); } ! else { obj = PyObject_MALLOC(size); ! } if (obj == NULL) return PyErr_NoMemory(); memset(obj, '\0', size); if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) Py_INCREF(type); if (type->tp_itemsize == 0) PyObject_INIT(obj, type); else (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems); if (PyType_IS_GC(type)) _PyObject_GC_TRACK(obj); --- 193,232 ---- #define PTRSIZE (sizeof(PyObject *)) ! size_t size = (size_t)_PyObject_VAR_SIZE(type, nitems); ! size_t padding = 0; PyObject *obj; ! /* Round up size, if necessary, so that the __dict__ pointer ! following the variable part is properly aligned for the platform. ! This is needed only for types with a vrbl number of items ! before the __dict__ pointer == types that record the dict offset ! as a negative offset from the end of the object. If tp_dictoffset ! is 0, there is no __dict__; if positive, tp_dict was declared in a C ! struct so the compiler already took care of aligning it. */ ! if (type->tp_dictoffset < 0) { ! padding = PTRSIZE - size % PTRSIZE; ! if (padding == PTRSIZE) ! padding = 0; ! size += padding; } ! ! if (PyType_IS_GC(type)) ! obj = _PyObject_GC_Malloc(type, nitems, padding); ! else obj = PyObject_MALLOC(size); ! if (obj == NULL) return PyErr_NoMemory(); + memset(obj, '\0', size); + if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) Py_INCREF(type); + if (type->tp_itemsize == 0) PyObject_INIT(obj, type); else (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems); + if (PyType_IS_GC(type)) _PyObject_GC_TRACK(obj); From tim_one@users.sourceforge.net Sat Oct 6 20:04:03 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 12:04:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules gcmodule.c,2.20,2.21 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv24971/python/Modules Modified Files: gcmodule.c Log Message: Repaired the debug Windows deaths in test_descr, by allocating enough pad memory to properly align the __dict__ pointer in all cases. gcmodule.c/objimpl.h, _PyObject_GC_Malloc: + Added a "padding" argument so that this flavor of malloc can allocate enough bytes for alignment padding (it can't know this is needed, but its callers do). typeobject.c, PyType_GenericAlloc: + Allocated enough bytes to align the __dict__ pointer. + Sped and simplified the round-up-to-PTRSIZE logic. + Added blank lines so I could parse the if/else blocks <0.7 wink>. Index: gcmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/gcmodule.c,v retrieving revision 2.20 retrieving revision 2.21 diff -C2 -d -r2.20 -r2.21 *** gcmodule.c 2001/10/06 08:03:20 2.20 --- gcmodule.c 2001/10/06 19:04:00 2.21 *************** *** 799,809 **** PyObject * ! _PyObject_GC_Malloc(PyTypeObject *tp, int size) { PyObject *op; #ifdef WITH_CYCLE_GC ! const size_t nbytes = sizeof(PyGC_Head) + ! (size_t)_PyObject_VAR_SIZE(tp, size); ! PyGC_Head *g = PyObject_MALLOC(nbytes); if (g == NULL) return (PyObject *)PyErr_NoMemory(); --- 799,810 ---- PyObject * ! _PyObject_GC_Malloc(PyTypeObject *tp, int nitems, size_t padding) { PyObject *op; #ifdef WITH_CYCLE_GC ! const size_t basic = (size_t)_PyObject_VAR_SIZE(tp, nitems); ! const size_t nbytes = sizeof(PyGC_Head) + basic + padding; ! ! PyGC_Head *g = PyObject_MALLOC(nbytes); if (g == NULL) return (PyObject *)PyErr_NoMemory(); *************** *** 821,825 **** op = FROM_GC(g); #else ! op = PyObject_MALLOC(_PyObject_VAR_SIZE(tp, size)); if (op == NULL) return (PyObject *)PyErr_NoMemory(); --- 822,826 ---- op = FROM_GC(g); #else ! op = PyObject_MALLOC(_PyObject_VAR_SIZE(tp, nitems) + padding); if (op == NULL) return (PyObject *)PyErr_NoMemory(); *************** *** 832,836 **** _PyObject_GC_New(PyTypeObject *tp) { ! PyObject *op = _PyObject_GC_Malloc(tp, 0); return PyObject_INIT(op, tp); } --- 833,837 ---- _PyObject_GC_New(PyTypeObject *tp) { ! PyObject *op = _PyObject_GC_Malloc(tp, 0, 0); return PyObject_INIT(op, tp); } *************** *** 839,843 **** _PyObject_GC_NewVar(PyTypeObject *tp, int size) { ! PyVarObject *op = (PyVarObject *) _PyObject_GC_Malloc(tp, size); return PyObject_INIT_VAR(op, tp, size); } --- 840,844 ---- _PyObject_GC_NewVar(PyTypeObject *tp, int size) { ! PyVarObject *op = (PyVarObject *) _PyObject_GC_Malloc(tp, size, 0); return PyObject_INIT_VAR(op, tp, size); } From tim_one@users.sourceforge.net Sat Oct 6 22:27:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 14:27:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include objimpl.h,2.40,2.41 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv19908/python/Include Modified Files: objimpl.h Log Message: _PyObject_VAR_SIZE: always round up to a multiple-of-pointer-size value. As Guido suggested, this makes the new subclassing code substantially simpler. But the mechanics of doing it w/ C macro semantics are a mess, and _PyObject_VAR_SIZE has a new calling sequence now. Question: The PyObject_NEW_VAR macro appears to be part of the public API. Regardless of what it expands to, the notion that it has to round up the memory it allocates is new, and extensions containing the old PyObject_NEW_VAR macro expansion (which was embedded in the PyObject_NEW_VAR expansion) won't do this rounding. But the rounding isn't actually *needed* except for new-style instances with dict pointers after a variable-length blob of embedded data. So my guess is that we do not need to bump the API version for this (as the rounding isn't needed for anything an extension can do unless it's recompiled anyway). What's your guess? Index: objimpl.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/objimpl.h,v retrieving revision 2.40 retrieving revision 2.41 diff -C2 -d -r2.40 -r2.41 *** objimpl.h 2001/10/06 19:04:00 2.40 --- objimpl.h 2001/10/06 21:27:34 2.41 *************** *** 57,61 **** recommended to use PyObject_{New, NewVar, Del}. */ ! /* * Core object memory allocator * ============================ --- 57,61 ---- recommended to use PyObject_{New, NewVar, Del}. */ ! /* * Core object memory allocator * ============================ *************** *** 64,68 **** /* The purpose of the object allocator is to make the distinction between "object memory" and the rest within the Python heap. ! Object memory is the one allocated by PyObject_{New, NewVar}, i.e. the one that holds the object's representation defined by its C --- 64,68 ---- /* The purpose of the object allocator is to make the distinction between "object memory" and the rest within the Python heap. ! Object memory is the one allocated by PyObject_{New, NewVar}, i.e. the one that holds the object's representation defined by its C *************** *** 173,186 **** #define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) ! #define _PyObject_VAR_SIZE(typeobj, n) \ ! ( (typeobj)->tp_basicsize + (n) * (typeobj)->tp_itemsize ) #define PyObject_NEW(type, typeobj) \ ( (type *) PyObject_Init( \ (PyObject *) PyObject_MALLOC( _PyObject_SIZE(typeobj) ), (typeobj)) ) ! #define PyObject_NEW_VAR(type, typeobj, n) \ ! ( (type *) PyObject_InitVar( \ ! (PyVarObject *) PyObject_MALLOC( _PyObject_VAR_SIZE((typeobj),(n)) ),\ ! (typeobj), (n)) ) #define PyObject_DEL(op) PyObject_FREE(op) --- 173,211 ---- #define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) ! ! /* _PyObject_VAR_SIZE computes the amount of memory allocated for a vrbl- ! size object with nitems items, exclusive of gc overhead (if any). The ! value is rounded up to the closest multiple of sizeof(void *), in order ! to ensure that pointer fields at the end of the object are correctly ! aligned for the platform (this is of special importance for subclasses ! of, e.g., str or long, so that pointers can be stored after the embedded ! data). ! ! Note that there's no memory wastage in doing this, as malloc has to ! return (at worst) pointer-aligned memory anyway ! ! However, writing the macro to *return* the result is clumsy due to the ! calculations needed. Instead you must pass the result lvalue as the first ! argument, and it should be of type size_t (both because that's the ! correct conceptual type, and because using an unsigned type allows the ! compiler to generate faster code for the mod computation inside the ! macro). ! */ ! #define _PyObject_VAR_SIZE(result, typeobj, nitems) \ ! do { \ ! size_t mod; \ ! (result) = (size_t) (typeobj)->tp_basicsize; \ ! (result) += (size_t) ((nitems)*(typeobj)->tp_itemsize); \ ! mod = (result) % SIZEOF_VOID_P; \ ! if (mod) \ ! (result) += SIZEOF_VOID_P - mod; \ ! } while(0) #define PyObject_NEW(type, typeobj) \ ( (type *) PyObject_Init( \ (PyObject *) PyObject_MALLOC( _PyObject_SIZE(typeobj) ), (typeobj)) ) ! ! #define PyObject_NEW_VAR(type, typeobj, nitems) \ ! ((type *) _PyObject_NewVar(typeobj, nitems)) #define PyObject_DEL(op) PyObject_FREE(op) *************** *** 231,236 **** ((o)->ob_type->tp_is_gc == NULL || (o)->ob_type->tp_is_gc(o))) ! extern DL_IMPORT(PyObject *) _PyObject_GC_Malloc(PyTypeObject *, ! int nitems, size_t padding); extern DL_IMPORT(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, int); --- 256,260 ---- ((o)->ob_type->tp_is_gc == NULL || (o)->ob_type->tp_is_gc(o))) ! extern DL_IMPORT(PyObject *) _PyObject_GC_Malloc(PyTypeObject *, int); extern DL_IMPORT(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, int); *************** *** 277,281 **** #define PyObject_GC_Track(op) _PyObject_GC_Track((PyObject *)op) #define PyObject_GC_UnTrack(op) _PyObject_GC_UnTrack((PyObject *)op) ! #define PyObject_GC_New(type, typeobj) \ --- 301,305 ---- #define PyObject_GC_Track(op) _PyObject_GC_Track((PyObject *)op) #define PyObject_GC_UnTrack(op) _PyObject_GC_UnTrack((PyObject *)op) ! #define PyObject_GC_New(type, typeobj) \ From tim_one@users.sourceforge.net Sat Oct 6 22:27:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 14:27:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.154,2.155 typeobject.c,2.91,2.92 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv19908/python/Objects Modified Files: object.c typeobject.c Log Message: _PyObject_VAR_SIZE: always round up to a multiple-of-pointer-size value. As Guido suggested, this makes the new subclassing code substantially simpler. But the mechanics of doing it w/ C macro semantics are a mess, and _PyObject_VAR_SIZE has a new calling sequence now. Question: The PyObject_NEW_VAR macro appears to be part of the public API. Regardless of what it expands to, the notion that it has to round up the memory it allocates is new, and extensions containing the old PyObject_NEW_VAR macro expansion (which was embedded in the PyObject_NEW_VAR expansion) won't do this rounding. But the rounding isn't actually *needed* except for new-style instances with dict pointers after a variable-length blob of embedded data. So my guess is that we do not need to bump the API version for this (as the rounding isn't needed for anything an extension can do unless it's recompiled anyway). What's your guess? Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.154 retrieving revision 2.155 diff -C2 -d -r2.154 -r2.155 *** object.c 2001/10/06 17:45:17 2.154 --- object.c 2001/10/06 21:27:34 2.155 *************** *** 128,138 **** PyVarObject * ! _PyObject_NewVar(PyTypeObject *tp, int size) { PyVarObject *op; ! op = (PyVarObject *) PyObject_MALLOC(_PyObject_VAR_SIZE(tp, size)); if (op == NULL) return (PyVarObject *)PyErr_NoMemory(); ! return PyObject_INIT_VAR(op, tp, size); } --- 128,141 ---- PyVarObject * ! _PyObject_NewVar(PyTypeObject *tp, int nitems) { PyVarObject *op; ! size_t size; ! ! _PyObject_VAR_SIZE(size, tp, nitems); ! op = (PyVarObject *) PyObject_MALLOC(size); if (op == NULL) return (PyVarObject *)PyErr_NoMemory(); ! return PyObject_INIT_VAR(op, tp, nitems); } *************** *** 1147,1152 **** _PyObject_GetDictPtr(PyObject *obj) { - #define PTRSIZE (sizeof(PyObject *)) - long dictoffset; PyTypeObject *tp = obj->ob_type; --- 1150,1153 ---- *************** *** 1158,1174 **** return NULL; if (dictoffset < 0) { ! /* dictoffset is positive by the time we're ready to round ! it, and compilers can generate faster rounding code if ! they know that. */ ! unsigned long udo; /* unsigned dictoffset */ ! const long nitems = ((PyVarObject *)obj)->ob_size; ! const long size = _PyObject_VAR_SIZE(tp, nitems); ! ! dictoffset += size; ! assert(dictoffset > 0); /* Sanity check */ ! /* Round up to multiple of PTRSIZE. */ ! udo = (unsigned long)dictoffset; ! udo = ((udo + PTRSIZE-1) / PTRSIZE) * PTRSIZE; ! dictoffset = (long)udo; } return (PyObject **) ((char *)obj + dictoffset); --- 1159,1167 ---- return NULL; if (dictoffset < 0) { ! size_t size; ! _PyObject_VAR_SIZE(size, tp, ((PyVarObject *)obj)->ob_size); ! dictoffset += (long)size; ! assert(dictoffset > 0); ! assert(dictoffset % SIZEOF_VOID_P == 0); } return (PyObject **) ((char *)obj + dictoffset); Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.91 retrieving revision 2.92 diff -C2 -d -r2.91 -r2.92 *** typeobject.c 2001/10/06 19:04:01 2.91 --- typeobject.c 2001/10/06 21:27:34 2.92 *************** *** 191,216 **** PyType_GenericAlloc(PyTypeObject *type, int nitems) { - #define PTRSIZE (sizeof(PyObject *)) - - size_t size = (size_t)_PyObject_VAR_SIZE(type, nitems); - size_t padding = 0; PyObject *obj; ! /* Round up size, if necessary, so that the __dict__ pointer ! following the variable part is properly aligned for the platform. ! This is needed only for types with a vrbl number of items ! before the __dict__ pointer == types that record the dict offset ! as a negative offset from the end of the object. If tp_dictoffset ! is 0, there is no __dict__; if positive, tp_dict was declared in a C ! struct so the compiler already took care of aligning it. */ ! if (type->tp_dictoffset < 0) { ! padding = PTRSIZE - size % PTRSIZE; ! if (padding == PTRSIZE) ! padding = 0; ! size += padding; ! } if (PyType_IS_GC(type)) ! obj = _PyObject_GC_Malloc(type, nitems, padding); else obj = PyObject_MALLOC(size); --- 191,201 ---- PyType_GenericAlloc(PyTypeObject *type, int nitems) { PyObject *obj; + size_t size; ! _PyObject_VAR_SIZE(size, type, nitems); if (PyType_IS_GC(type)) ! obj = _PyObject_GC_Malloc(type, nitems); else obj = PyObject_MALLOC(size); From tim_one@users.sourceforge.net Sat Oct 6 22:27:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 14:27:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules gcmodule.c,2.21,2.22 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv19908/python/Modules Modified Files: gcmodule.c Log Message: _PyObject_VAR_SIZE: always round up to a multiple-of-pointer-size value. As Guido suggested, this makes the new subclassing code substantially simpler. But the mechanics of doing it w/ C macro semantics are a mess, and _PyObject_VAR_SIZE has a new calling sequence now. Question: The PyObject_NEW_VAR macro appears to be part of the public API. Regardless of what it expands to, the notion that it has to round up the memory it allocates is new, and extensions containing the old PyObject_NEW_VAR macro expansion (which was embedded in the PyObject_NEW_VAR expansion) won't do this rounding. But the rounding isn't actually *needed* except for new-style instances with dict pointers after a variable-length blob of embedded data. So my guess is that we do not need to bump the API version for this (as the rounding isn't needed for anything an extension can do unless it's recompiled anyway). What's your guess? Index: gcmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/gcmodule.c,v retrieving revision 2.21 retrieving revision 2.22 diff -C2 -d -r2.21 -r2.22 *** gcmodule.c 2001/10/06 19:04:00 2.21 --- gcmodule.c 2001/10/06 21:27:34 2.22 *************** *** 799,810 **** PyObject * ! _PyObject_GC_Malloc(PyTypeObject *tp, int nitems, size_t padding) { PyObject *op; #ifdef WITH_CYCLE_GC ! const size_t basic = (size_t)_PyObject_VAR_SIZE(tp, nitems); ! const size_t nbytes = sizeof(PyGC_Head) + basic + padding; ! PyGC_Head *g = PyObject_MALLOC(nbytes); if (g == NULL) return (PyObject *)PyErr_NoMemory(); --- 799,813 ---- PyObject * ! _PyObject_GC_Malloc(PyTypeObject *tp, int nitems) { PyObject *op; + size_t basicsize; #ifdef WITH_CYCLE_GC ! size_t nbytes; ! PyGC_Head *g; ! _PyObject_VAR_SIZE(basicsize, tp, nitems); ! nbytes = sizeof(PyGC_Head) + basicsize; ! g = PyObject_MALLOC(nbytes); if (g == NULL) return (PyObject *)PyErr_NoMemory(); *************** *** 822,826 **** op = FROM_GC(g); #else ! op = PyObject_MALLOC(_PyObject_VAR_SIZE(tp, nitems) + padding); if (op == NULL) return (PyObject *)PyErr_NoMemory(); --- 825,830 ---- op = FROM_GC(g); #else ! _PyObject_VAR_SIZE(basicsize, tp, nitems); ! op = PyObject_MALLOC(basicsize); if (op == NULL) return (PyObject *)PyErr_NoMemory(); *************** *** 833,863 **** _PyObject_GC_New(PyTypeObject *tp) { ! PyObject *op = _PyObject_GC_Malloc(tp, 0, 0); return PyObject_INIT(op, tp); } PyVarObject * ! _PyObject_GC_NewVar(PyTypeObject *tp, int size) { ! PyVarObject *op = (PyVarObject *) _PyObject_GC_Malloc(tp, size, 0); ! return PyObject_INIT_VAR(op, tp, size); } PyVarObject * ! _PyObject_GC_Resize(PyVarObject *op, int size) { #ifdef WITH_CYCLE_GC PyGC_Head *g = AS_GC(op); ! g = PyObject_REALLOC(g, _PyObject_VAR_SIZE(op->ob_type, size) + ! sizeof(PyGC_Head)); if (g == NULL) return (PyVarObject *)PyErr_NoMemory(); op = (PyVarObject *) FROM_GC(g); #else ! op = PyObject_REALLOC(op, _PyObject_VAR_SIZE(op->ob_type, size)); if (op == NULL) return (PyVarObject *)PyErr_NoMemory(); #endif ! op->ob_size = size; return op; } --- 837,870 ---- _PyObject_GC_New(PyTypeObject *tp) { ! PyObject *op = _PyObject_GC_Malloc(tp, 0); return PyObject_INIT(op, tp); } PyVarObject * ! _PyObject_GC_NewVar(PyTypeObject *tp, int nitems) { ! PyVarObject *op = (PyVarObject *) _PyObject_GC_Malloc(tp, nitems); ! return PyObject_INIT_VAR(op, tp, nitems); } PyVarObject * ! _PyObject_GC_Resize(PyVarObject *op, int nitems) { + size_t basicsize; #ifdef WITH_CYCLE_GC PyGC_Head *g = AS_GC(op); ! ! _PyObject_VAR_SIZE(basicsize, op->ob_type, nitems); ! g = PyObject_REALLOC(g, sizeof(PyGC_Head) + basicsize); if (g == NULL) return (PyVarObject *)PyErr_NoMemory(); op = (PyVarObject *) FROM_GC(g); #else ! _PyObject_VAR_SIZE(basicsize, op->ob_type, nitems); ! op = PyObject_REALLOC(op, basicsize); if (op == NULL) return (PyVarObject *)PyErr_NoMemory(); #endif ! op->ob_size = nitems; return op; } From tim_one@users.sourceforge.net Sun Oct 7 04:12:10 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 20:12:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv28021/python/Lib Modified Files: profile.py Log Message: Remove code and docs for the OldProfile and HotProfile classes: code hasn't worked in years, docs were wrong, and they aren't interesting anymore regardless. Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** profile.py 2001/10/05 23:15:10 1.34 --- profile.py 2001/10/07 03:12:08 1.35 *************** *** 498,616 **** self.ut = t - - - class OldProfile(Profile): - """A derived profiler that simulates the old style profile, providing - errant results on recursive functions. The reason for the usefulness of - this profiler is that it runs faster (i.e., less overhead). It still - creates all the caller stats, and is quite useful when there is *no* - recursion in the user's code. - - This code also shows how easy it is to create a modified profiler. - """ - - def trace_dispatch_exception(self, frame, t): - rt, rtt, rct, rfn, rframe, rcur = self.cur - if rcur and not rframe is frame: - return self.trace_dispatch_return(rframe, t) - return 0 - - def trace_dispatch_call(self, frame, t): - fn = `frame.f_code` - - self.cur = (t, 0, 0, fn, frame, self.cur) - if self.timings.has_key(fn): - tt, ct, callers = self.timings[fn] - self.timings[fn] = tt, ct, callers - else: - self.timings[fn] = 0, 0, {} - return 1 - - def trace_dispatch_return(self, frame, t): - rt, rtt, rct, rfn, frame, rcur = self.cur - rtt = rtt + t - sft = rtt + rct - - pt, ptt, pct, pfn, pframe, pcur = rcur - self.cur = pt, ptt+rt, pct+sft, pfn, pframe, pcur - - tt, ct, callers = self.timings[rfn] - if callers.has_key(pfn): - callers[pfn] = callers[pfn] + 1 - else: - callers[pfn] = 1 - self.timings[rfn] = tt+rtt, ct + sft, callers - - return 1 - - - dispatch = { - "call": trace_dispatch_call, - "exception": trace_dispatch_exception, - "return": trace_dispatch_return, - } - - - def snapshot_stats(self): - self.stats = {} - for func in self.timings.keys(): - tt, ct, callers = self.timings[func] - callers = callers.copy() - nc = 0 - for func_caller in callers.keys(): - nc = nc + callers[func_caller] - self.stats[func] = nc, nc, tt, ct, callers - - - - class HotProfile(Profile): - """The fastest derived profile example. It does not calculate - caller-callee relationships, and does not calculate cumulative - time under a function. It only calculates time spent in a - function, so it runs very quickly due to its very low overhead. - """ - - def trace_dispatch_exception(self, frame, t): - rt, rtt, rfn, rframe, rcur = self.cur - if rcur and not rframe is frame: - return self.trace_dispatch_return(rframe, t) - return 0 - - def trace_dispatch_call(self, frame, t): - self.cur = (t, 0, frame, self.cur) - return 1 - - def trace_dispatch_return(self, frame, t): - rt, rtt, frame, rcur = self.cur - - rfn = `frame.f_code` - - pt, ptt, pframe, pcur = rcur - self.cur = pt, ptt+rt, pframe, pcur - - if self.timings.has_key(rfn): - nc, tt = self.timings[rfn] - self.timings[rfn] = nc + 1, rt + rtt + tt - else: - self.timings[rfn] = 1, rt + rtt - - return 1 - - - dispatch = { - "call": trace_dispatch_call, - "exception": trace_dispatch_exception, - "return": trace_dispatch_return, - } - - - def snapshot_stats(self): - self.stats = {} - for func in self.timings.keys(): - nc, tt = self.timings[func] - self.stats[func] = nc, nc, tt, 0, {} - - - #**************************************************************************** def Stats(*args): --- 498,501 ---- From tim_one@users.sourceforge.net Sun Oct 7 04:12:11 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 20:12:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.271,1.272 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv28021/python/Misc Modified Files: NEWS Log Message: Remove code and docs for the OldProfile and HotProfile classes: code hasn't worked in years, docs were wrong, and they aren't interesting anymore regardless. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.271 retrieving revision 1.272 diff -C2 -d -r1.271 -r1.272 *** NEWS 2001/10/04 22:46:41 1.271 --- NEWS 2001/10/07 03:12:08 1.272 *************** *** 39,42 **** --- 39,51 ---- functions and attribution of time spent to the wrong function. + The code and documentation for the derived OldProfile and HotProfile + profiling classes was removed. The code hasn't worked for years (if + you tried to use them, they raised exceptions). OldProfile + intended to reproduce the behavior of the profiler Python used more + than 7 years ago, and isn't interesting anymore. HotProfile intended + to provide a faster profiler (but producing less information), and + that's a worthy goal we intend to meet via a different approach (but + without losing information). + - quopri's encode and decode methods take an optional header parameter, which indicates whether output is intended for the header 'Q' encoding. From tim_one@users.sourceforge.net Sun Oct 7 04:12:10 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 20:12:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libprofile.tex,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv28021/python/Doc/lib Modified Files: libprofile.tex Log Message: Remove code and docs for the OldProfile and HotProfile classes: code hasn't worked in years, docs were wrong, and they aren't interesting anymore regardless. Index: libprofile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libprofile.tex,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** libprofile.tex 2001/07/06 20:30:11 1.36 --- libprofile.tex 2001/10/07 03:12:08 1.37 *************** *** 211,215 **** \end{verbatim} ! and you would get a list of callers for each of the listed functions. If you want more functionality, you're going to have to read the --- 211,215 ---- \end{verbatim} ! and you would get a list of callers for each of the listed functions. If you want more functionality, you're going to have to read the *************** *** 310,314 **** \item[ncalls ] ! for the number of calls, \item[tottime ] --- 310,314 ---- \item[ncalls ] ! for the number of calls, \item[tottime ] *************** *** 407,411 **** Abbreviations can be used for any key names, as long as the abbreviation is unambiguous. The following are the keys currently ! defined: \begin{tableii}{l|l}{code}{Valid Arg}{Meaning} --- 407,411 ---- Abbreviations can be used for any key names, as long as the abbreviation is unambiguous. The following are the keys currently ! defined: \begin{tableii}{l|l}{code}{Valid Arg}{Meaning} *************** *** 629,643 **** The \class{Profile} class of module \module{profile} was written so that ! derived classes could be developed to extend the profiler. Rather ! than describing all the details of such an effort, I'll just present ! the following two examples of derived classes that can be used to do ! profiling. If the reader is an avid Python programmer, then it should ! be possible to use these as a model and create similar (and perchance ! better) profile classes. ! If all you want to do is change how the timer is called, or which ! timer function is used, then the basic class has an option for that in ! the constructor for the class. Consider passing the name of a ! function to call into the constructor: \begin{verbatim} --- 629,642 ---- The \class{Profile} class of module \module{profile} was written so that ! derived classes could be developed to extend the profiler. The details ! are not described here, as doing this successfully requires an expert ! understanding of how the \class{Profile} class works internally. Study ! the source code of module \module{profile} carefully if you want to ! pursue this. ! If all you want to do is change how current time is determined (for ! example, to force use of wall-clock time or elapsed process time), ! pass the timing function you want to the \class{Profile} class ! constructor: \begin{verbatim} *************** *** 645,808 **** \end{verbatim} ! The resulting profiler will call \code{your_time_func()} instead of ! \function{os.times()}. The function should return either a single number ! or a list of numbers (like what \function{os.times()} returns). If the ! function returns a single time number, or the list of returned numbers ! has length 2, then you will get an especially fast version of the ! dispatch routine. ! Be warned that you \emph{should} calibrate the profiler class for the timer function that you choose. For most machines, a timer that returns a lone integer value will provide the best results in terms of low overhead during profiling. (\function{os.times()} is ! \emph{pretty} bad, as it returns a tuple of floating point values, ! so all arithmetic is floating point in the profiler!). If you want to ! substitute a better timer in the cleanest fashion, you should derive a ! class, and simply put in the replacement dispatch method that better handles your timer call, along with the appropriate calibration constant. - - Note that subclasses which override any of the - \method{trace_dispatch_call()}, \method{trace_dispatch_exception()}, - or \method{trace_dispatch_return()} methods also need to specify a - dispatch table as well. The table, named \member{dispatch}, should - have the three keys \code{'call'}, \code{'exception'}, and - \code{'return'}, each giving the function of the corresponding - handler. Note that best performance is achieved by using the - \emph{function} objects for the handlers and not bound methods. This - is preferred since calling a simple function object executes less code - in the runtime than calling either bound or unbound methods. For - example, if the derived profiler overrides only one method, the - \member{dispatch} table can be built like this: - - \begin{verbatim} - from profile import Profile - - class MyProfiler(Profile): - def trace_dispath_call(self, frame, t): - # do something interesting here - ... - - dispatch = { - 'call': trace_dispatch_call, - 'exception': Profile.__dict__['trace_dispatch_exception'], - 'return': Profile.__dict__['trace_dispatch_return'], - } - \end{verbatim} - - - \subsection{OldProfile Class \label{profile-old}} - - The following derived profiler simulates the old style profiler, - providing errant results on recursive functions. The reason for the - usefulness of this profiler is that it runs faster (less - overhead) than the new profiler. It still creates all the caller - stats, and is quite useful when there is \emph{no} recursion in the - user's code. It is also a lot more accurate than the old profiler, as - it does not charge all its overhead time to the user's code. - - \begin{verbatim} - class OldProfile(Profile): - - def trace_dispatch_exception(self, frame, t): - rt, rtt, rct, rfn, rframe, rcur = self.cur - if rcur and not rframe is frame: - return self.trace_dispatch_return(rframe, t) - return 0 - - def trace_dispatch_call(self, frame, t): - fn = `frame.f_code` - - self.cur = (t, 0, 0, fn, frame, self.cur) - if self.timings.has_key(fn): - tt, ct, callers = self.timings[fn] - self.timings[fn] = tt, ct, callers - else: - self.timings[fn] = 0, 0, {} - return 1 - - def trace_dispatch_return(self, frame, t): - rt, rtt, rct, rfn, frame, rcur = self.cur - rtt = rtt + t - sft = rtt + rct - - pt, ptt, pct, pfn, pframe, pcur = rcur - self.cur = pt, ptt+rt, pct+sft, pfn, pframe, pcur - - tt, ct, callers = self.timings[rfn] - if callers.has_key(pfn): - callers[pfn] = callers[pfn] + 1 - else: - callers[pfn] = 1 - self.timings[rfn] = tt+rtt, ct + sft, callers - - return 1 - - dispatch = { - "call": trace_dispatch_call, - "exception": trace_dispatch_exception, - "return": trace_dispatch_return, - } - - def snapshot_stats(self): - self.stats = {} - for func in self.timings.keys(): - tt, ct, callers = self.timings[func] - callers = callers.copy() - nc = 0 - for func_caller in callers.keys(): - nc = nc + callers[func_caller] - self.stats[func] = nc, nc, tt, ct, callers - \end{verbatim} - - - \subsection{HotProfile Class \label{profile-HotProfile}} - - This profiler is the fastest derived profile example. It does not - calculate caller-callee relationships, and does not calculate - cumulative time under a function. It only calculates time spent in a - function, so it runs very quickly (re: very low overhead). In truth, - the basic profiler is so fast, that is probably not worth the savings - to give up the data, but this class still provides a nice example. - - \begin{verbatim} - class HotProfile(Profile): - - def trace_dispatch_exception(self, frame, t): - rt, rtt, rfn, rframe, rcur = self.cur - if rcur and not rframe is frame: - return self.trace_dispatch_return(rframe, t) - return 0 - - def trace_dispatch_call(self, frame, t): - self.cur = (t, 0, frame, self.cur) - return 1 - - def trace_dispatch_return(self, frame, t): - rt, rtt, frame, rcur = self.cur - - rfn = `frame.f_code` - - pt, ptt, pframe, pcur = rcur - self.cur = pt, ptt+rt, pframe, pcur - - if self.timings.has_key(rfn): - nc, tt = self.timings[rfn] - self.timings[rfn] = nc + 1, rt + rtt + tt - else: - self.timings[rfn] = 1, rt + rtt - - return 1 - - dispatch = { - "call": trace_dispatch_call, - "exception": trace_dispatch_exception, - "return": trace_dispatch_return, - } - - def snapshot_stats(self): - self.stats = {} - for func in self.timings.keys(): - nc, tt = self.timings[func] - self.stats[func] = nc, nc, tt, 0, {} - \end{verbatim} --- 644,661 ---- \end{verbatim} ! The resulting profiler will then call \code{your_time_func()}. ! The function should return a single number, or a list of ! numbers whose sum is the current time (like what \function{os.times()} ! returns). If the function returns a single time number, or the list of ! returned numbers has length 2, then you will get an especially fast ! version of the dispatch routine. ! Be warned that you should calibrate the profiler class for the timer function that you choose. For most machines, a timer that returns a lone integer value will provide the best results in terms of low overhead during profiling. (\function{os.times()} is ! \emph{pretty} bad, as it returns a tuple of floating point values). If ! you want to substitute a better timer in the cleanest fashion, ! derive a class and hardwire a replacement dispatch method that best handles your timer call, along with the appropriate calibration constant. From tim_one@users.sourceforge.net Sun Oct 7 04:54:53 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 20:54:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include objimpl.h,2.41,2.42 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv14609/python/Include Modified Files: objimpl.h Log Message: Guido suggests, and I agree, to insist that SIZEOF_VOID_P be a power of 2. This simplifies the rounding in _PyObject_VAR_SIZE, allows to restore the pre-rounding calling sequence, and allows some nice little simplifications in its callers. I'm still making it return a size_t, though. Index: objimpl.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/objimpl.h,v retrieving revision 2.41 retrieving revision 2.42 diff -C2 -d -r2.41 -r2.42 *** objimpl.h 2001/10/06 21:27:34 2.41 --- objimpl.h 2001/10/07 03:54:51 2.42 *************** *** 174,211 **** #define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) ! /* _PyObject_VAR_SIZE computes the amount of memory allocated for a vrbl- ! size object with nitems items, exclusive of gc overhead (if any). The ! value is rounded up to the closest multiple of sizeof(void *), in order ! to ensure that pointer fields at the end of the object are correctly ! aligned for the platform (this is of special importance for subclasses ! of, e.g., str or long, so that pointers can be stored after the embedded ! data). ! ! Note that there's no memory wastage in doing this, as malloc has to ! return (at worst) pointer-aligned memory anyway ! However, writing the macro to *return* the result is clumsy due to the ! calculations needed. Instead you must pass the result lvalue as the first ! argument, and it should be of type size_t (both because that's the ! correct conceptual type, and because using an unsigned type allows the ! compiler to generate faster code for the mod computation inside the ! macro). */ ! #define _PyObject_VAR_SIZE(result, typeobj, nitems) \ ! do { \ ! size_t mod; \ ! (result) = (size_t) (typeobj)->tp_basicsize; \ ! (result) += (size_t) ((nitems)*(typeobj)->tp_itemsize); \ ! mod = (result) % SIZEOF_VOID_P; \ ! if (mod) \ ! (result) += SIZEOF_VOID_P - mod; \ ! } while(0) #define PyObject_NEW(type, typeobj) \ ( (type *) PyObject_Init( \ (PyObject *) PyObject_MALLOC( _PyObject_SIZE(typeobj) ), (typeobj)) ) ! #define PyObject_NEW_VAR(type, typeobj, nitems) \ ! ((type *) _PyObject_NewVar(typeobj, nitems)) #define PyObject_DEL(op) PyObject_FREE(op) --- 174,207 ---- #define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) ! /* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a ! vrbl-size object with nitems items, exclusive of gc overhead (if any). The ! value is rounded up to the closest multiple of sizeof(void *), in order to ! ensure that pointer fields at the end of the object are correctly aligned ! for the platform (this is of special importance for subclasses of, e.g., ! str or long, so that pointers can be stored after the embedded data). ! Note that there's no memory wastage in doing this, as malloc has to ! return (at worst) pointer-aligned memory anyway. */ ! #if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0 ! # error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2" ! #endif + #define _PyObject_VAR_SIZE(typeobj, nitems) \ + (size_t) \ + ( ( (typeobj)->tp_basicsize + \ + (nitems)*(typeobj)->tp_itemsize + \ + (SIZEOF_VOID_P - 1) \ + ) & ~(SIZEOF_VOID_P - 1) \ + ) + #define PyObject_NEW(type, typeobj) \ ( (type *) PyObject_Init( \ (PyObject *) PyObject_MALLOC( _PyObject_SIZE(typeobj) ), (typeobj)) ) ! #define PyObject_NEW_VAR(type, typeobj, n) \ ! ( (type *) PyObject_InitVar( \ ! (PyVarObject *) PyObject_MALLOC(_PyObject_VAR_SIZE((typeobj),(n)) ),\ ! (typeobj), (n)) ) #define PyObject_DEL(op) PyObject_FREE(op) From tim_one@users.sourceforge.net Sun Oct 7 04:54:53 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 20:54:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.155,2.156 typeobject.c,2.92,2.93 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv14609/python/Objects Modified Files: object.c typeobject.c Log Message: Guido suggests, and I agree, to insist that SIZEOF_VOID_P be a power of 2. This simplifies the rounding in _PyObject_VAR_SIZE, allows to restore the pre-rounding calling sequence, and allows some nice little simplifications in its callers. I'm still making it return a size_t, though. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.155 retrieving revision 2.156 diff -C2 -d -r2.155 -r2.156 *** object.c 2001/10/06 21:27:34 2.155 --- object.c 2001/10/07 03:54:51 2.156 *************** *** 131,137 **** { PyVarObject *op; ! size_t size; ! ! _PyObject_VAR_SIZE(size, tp, nitems); op = (PyVarObject *) PyObject_MALLOC(size); if (op == NULL) --- 131,135 ---- { PyVarObject *op; ! const size_t size = _PyObject_VAR_SIZE(tp, nitems); op = (PyVarObject *) PyObject_MALLOC(size); if (op == NULL) *************** *** 1159,1164 **** return NULL; if (dictoffset < 0) { ! size_t size; ! _PyObject_VAR_SIZE(size, tp, ((PyVarObject *)obj)->ob_size); dictoffset += (long)size; assert(dictoffset > 0); --- 1157,1162 ---- return NULL; if (dictoffset < 0) { ! const size_t size = _PyObject_VAR_SIZE(tp, ! ((PyVarObject *)obj)->ob_size); dictoffset += (long)size; assert(dictoffset > 0); Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.92 retrieving revision 2.93 diff -C2 -d -r2.92 -r2.93 *** typeobject.c 2001/10/06 21:27:34 2.92 --- typeobject.c 2001/10/07 03:54:51 2.93 *************** *** 192,198 **** { PyObject *obj; ! size_t size; ! ! _PyObject_VAR_SIZE(size, type, nitems); if (PyType_IS_GC(type)) --- 192,196 ---- { PyObject *obj; ! const size_t size = _PyObject_VAR_SIZE(type, nitems); if (PyType_IS_GC(type)) From tim_one@users.sourceforge.net Sun Oct 7 04:54:53 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 20:54:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules gcmodule.c,2.22,2.23 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv14609/python/Modules Modified Files: gcmodule.c Log Message: Guido suggests, and I agree, to insist that SIZEOF_VOID_P be a power of 2. This simplifies the rounding in _PyObject_VAR_SIZE, allows to restore the pre-rounding calling sequence, and allows some nice little simplifications in its callers. I'm still making it return a size_t, though. Index: gcmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/gcmodule.c,v retrieving revision 2.22 retrieving revision 2.23 diff -C2 -d -r2.22 -r2.23 *** gcmodule.c 2001/10/06 21:27:34 2.22 --- gcmodule.c 2001/10/07 03:54:51 2.23 *************** *** 802,813 **** { PyObject *op; ! size_t basicsize; #ifdef WITH_CYCLE_GC ! size_t nbytes; ! PyGC_Head *g; ! ! _PyObject_VAR_SIZE(basicsize, tp, nitems); ! nbytes = sizeof(PyGC_Head) + basicsize; ! g = PyObject_MALLOC(nbytes); if (g == NULL) return (PyObject *)PyErr_NoMemory(); --- 802,809 ---- { PyObject *op; ! const size_t basicsize = _PyObject_VAR_SIZE(tp, nitems); #ifdef WITH_CYCLE_GC ! const size_t nbytes = sizeof(PyGC_Head) + basicsize; ! PyGC_Head *g = PyObject_MALLOC(nbytes); if (g == NULL) return (PyObject *)PyErr_NoMemory(); *************** *** 825,829 **** op = FROM_GC(g); #else - _PyObject_VAR_SIZE(basicsize, tp, nitems); op = PyObject_MALLOC(basicsize); if (op == NULL) --- 821,824 ---- *************** *** 851,859 **** _PyObject_GC_Resize(PyVarObject *op, int nitems) { ! size_t basicsize; #ifdef WITH_CYCLE_GC PyGC_Head *g = AS_GC(op); - - _PyObject_VAR_SIZE(basicsize, op->ob_type, nitems); g = PyObject_REALLOC(g, sizeof(PyGC_Head) + basicsize); if (g == NULL) --- 846,852 ---- _PyObject_GC_Resize(PyVarObject *op, int nitems) { ! const size_t basicsize = _PyObject_VAR_SIZE(op->ob_type, nitems); #ifdef WITH_CYCLE_GC PyGC_Head *g = AS_GC(op); g = PyObject_REALLOC(g, sizeof(PyGC_Head) + basicsize); if (g == NULL) *************** *** 861,865 **** op = (PyVarObject *) FROM_GC(g); #else - _PyObject_VAR_SIZE(basicsize, op->ob_type, nitems); op = PyObject_REALLOC(op, basicsize); if (op == NULL) --- 854,857 ---- From tim_one@users.sourceforge.net Sun Oct 7 05:02:38 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 21:02:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv18607/python/Lib Modified Files: profile.py Log Message: Repair some longstanding comment errors: + The last index in the timing tuple is 4, not 5 (noted by Guido). + The poorly named trace_dispatch_i works with float return values too. Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** profile.py 2001/10/07 03:12:08 1.35 --- profile.py 2001/10/07 04:02:36 1.36 *************** *** 136,140 **** to finish of each invocation of a function, including time spent in all subfunctions. ! [5] = A dictionary indicating for each function name, the number of times it was called by us. """ --- 136,140 ---- to finish of each invocation of a function, including time spent in all subfunctions. ! [4] = A dictionary indicating for each function name, the number of times it was called by us. """ *************** *** 203,212 **** ! ! # Dispatch routine for best timer program (return = scalar integer) def trace_dispatch_i(self, frame, event, arg): timer = self.timer ! t = timer() - self.t # - 1 # Integer calibration constant if self.dispatch[event](self, frame,t): self.t = timer() --- 203,212 ---- ! # Dispatch routine for best timer program (return = scalar, fastest if ! # an integer but float works too -- and time.clock() relies on that). def trace_dispatch_i(self, frame, event, arg): timer = self.timer ! t = timer() - self.t # - 1 # calibration constant if self.dispatch[event](self, frame,t): self.t = timer() From tim_one@users.sourceforge.net Sun Oct 7 05:30:55 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 06 Oct 2001 21:30:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv32041/python/Lib Modified Files: profile.py Log Message: At Guido's request, changed the code that's conceptually asserting stuff to use assert stmts (was raising unexpected kinds of exceptions). Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** profile.py 2001/10/07 04:02:36 1.36 --- profile.py 2001/10/07 04:30:53 1.37 *************** *** 253,263 **** rt, rtt, rct, rfn, rframe, rcur = self.cur if not isinstance(rframe, Profile.fake_frame): ! if rframe.f_back is not frame.f_back: ! print rframe, rframe.f_back ! print frame, frame.f_back ! raise "Bad call", self.cur[-3] self.trace_dispatch_return(rframe, 0) ! if self.cur and frame.f_back is not self.cur[-2]: ! raise "Bad call[2]", self.cur[-3] fcode = frame.f_code fn = (fcode.co_filename, fcode.co_firstlineno, fcode.co_name) --- 253,263 ---- rt, rtt, rct, rfn, rframe, rcur = self.cur if not isinstance(rframe, Profile.fake_frame): ! assert rframe.f_back is frame.f_back, ("Bad call", rfn, ! rframe, rframe.f_back, ! frame, frame.f_back) self.trace_dispatch_return(rframe, 0) ! assert (self.cur is None or \ ! frame.f_back is self.cur[-2]), ("Bad call", ! self.cur[-3]) fcode = frame.f_code fn = (fcode.co_filename, fcode.co_firstlineno, fcode.co_name) *************** *** 273,280 **** def trace_dispatch_return(self, frame, t): if frame is not self.cur[-2]: ! if frame is self.cur[-2].f_back: ! self.trace_dispatch_return(self.cur[-2], 0) ! else: ! raise "Bad return", self.cur[-3] # Prefix "r" means part of the Returning or exiting frame --- 273,278 ---- def trace_dispatch_return(self, frame, t): if frame is not self.cur[-2]: ! assert frame is self.cur[-2].f_back, ("Bad return", self.cur[-3]) ! self.trace_dispatch_return(self.cur[-2], 0) # Prefix "r" means part of the Returning or exiting frame *************** *** 312,316 **** ! # The next few function play with self.cmd. By carefully preloading # our parallel stack, we can force the profiled result to include # an arbitrary string as the name of the calling function. --- 310,314 ---- ! # The next few functions play with self.cmd. By carefully preloading # our parallel stack, we can force the profiled result to include # an arbitrary string as the name of the calling function. From loewis@users.sourceforge.net Sun Oct 7 09:14:43 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 07 Oct 2001 01:14:43 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.255,1.256 configure.in,1.263,1.264 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv6691 Modified Files: configure configure.in Log Message: Use AC_TRY_RUN for checking for -Kpthread. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.255 retrieving revision 1.256 diff -C2 -d -r1.255 -r1.256 *** configure 2001/10/04 22:44:25 1.255 --- configure 2001/10/07 08:14:41 1.256 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.262 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.263 [...4155 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 < *************** *** 7225,7229 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7228: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 7235,7239 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7238: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.263 retrieving revision 1.264 diff -C2 -d -r1.263 -r1.264 *** configure.in 2001/10/04 22:44:26 1.263 --- configure.in 2001/10/07 08:14:41 1.264 *************** *** 408,425 **** # -Kpthread, if available, provides the right #defines # and linker options to make pthread_create available AC_MSG_CHECKING(whether $CC accepts -Kpthread) AC_CACHE_VAL(ac_cv_kpthread, [ac_save_cc="$CC" CC="$CC -Kpthread" ! AC_TRY_LINK([#include ],[pthread_create(0,0,0,0)], ac_cv_kpthread=yes, ac_cv_kpthread=no) CC="$ac_save_cc"]) - - # GCC does not reject -Kpthread as an illegal option, it merely complains that - # it is unrecognized - if test "$GCC" = "yes" - then ac_cv_kpthread="no, we have gcc" - fi AC_MSG_RESULT($ac_cv_kpthread) --- 408,434 ---- # -Kpthread, if available, provides the right #defines # and linker options to make pthread_create available + # Some compilers won't report that they do not support -Kpthread, + # so we need to run a program to see whether it really made the + # function available. AC_MSG_CHECKING(whether $CC accepts -Kpthread) AC_CACHE_VAL(ac_cv_kpthread, [ac_save_cc="$CC" CC="$CC -Kpthread" ! AC_TRY_RUN([ ! #include ! ! void* routine(void* p){return NULL;} ! ! int main(){ ! pthread_t p; ! if(pthread_create(&p,NULL,routine,NULL)!=0) ! return 1; ! return 0; ! } ! ], ac_cv_kpthread=yes, + ac_cv_kpthread=no, ac_cv_kpthread=no) CC="$ac_save_cc"]) AC_MSG_RESULT($ac_cv_kpthread) From tim_one@users.sourceforge.net Sun Oct 7 09:35:46 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 07 Oct 2001 01:35:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv9148/python/Lib Modified Files: profile.py Log Message: Guido points out that the comments for self.cur[2] were subtly but seriously wrong. This started out by just fixing the docs, but then it occurred to me that the doc confusion propagated into misleading vrbl names too, so I also renamed those to match reality. As a result, INO the time computations are much easier to understand now (within the limitations of vast quantities of 3-character names ). Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** profile.py 2001/10/07 04:30:53 1.37 --- profile.py 2001/10/07 08:35:44 1.38 *************** *** 117,126 **** timing data for the parent frame. [ 1] = Total time spent in this frame's function, excluding time in ! subfunctions ! [ 2] = Cumulative time spent in this frame's function, including time in ! all subfunctions to this frame. [-3] = Name of the function that corresponds to this frame. ! [-2] = Actual frame that we correspond to (used to sync exception handling) ! [-1] = Our parent 6-tuple (corresponds to frame.f_back) Timing data for each function is stored as a 5-tuple in the dictionary --- 117,126 ---- timing data for the parent frame. [ 1] = Total time spent in this frame's function, excluding time in ! subfunctions (this latter is tallied in cur[2]). ! [ 2] = Total time spent in subfunctions, excluding time execute the ! frame's function (this latter is tallied in cur[1]). [-3] = Name of the function that corresponds to this frame. ! [-2] = Actual frame that we correspond to (used to sync exception handling). ! [-1] = Our parent 6-tuple (corresponds to frame.f_back). Timing data for each function is stored as a 5-tuple in the dictionary *************** *** 240,249 **** return def trace_dispatch_exception(self, frame, t): ! rt, rtt, rct, rfn, rframe, rcur = self.cur if (rframe is not frame) and rcur: return self.trace_dispatch_return(rframe, t) ! self.cur = rt, rtt+t, rct, rfn, rframe, rcur return 1 --- 240,255 ---- return + # In the event handlers, the first 3 elements of self.cur are unpacked + # into vrbls w/ 3-letter names. The last two characters are meant to be + # mnemonic: + # _pt self.cur[0] "parent time" time to be charged to parent frame + # _it self.cur[1] "internal time" time spent directly in the function + # _et self.cur[2] "external time" time spent in subfunctions def trace_dispatch_exception(self, frame, t): ! rpt, rit, ret, rfn, rframe, rcur = self.cur if (rframe is not frame) and rcur: return self.trace_dispatch_return(rframe, t) ! self.cur = rpt, rit+t, ret, rfn, rframe, rcur return 1 *************** *** 251,255 **** def trace_dispatch_call(self, frame, t): if self.cur and frame.f_back is not self.cur[-2]: ! rt, rtt, rct, rfn, rframe, rcur = self.cur if not isinstance(rframe, Profile.fake_frame): assert rframe.f_back is frame.f_back, ("Bad call", rfn, --- 257,261 ---- def trace_dispatch_call(self, frame, t): if self.cur and frame.f_back is not self.cur[-2]: ! rpt, rit, ret, rfn, rframe, rcur = self.cur if not isinstance(rframe, Profile.fake_frame): assert rframe.f_back is frame.f_back, ("Bad call", rfn, *************** *** 276,294 **** self.trace_dispatch_return(self.cur[-2], 0) ! # Prefix "r" means part of the Returning or exiting frame ! # Prefix "p" means part of the Previous or older frame ! rt, rtt, rct, rfn, frame, rcur = self.cur ! rtt = rtt + t ! sft = rtt + rct ! pt, ptt, pct, pfn, pframe, pcur = rcur ! self.cur = pt, ptt+rt, pct+sft, pfn, pframe, pcur timings = self.timings cc, ns, tt, ct, callers = timings[rfn] if not ns: ! ct = ct + sft cc = cc + 1 if callers.has_key(pfn): callers[pfn] = callers[pfn] + 1 # hack: gather more --- 282,305 ---- self.trace_dispatch_return(self.cur[-2], 0) ! # Prefix "r" means part of the Returning or exiting frame. ! # Prefix "p" means part of the Previous or Parent or older frame. ! rpt, rit, ret, rfn, frame, rcur = self.cur ! rit = rit + t ! frame_total = rit + ret ! ppt, pit, pet, pfn, pframe, pcur = rcur ! self.cur = ppt, pit + rpt, pet + frame_total, pfn, pframe, pcur timings = self.timings cc, ns, tt, ct, callers = timings[rfn] if not ns: ! # This is the only occurrence of the function on the stack. ! # Else this is a (directly or indirectly) recursive call, and ! # its cumulative time will get updated when the topmost call to ! # it returns. ! ct = ct + frame_total cc = cc + 1 + if callers.has_key(pfn): callers[pfn] = callers[pfn] + 1 # hack: gather more *************** *** 298,302 **** else: callers[pfn] = 1 ! timings[rfn] = cc, ns - 1, tt+rtt, ct, callers return 1 --- 309,314 ---- else: callers[pfn] = 1 ! ! timings[rfn] = cc, ns - 1, tt + rit, ct, callers return 1 From loewis@users.sourceforge.net Sun Oct 7 09:39:21 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 07 Oct 2001 01:39:21 -0700 Subject: [Python-checkins] CVS: python/dist/src configure.in,1.264,1.265 configure,1.256,1.257 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv10319 Modified Files: configure.in configure Log Message: Support OpenUNIX like UnixWare. Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.264 retrieving revision 1.265 diff -C2 -d -r1.264 -r1.265 *** configure.in 2001/10/07 08:14:41 1.264 --- configure.in 2001/10/07 08:39:18 1.265 *************** *** 353,357 **** *) case $ac_sys_system in ! UnixWare*) OPT="-O -K pentium,host,inline,loop_unroll,alloca ";; *) --- 353,357 ---- *) case $ac_sys_system in ! OpenUNIX*|UnixWare*) OPT="-O -K pentium,host,inline,loop_unroll,alloca ";; *) *************** *** 732,736 **** LDSHARED="ld -Bshareable ${LDFLAGS}" fi;; ! UnixWare*) if test "$GCC" = "yes" then LDSHARED="$(CC) -shared" --- 732,736 ---- LDSHARED="ld -Bshareable ${LDFLAGS}" fi;; ! OpenUNIX*|UnixWare*) if test "$GCC" = "yes" then LDSHARED="$(CC) -shared" *************** *** 761,765 **** BSD/OS*/4*) CCSHARED="-fpic";; FreeBSD*|NetBSD*|OpenBSD*) CCSHARED="-fPIC";; ! UnixWare*) if test "$GCC" = "yes" then CCSHARED="-fPIC" --- 761,765 ---- BSD/OS*/4*) CCSHARED="-fpic";; FreeBSD*|NetBSD*|OpenBSD*) CCSHARED="-fPIC";; ! OpenUNIX*|UnixWare*) if test "$GCC" = "yes" then CCSHARED="-fPIC" *************** *** 802,806 **** fi LINKFORSHARED="$LINKFORSHARED $extra_frameworks";; ! UnixWare*) LINKFORSHARED="-Wl,-Bexport";; SCO_SV*) LINKFORSHARED="-Bdynamic -dy -Wl,-Bexport";; ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";; --- 802,806 ---- fi LINKFORSHARED="$LINKFORSHARED $extra_frameworks";; ! OpenUNIX*|UnixWare*) LINKFORSHARED="-Wl,-Bexport";; SCO_SV*) LINKFORSHARED="-Bdynamic -dy -Wl,-Bexport";; ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";; Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.256 retrieving revision 1.257 diff -C2 -d -r1.256 -r1.257 *** configure 2001/10/07 08:14:41 1.256 --- configure 2001/10/07 08:39:18 1.257 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.263 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.264 # Guess values for system-dependent variables and create Makefiles. *************** *** 1650,1654 **** *) case $ac_sys_system in ! UnixWare*) OPT="-O -K pentium,host,inline,loop_unroll,alloca ";; *) --- 1650,1654 ---- *) case $ac_sys_system in ! OpenUNIX*|UnixWare*) OPT="-O -K pentium,host,inline,loop_unroll,alloca ";; *) *************** *** 3103,3107 **** LDSHARED="ld -Bshareable ${LDFLAGS}" fi;; ! UnixWare*) if test "$GCC" = "yes" then LDSHARED="$(CC) -shared" --- 3103,3107 ---- LDSHARED="ld -Bshareable ${LDFLAGS}" fi;; ! OpenUNIX*|UnixWare*) if test "$GCC" = "yes" then LDSHARED="$(CC) -shared" *************** *** 3133,3137 **** BSD/OS*/4*) CCSHARED="-fpic";; FreeBSD*|NetBSD*|OpenBSD*) CCSHARED="-fPIC";; ! UnixWare*) if test "$GCC" = "yes" then CCSHARED="-fPIC" --- 3133,3137 ---- BSD/OS*/4*) CCSHARED="-fpic";; FreeBSD*|NetBSD*|OpenBSD*) CCSHARED="-fPIC";; ! OpenUNIX*|UnixWare*) if test "$GCC" = "yes" then CCSHARED="-fPIC" *************** *** 3175,3179 **** fi LINKFORSHARED="$LINKFORSHARED $extra_frameworks";; ! UnixWare*) LINKFORSHARED="-Wl,-Bexport";; SCO_SV*) LINKFORSHARED="-Bdynamic -dy -Wl,-Bexport";; ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";; --- 3175,3179 ---- fi LINKFORSHARED="$LINKFORSHARED $extra_frameworks";; ! OpenUNIX*|UnixWare*) LINKFORSHARED="-Wl,-Bexport";; SCO_SV*) LINKFORSHARED="-Bdynamic -dy -Wl,-Bexport";; ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";; From tim_one@users.sourceforge.net Sun Oct 7 09:49:04 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 07 Oct 2001 01:49:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11557/python/Lib Modified Files: profile.py Log Message: Typo repair in comment. Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** profile.py 2001/10/07 08:35:44 1.38 --- profile.py 2001/10/07 08:49:02 1.39 *************** *** 118,122 **** [ 1] = Total time spent in this frame's function, excluding time in subfunctions (this latter is tallied in cur[2]). ! [ 2] = Total time spent in subfunctions, excluding time execute the frame's function (this latter is tallied in cur[1]). [-3] = Name of the function that corresponds to this frame. --- 118,122 ---- [ 1] = Total time spent in this frame's function, excluding time in subfunctions (this latter is tallied in cur[2]). ! [ 2] = Total time spent in subfunctions, excluding time executing the frame's function (this latter is tallied in cur[1]). [-3] = Name of the function that corresponds to this frame. From loewis@users.sourceforge.net Sun Oct 7 09:53:34 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 07 Oct 2001 01:53:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib ftplib.py,1.57,1.58 httplib.py,1.39,1.40 poplib.py,1.17,1.18 smtplib.py,1.43,1.44 telnetlib.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv12115 Modified Files: ftplib.py httplib.py poplib.py smtplib.py telnetlib.py Log Message: Only close sockets if they have been created. Reported by Blake Winton. Index: ftplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ftplib.py,v retrieving revision 1.57 retrieving revision 1.58 diff -C2 -d -r1.57 -r1.58 *** ftplib.py 2001/08/17 17:24:29 1.57 --- ftplib.py 2001/10/07 08:53:32 1.58 *************** *** 123,127 **** self.sock.connect(sa) except socket.error, msg: ! self.sock.close() self.sock = None continue --- 123,128 ---- self.sock.connect(sa) except socket.error, msg: ! if self.sock: ! self.sock.close() self.sock = None continue *************** *** 273,276 **** --- 274,278 ---- '''Create a new socket and send a PORT command for it.''' msg = "getaddrinfo returns an empty list" + sock = None for res in socket.getaddrinfo(None, 0, self.af, socket.SOCK_STREAM, 0, socket.AI_PASSIVE): af, socktype, proto, canonname, sa = res *************** *** 279,283 **** sock.bind(sa) except socket.error, msg: ! sock.close() sock = None continue --- 281,286 ---- sock.bind(sa) except socket.error, msg: ! if sock: ! sock.close() sock = None continue Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** httplib.py 2001/08/18 09:20:23 1.39 --- httplib.py 2001/10/07 08:53:32 1.40 *************** *** 369,373 **** if self.debuglevel > 0: print 'connect fail:', (self.host, self.port) ! self.sock.close() self.sock = None continue --- 369,374 ---- if self.debuglevel > 0: print 'connect fail:', (self.host, self.port) ! if self.sock: ! self.sock.close() self.sock = None continue Index: poplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/poplib.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** poplib.py 2001/07/31 08:40:21 1.17 --- poplib.py 2001/10/07 08:53:32 1.18 *************** *** 77,80 **** --- 77,81 ---- self.port = port msg = "getaddrinfo returns an empty list" + self.sock = None for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res *************** *** 83,87 **** self.sock.connect(sa) except socket.error, msg: ! self.sock.close() self.sock = None continue --- 84,89 ---- self.sock.connect(sa) except socket.error, msg: ! if self.sock: ! self.sock.close() self.sock = None continue Index: smtplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/smtplib.py,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** smtplib.py 2001/09/18 02:26:39 1.43 --- smtplib.py 2001/10/07 08:53:32 1.44 *************** *** 266,269 **** --- 266,270 ---- if self.debuglevel > 0: print 'connect:', (host, port) msg = "getaddrinfo returns an empty list" + self.sock = None for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res *************** *** 274,278 **** except socket.error, msg: if self.debuglevel > 0: print 'connect fail:', (host, port) ! self.sock.close() self.sock = None continue --- 275,280 ---- except socket.error, msg: if self.debuglevel > 0: print 'connect fail:', (host, port) ! if self.sock: ! self.sock.close() self.sock = None continue Index: telnetlib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/telnetlib.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** telnetlib.py 2001/09/06 08:51:38 1.15 --- telnetlib.py 2001/10/07 08:53:32 1.16 *************** *** 211,215 **** self.sock.connect(sa) except socket.error, msg: ! self.sock.close() self.sock = None continue --- 211,216 ---- self.sock.connect(sa) except socket.error, msg: ! if self.sock: ! self.sock.close() self.sock = None continue From gvanrossum@users.sourceforge.net Sun Oct 7 21:53:47 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 07 Oct 2001 13:53:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.83,2.84 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv13774 Modified Files: abstract.c Log Message: Implement isinstance(x, (A, B, ...)). Note that we only allow tuples, not other sequences (then we'd have to except strings, and we'd still be susceptible to recursive attacks). Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.83 retrieving revision 2.84 diff -C2 -d -r2.83 -r2.84 *** abstract.c 2001/10/01 17:10:18 2.83 --- abstract.c 2001/10/07 20:53:45 2.84 *************** *** 1806,1809 **** --- 1806,1823 ---- retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls); } + else if (PyTuple_Check(cls)) { + /* Not a general sequence -- that opens up the road to + recursion and stack overflow. */ + int i, n; + + n = PyTuple_GET_SIZE(cls); + for (i = 0; i < n; i++) { + retval = PyObject_IsInstance( + inst, PyTuple_GET_ITEM(cls, i)); + if (retval != 0) + break; + } + return retval; + } else if (!PyInstance_Check(inst)) { if (__class__ == NULL) { *************** *** 1828,1832 **** if (retval < 0) { PyErr_SetString(PyExc_TypeError, ! "isinstance() arg 2 must be a class or type"); } return retval; --- 1842,1847 ---- if (retval < 0) { PyErr_SetString(PyExc_TypeError, ! "isinstance() arg 2 must be a class or type " ! "or tuple of those"); } return retval; From gvanrossum@users.sourceforge.net Sun Oct 7 21:54:14 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 07 Oct 2001 13:54:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.239,2.240 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv13870 Modified Files: bltinmodule.c Log Message: Implement isinstance(x, (A, B, ...)). Note that we only allow tuples, not other sequences (then we'd have to except strings, and we'd still be susceptible to recursive attacks). Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.239 retrieving revision 2.240 diff -C2 -d -r2.239 -r2.240 *** bltinmodule.c 2001/09/13 21:49:44 2.239 --- bltinmodule.c 2001/10/07 20:54:12 2.240 *************** *** 1642,1649 **** static char isinstance_doc[] = ! "isinstance(object, class-or-type) -> Boolean\n\ \n\ Return whether an object is an instance of a class or of a subclass thereof.\n\ ! With a type as second argument, return whether that is the object's type."; --- 1642,1651 ---- static char isinstance_doc[] = ! "isinstance(object, class-or-type-or-tuple) -> Boolean\n\ \n\ Return whether an object is an instance of a class or of a subclass thereof.\n\ ! With a type as second argument, return whether that is the object's type.\n\ ! The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for\n\ ! isinstance(x, A) or isinstance(x, B) or ... (etc.)."; From tim_one@users.sourceforge.net Mon Oct 8 07:13:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 07 Oct 2001 23:13:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pstats.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv7871/python/Lib Modified Files: pstats.py Log Message: Widespread random code cleanup. Most of this code was old enough to vote. Examples of cleanups: + Backslashes were used for line continuation even inside unclosed bracket structures, from back in the days that was still needed. + There was no use of % formats, and e.g. the old fpformat module was still used to format floats "by hand" in conjunction with rjust(). + There was even use of a do-nothing .ignore() method to tack on to the end of a chain of method calls, else way back when Python would print the non-None result (as it does now in an interactive session -- it *used* to do that in batch mode too). + Perhaps controversial (although I can't imagine why for real ), used augmented assignment where helpful. Stuff like self.total_calls = self.total_calls + other.total_calls is just plain harder to follow than self.total_calls += other.total_calls Index: pstats.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pstats.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** pstats.py 2001/08/13 14:47:49 1.21 --- pstats.py 2001/10/08 06:13:19 1.22 *************** *** 38,43 **** import re - import fpformat - __all__ = ["Stats"] --- 38,41 ---- *************** *** 79,83 **** args = args[1:] self.init(arg) ! apply(self.add, args).ignore() def init(self, arg): --- 77,81 ---- args = args[1:] self.init(arg) ! apply(self.add, args) def init(self, arg): *************** *** 103,107 **** print - def load_stats(self, arg): if not arg: self.stats = {} --- 101,104 ---- *************** *** 127,135 **** def get_top_level_stats(self): ! for func in self.stats.keys(): ! cc, nc, tt, ct, callers = self.stats[func] ! self.total_calls = self.total_calls + nc ! self.prim_calls = self.prim_calls + cc ! self.total_tt = self.total_tt + tt if callers.has_key(("jprofile", 0, "profiler")): self.top_level[func] = None --- 124,131 ---- def get_top_level_stats(self): ! for func, (cc, nc, tt, ct, callers) in self.stats.items(): ! self.total_calls += nc ! self.prim_calls += cc ! self.total_tt += tt if callers.has_key(("jprofile", 0, "profiler")): self.top_level[func] = None *************** *** 141,151 **** if len(arg_list) > 1: apply(self.add, arg_list[1:]) other = arg_list[0] ! if type(self) != type(other) or \ ! self.__class__ != other.__class__: other = Stats(other) ! self.files = self.files + other.files ! self.total_calls = self.total_calls + other.total_calls ! self.prim_calls = self.prim_calls + other.prim_calls ! self.total_tt = self.total_tt + other.total_tt for func in other.top_level.keys(): self.top_level[func] = None --- 137,146 ---- if len(arg_list) > 1: apply(self.add, arg_list[1:]) other = arg_list[0] ! if type(self) != type(other) or self.__class__ != other.__class__: other = Stats(other) ! self.files += other.files ! self.total_calls += other.total_calls ! self.prim_calls += other.prim_calls ! self.total_tt += other.total_tt for func in other.top_level.keys(): self.top_level[func] = None *************** *** 161,183 **** else: old_func_stat = (0, 0, 0, 0, {},) ! self.stats[func] = add_func_stats(old_func_stat, \ ! other.stats[func]) return self - - # list the tuple indices and directions for sorting, # along with some printable description ! sort_arg_dict_default = {\ ! "calls" : (((1,-1), ), "call count"),\ ! "cumulative": (((3,-1), ), "cumulative time"),\ ! "file" : (((4, 1), ), "file name"),\ ! "line" : (((5, 1), ), "line number"),\ ! "module" : (((4, 1), ), "file name"),\ ! "name" : (((6, 1), ), "function name"),\ ! "nfl" : (((6, 1),(4, 1),(5, 1),), "name/file/line"), \ ! "pcalls" : (((0,-1), ), "call count"),\ ! "stdname" : (((7, 1), ), "standard name"),\ ! "time" : (((2,-1), ), "internal time"),\ } --- 156,175 ---- else: old_func_stat = (0, 0, 0, 0, {},) ! self.stats[func] = add_func_stats(old_func_stat, other.stats[func]) return self # list the tuple indices and directions for sorting, # along with some printable description ! sort_arg_dict_default = { ! "calls" : (((1,-1), ), "call count"), ! "cumulative": (((3,-1), ), "cumulative time"), ! "file" : (((4, 1), ), "file name"), ! "line" : (((5, 1), ), "line number"), ! "module" : (((4, 1), ), "file name"), ! "name" : (((6, 1), ), "function name"), ! "nfl" : (((6, 1),(4, 1),(5, 1),), "name/file/line"), ! "pcalls" : (((0,-1), ), "call count"), ! "stdname" : (((7, 1), ), "standard name"), ! "time" : (((2,-1), ), "internal time"), } *************** *** 195,200 **** bad_list[fragment] = 0 break ! dict[fragment] = self. \ ! sort_arg_dict_default[word] fragment = fragment[:-1] for word in bad_list.keys(): --- 187,191 ---- bad_list[fragment] = 0 break ! dict[fragment] = self.sort_arg_dict_default[word] fragment = fragment[:-1] for word in bad_list.keys(): *************** *** 202,206 **** return self.sort_arg_dict - def sort_stats(self, *field): if not field: --- 193,196 ---- *************** *** 209,215 **** if len(field) == 1 and type(field[0]) == type(1): # Be compatible with old profiler ! field = [ {-1: "stdname", \ ! 0:"calls", \ ! 1:"time", \ 2: "cumulative" } [ field[0] ] ] --- 199,205 ---- if len(field) == 1 and type(field[0]) == type(1): # Be compatible with old profiler ! field = [ {-1: "stdname", ! 0:"calls", ! 1:"time", 2: "cumulative" } [ field[0] ] ] *************** *** 220,225 **** for word in field: sort_tuple = sort_tuple + sort_arg_defs[word][0] ! self.sort_type = self.sort_type + connector + \ ! sort_arg_defs[word][1] connector = ", " --- 210,214 ---- for word in field: sort_tuple = sort_tuple + sort_arg_defs[word][0] ! self.sort_type += connector + sort_arg_defs[word][1] connector = ", " *************** *** 227,232 **** for func in self.stats.keys(): cc, nc, tt, ct, callers = self.stats[func] ! stats_list.append((cc, nc, tt, ct) + func_split(func) \ ! + (func_std_string(func), func,) ) stats_list.sort(TupleComp(sort_tuple).compare) --- 216,221 ---- for func in self.stats.keys(): cc, nc, tt, ct, callers = self.stats[func] ! stats_list.append((cc, nc, tt, ct) + func + ! (func_std_string(func), func)) stats_list.sort(TupleComp(sort_tuple).compare) *************** *** 237,243 **** return self - def reverse_order(self): ! if self.fcn_list: self.fcn_list.reverse() return self --- 226,232 ---- return self def reverse_order(self): ! if self.fcn_list: ! self.fcn_list.reverse() return self *************** *** 253,263 **** newcallers = {} for func2 in callers.keys(): ! newcallers[func_strip_path(func2)] = \ ! callers[func2] if newstats.has_key(newfunc): ! newstats[newfunc] = add_func_stats( \ ! newstats[newfunc],\ ! (cc, nc, tt, ct, newcallers)) else: newstats[newfunc] = (cc, nc, tt, ct, newcallers) --- 242,251 ---- newcallers = {} for func2 in callers.keys(): ! newcallers[func_strip_path(func2)] = callers[func2] if newstats.has_key(newfunc): ! newstats[newfunc] = add_func_stats( ! newstats[newfunc], ! (cc, nc, tt, ct, newcallers)) else: newstats[newfunc] = (cc, nc, tt, ct, newcallers) *************** *** 273,278 **** return self - - def calc_callees(self): if self.all_callees: return --- 261,264 ---- *************** *** 304,308 **** count = len(list) if type(sel) == type(1.0) and 0.0 <= sel < 1.0: ! count = int (count * sel + .5) new_list = list[:count] elif type(sel) == type(1) and 0 <= sel < count: --- 290,294 ---- count = len(list) if type(sel) == type(1.0) and 0.0 <= sel < 1.0: ! count = int(count * sel + .5) new_list = list[:count] elif type(sel) == type(1) and 0 <= sel < count: *************** *** 316,321 **** return new_list, msg - - def get_print_list(self, sel_list): width = self.max_name_len --- 302,305 ---- *************** *** 328,332 **** for selection in sel_list: ! list,msg = self.eval_print_amount(selection, list, msg) count = len(list) --- 312,316 ---- for selection in sel_list: ! list, msg = self.eval_print_amount(selection, list, msg) count = len(list) *************** *** 346,357 **** print filename if self.files: print ! indent = " " for func in self.top_level.keys(): print indent, func_get_function_name(func) ! print indent, self.total_calls, "function calls", if self.total_calls != self.prim_calls: ! print "(" + `self.prim_calls`, "primitive calls)", ! print "in", fpformat.fix(self.total_tt, 3), "CPU seconds" print width, list = self.get_print_list(amount) --- 330,341 ---- print filename if self.files: print ! indent = ' ' * 8 for func in self.top_level.keys(): print indent, func_get_function_name(func) ! print indent, self.total_calls, "function calls", if self.total_calls != self.prim_calls: ! print "(%d primitive calls)" % self.prim_calls, ! print "in %.3f CPU seconds" % self.total_tt print width, list = self.get_print_list(amount) *************** *** 364,368 **** return self - def print_callees(self, *amount): width, list = self.get_print_list(amount) --- 348,351 ---- *************** *** 373,378 **** for func in list: if self.all_callees.has_key(func): ! self.print_call_line(width, \ ! func, self.all_callees[func]) else: self.print_call_line(width, func, {}) --- 356,360 ---- for func in list: if self.all_callees.has_key(func): ! self.print_call_line(width, func, self.all_callees[func]) else: self.print_call_line(width, func, {}) *************** *** 395,399 **** print "Function ".ljust(name_size) + column_title - def print_call_line(self, name_size, source, call_dict): print func_std_string(source).ljust(name_size), --- 377,380 ---- *************** *** 412,431 **** indent = " " - - def print_title(self): ! print 'ncalls'.rjust(9), ! print 'tottime'.rjust(8), ! print 'percall'.rjust(8), ! print 'cumtime'.rjust(8), ! print 'percall'.rjust(8), ! print 'filename:lineno(function)' ! def print_line(self, func): # hack : should print percentages cc, nc, tt, ct, callers = self.stats[func] ! c = `nc` if nc != cc: ! c = c + '/' + `cc` print c.rjust(9), print f8(tt), --- 393,405 ---- indent = " " def print_title(self): ! print ' ncalls tottime percall cumtime percall', \ ! 'filename:lineno(function)' def print_line(self, func): # hack : should print percentages cc, nc, tt, ct, callers = self.stats[func] ! c = str(nc) if nc != cc: ! c = c + '/' + str(cc) print c.rjust(9), print f8(tt), *************** *** 441,449 **** print func_std_string(func) - - def ignore(self): - pass # has no return value, so use at end of line :-) - - class TupleComp: """This class provides a generic function for comparing any two tuples. --- 415,418 ---- *************** *** 466,473 **** return direction return 0 - #************************************************************************** def func_strip_path(func_name): --- 435,445 ---- return direction return 0 + def ignore(self): + # Deprecated since 1.5.1 -- see the docs. + pass # has no return value, so use at end of line :-) #************************************************************************** + # func_name is a triple (file:string, line:int, name:string) def func_strip_path(func_name): *************** *** 479,487 **** def func_std_string(func_name): # match what old profile produced ! file, line, name = func_name ! return file + ":" + `line` + "(" + name + ")" ! ! def func_split(func_name): ! return func_name #************************************************************************** --- 451,455 ---- def func_std_string(func_name): # match what old profile produced ! return "%s:%d(%s)" % func_name #************************************************************************** *************** *** 495,502 **** cc, nc, tt, ct, callers = source t_cc, t_nc, t_tt, t_ct, t_callers = target ! return (cc+t_cc, nc+t_nc, tt+t_tt, ct+t_ct, \ add_callers(t_callers, callers)) - def add_callers(target, source): """Combine two caller lists in a single list.""" --- 463,469 ---- cc, nc, tt, ct, callers = source t_cc, t_nc, t_tt, t_ct, t_callers = target ! return (cc+t_cc, nc+t_nc, tt+t_tt, ct+t_ct, add_callers(t_callers, callers)) def add_callers(target, source): """Combine two caller lists in a single list.""" *************** *** 515,519 **** nc = 0 for func in callers.keys(): ! nc = nc + callers[func] return nc --- 482,486 ---- nc = 0 for func in callers.keys(): ! nc += callers[func] return nc *************** *** 523,527 **** def f8(x): ! return fpformat.fix(x, 3).rjust(8) #************************************************************************** --- 490,494 ---- def f8(x): ! return "%8.3f" % x #************************************************************************** From tim_one@users.sourceforge.net Mon Oct 8 07:28:20 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 07 Oct 2001 23:28:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pstats.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11677/python/Lib Modified Files: pstats.py Log Message: Put the deprecated .ignore() method back where it was. Index: pstats.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pstats.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** pstats.py 2001/10/08 06:13:19 1.22 --- pstats.py 2001/10/08 06:28:18 1.23 *************** *** 415,418 **** --- 415,422 ---- print func_std_string(func) + def ignore(self): + # Deprecated since 1.5.1 -- see the docs. + pass # has no return value, so use at end of line :-) + class TupleComp: """This class provides a generic function for comparing any two tuples. *************** *** 435,442 **** return direction return 0 - - def ignore(self): - # Deprecated since 1.5.1 -- see the docs. - pass # has no return value, so use at end of line :-) #************************************************************************** --- 439,442 ---- From jackjansen@users.sourceforge.net Mon Oct 8 14:00:28 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 08 Oct 2001 06:00:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Build PythonCore.mcp,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory usw-pr-cvs1:/tmp/cvs-serv1184/python/Mac/Build Modified Files: PythonCore.mcp Log Message: Added weakrefobject.c and regenerated .exp files. Index: PythonCore.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCore.mcp,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 Binary files /tmp/cvsbFUJmA and /tmp/cvsihRy01 differ From jackjansen@users.sourceforge.net Mon Oct 8 14:00:46 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 08 Oct 2001 06:00:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Build PythonStandSmall.mcp,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory usw-pr-cvs1:/tmp/cvs-serv1255/python/Mac/Build Modified Files: PythonStandSmall.mcp Log Message: Added weakrefobject.c and regenerated .exp files. Index: PythonStandSmall.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonStandSmall.mcp,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 Binary files /tmp/cvsLc6uAr and /tmp/cvsgSDGbJ differ From jackjansen@users.sourceforge.net Mon Oct 8 14:00:53 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 08 Oct 2001 06:00:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Build PythonCore.exp,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory usw-pr-cvs1:/tmp/cvs-serv1318/python/Mac/Build Modified Files: PythonCore.exp Log Message: Added weakrefobject.c and regenerated .exp files. Index: PythonCore.exp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCore.exp,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** PythonCore.exp 2001/09/08 21:37:35 1.15 --- PythonCore.exp 2001/10/08 13:00:51 1.16 *************** *** 209,213 **** --- 209,215 ---- PyInterpreterState_Clear PyInterpreterState_New + PyMember_SetOne PyMember_Set + PyMember_GetOne PyMember_Get PySys_WriteStderr *************** *** 250,255 **** PySequence_In PySequence_Contains - _PySequence_IterContains PySequence_Count PySequence_Fast PySequence_List --- 252,257 ---- PySequence_In PySequence_Contains PySequence_Count + _PySequence_IterSearch PySequence_Fast PySequence_List *************** *** 434,437 **** --- 436,440 ---- PyLong_FromUnsignedLong PyLong_FromLong + _PyLong_Copy _PyLong_New PyCFunction_Type *************** *** 455,459 **** _Py_cobject_hack _Py_abstract_hack - PyObject_ClearWeakRefs Py_DivisionWarningFlag _PyTrash_delete_later --- 458,461 ---- *************** *** 545,550 **** --- 547,554 ---- PyBaseObject_Type PySuper_Type + _PyObject_SlotCompare PyType_Ready _PyType_Lookup + call_maybe call_method PyType_IsSubtype *************** *** 662,666 **** RotateCursor SpinCursor ! PyMac_GetFullPath PyMac_AppRefNum PyMac_options --- 666,670 ---- RotateCursor SpinCursor ! PyMac_GetFullPathname PyMac_AppRefNum PyMac_options *************** *** 797,800 **** --- 801,806 ---- PyUnicodeUCS2_EncodeUTF8 PyUnicodeUCS2_DecodeUTF8 + PyUnicode_EncodeUTF7 + PyUnicode_DecodeUTF7 PyUnicodeUCS2_SetDefaultEncoding PyUnicodeUCS2_GetDefaultEncoding *************** *** 850,853 **** --- 856,860 ---- PyExc_IndentationError PyExc_TabError + PyExc_ReferenceError PyExc_SystemError PyExc_SystemExit *************** *** 884,887 **** --- 891,895 ---- PyOS_vsnprintf PyOS_snprintf + PyWrapperDescr_Type proxytype wrappertype *************** *** 1027,1030 **** --- 1035,1046 ---- PyMac_StrError PyMac_getscript + _PyWeakref_RefType + _PyWeakref_ProxyType + _PyWeakref_CallableProxyType + PyObject_ClearWeakRefs + PyWeakref_GetObject + PyWeakref_NewProxy + PyWeakref_NewRef + _PyWeakref_GetWeakrefCount GUSISetupConsoleStdio GUSIStdioFlush From jackjansen@users.sourceforge.net Mon Oct 8 14:01:08 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 08 Oct 2001 06:01:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Build PythonCoreCarbon.exp,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory usw-pr-cvs1:/tmp/cvs-serv1403/python/Mac/Build Modified Files: PythonCoreCarbon.exp Log Message: Added weakrefobject.c and regenerated .exp files. Index: PythonCoreCarbon.exp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCoreCarbon.exp,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** PythonCoreCarbon.exp 2001/09/08 21:37:46 1.15 --- PythonCoreCarbon.exp 2001/10/08 13:01:05 1.16 *************** *** 209,213 **** --- 209,215 ---- PyInterpreterState_Clear PyInterpreterState_New + PyMember_SetOne PyMember_Set + PyMember_GetOne PyMember_Get PySys_WriteStderr *************** *** 250,255 **** PySequence_In PySequence_Contains - _PySequence_IterContains PySequence_Count PySequence_Fast PySequence_List --- 252,257 ---- PySequence_In PySequence_Contains PySequence_Count + _PySequence_IterSearch PySequence_Fast PySequence_List *************** *** 434,437 **** --- 436,440 ---- PyLong_FromUnsignedLong PyLong_FromLong + _PyLong_Copy _PyLong_New PyCFunction_Type *************** *** 455,459 **** _Py_cobject_hack _Py_abstract_hack - PyObject_ClearWeakRefs Py_DivisionWarningFlag _PyTrash_delete_later --- 458,461 ---- *************** *** 545,550 **** --- 547,554 ---- PyBaseObject_Type PySuper_Type + _PyObject_SlotCompare PyType_Ready _PyType_Lookup + call_maybe call_method PyType_IsSubtype *************** *** 656,660 **** RotateCursor SpinCursor ! PyMac_GetFullPath PyMac_AppRefNum PyMac_options --- 660,664 ---- RotateCursor SpinCursor ! PyMac_GetFullPathname PyMac_AppRefNum PyMac_options *************** *** 791,794 **** --- 795,800 ---- PyUnicodeUCS2_EncodeUTF8 PyUnicodeUCS2_DecodeUTF8 + PyUnicode_EncodeUTF7 + PyUnicode_DecodeUTF7 PyUnicodeUCS2_SetDefaultEncoding PyUnicodeUCS2_GetDefaultEncoding *************** *** 844,847 **** --- 850,854 ---- PyExc_IndentationError PyExc_TabError + PyExc_ReferenceError PyExc_SystemError PyExc_SystemExit *************** *** 878,881 **** --- 885,889 ---- PyOS_vsnprintf PyOS_snprintf + PyWrapperDescr_Type proxytype wrappertype *************** *** 1021,1024 **** --- 1029,1040 ---- PyMac_StrError PyMac_getscript + _PyWeakref_RefType + _PyWeakref_ProxyType + _PyWeakref_CallableProxyType + PyObject_ClearWeakRefs + PyWeakref_GetObject + PyWeakref_NewProxy + PyWeakref_NewRef + _PyWeakref_GetWeakrefCount GUSISetupConsoleStdio GUSIStdioFlush From jackjansen@users.sourceforge.net Mon Oct 8 14:16:41 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 08 Oct 2001 06:16:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Include macglue.h,1.58,1.59 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Include In directory usw-pr-cvs1:/tmp/cvs-serv5454 Modified Files: macglue.h Log Message: Added declarations for PyMac_SetConsoleHandler, PyMan_DUmmyReadHandler and PyMac_DummyWriteHandler. Index: macglue.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Include/macglue.h,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -d -r1.58 -r1.59 *** macglue.h 2001/09/10 22:00:39 1.58 --- macglue.h 2001/10/08 13:16:39 1.59 *************** *** 124,127 **** --- 124,146 ---- #endif + #ifdef USE_GUSI2 + /* from pyGUSISIOUX.cp */ + typedef long (*PyWriteHandler)(char *buffer, long n); + typedef long (*PyReadHandler)(char *buffer, long n); + + /* Override routines that normally reads and writes to the + ** SIOUX console window. Intended for embedding applications + ** that want to forestall a Python console window ever showing up. + */ + void PyMac_SetConsoleHandler(PyReadHandler stdinH, PyWriteHandler stdoutH, + PyWriteHandler stderrH); + + /* Courtesy console handlers that drop all output and return + ** 0 on reads. + */ + long PyMac_DummyReadHandler(char *, long); + long PyMac_DummyWriteHandler(char *, long); + #endif /* USE_GUSI2 */ + #ifdef __cplusplus } From loewis@users.sourceforge.net Mon Oct 8 14:17:30 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Mon, 08 Oct 2001 06:17:30 -0700 Subject: [Python-checkins] CVS: python/dist/src configure.in,1.265,1.266 configure,1.257,1.258 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv5700 Modified Files: configure.in configure Log Message: Provide explicit program when trying to link pthread_create. Contributed by Albert Chin in discussion of bug #210665. Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.265 retrieving revision 1.266 diff -C2 -d -r1.265 -r1.266 *** configure.in 2001/10/07 08:39:18 1.265 --- configure.in 2001/10/08 13:17:28 1.266 *************** *** 953,957 **** LIBOBJS="$LIBOBJS thread.o"],[ AC_MSG_RESULT(no) ! AC_CHECK_LIB(pthread, pthread_create, [AC_DEFINE(WITH_THREAD) case $ac_sys_system in Darwin*) ;; --- 953,969 ---- LIBOBJS="$LIBOBJS thread.o"],[ AC_MSG_RESULT(no) ! ! # Just looking for pthread_create in libpthread is not enough: ! # on HP/UX, pthread.h renames pthread_create to a different symbol name. ! # So we really have to include pthread.h, and then link. ! _libs=$LIBS ! LIBS="$LIBS -lpthread" ! AC_MSG_CHECKING([for pthread_create in -lpthread]) ! AC_TRY_LINK([#include ! ! void * start_routine (void *arg) { exit (0); }], [ ! pthread_create (NULL, NULL, start_routine, NULL)], [ ! AC_MSG_RESULT(yes) ! AC_DEFINE(WITH_THREAD) case $ac_sys_system in Darwin*) ;; *************** *** 960,965 **** ;; esac - LIBS="-lpthread $LIBS" LIBOBJS="$LIBOBJS thread.o"],[ AC_CHECK_FUNC(pthread_detach, [AC_DEFINE(WITH_THREAD) case $ac_sys_system in --- 972,977 ---- ;; esac LIBOBJS="$LIBOBJS thread.o"],[ + LIBS=$_libs AC_CHECK_FUNC(pthread_detach, [AC_DEFINE(WITH_THREAD) case $ac_sys_system in Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.257 retrieving revision 1.258 diff -C2 -d -r1.257 -r1.258 *** configure 2001/10/07 08:39:18 1.257 --- configure 2001/10/08 13:17:28 1.258 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.264 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.265 [...2678 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 < *************** *** 7235,7239 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7238: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 7225,7229 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7228: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then From loewis@users.sourceforge.net Mon Oct 8 14:18:39 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Mon, 08 Oct 2001 06:18:39 -0700 Subject: [Python-checkins] CVS: python/dist/src setup.py,1.58,1.59 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv5785 Modified Files: setup.py Log Message: Do not add -shared to linker_so. Any necessary options should already be in LDSHARED. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -d -r1.58 -r1.59 *** setup.py 2001/10/03 19:59:30 1.58 --- setup.py 2001/10/08 13:18:37 1.59 *************** *** 142,149 **** args['compiler_so'] = compiler + ' ' + opt + ' ' + ccshared if linker_so is not None: ! if platform == 'darwin1': ! args['linker_so'] = linker_so ! else: ! args['linker_so'] = linker_so + ' -shared' self.compiler.set_executables(**args) --- 142,146 ---- args['compiler_so'] = compiler + ' ' + opt + ' ' + ccshared if linker_so is not None: ! args['linker_so'] = linker_so self.compiler.set_executables(**args) From jackjansen@users.sourceforge.net Mon Oct 8 14:21:17 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 08 Oct 2001 06:21:17 -0700 Subject: [Python-checkins] CVS: python/dist/src README,1.128,1.129 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv6440 Modified Files: README Log Message: Mac OS X build instructions talked about --without-toolbox-glue, but the configure option is really called --disable-toolbox-glue. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/README,v retrieving revision 1.128 retrieving revision 1.129 diff -C2 -d -r1.128 -r1.129 *** README 2001/10/05 17:04:42 1.128 --- README 2001/10/08 13:21:15 1.129 *************** *** 401,405 **** X?). On naked Darwin you may have to add the configure option ! "--without-toolbox-glue" to disable the glue code for the Carbon interface modules. (The modules themselves are currently not built by default as they are experimental, on real OSX you can enable them --- 401,405 ---- X?). On naked Darwin you may have to add the configure option ! "--disable-toolbox-glue" to disable the glue code for the Carbon interface modules. (The modules themselves are currently not built by default as they are experimental, on real OSX you can enable them From gvanrossum@users.sourceforge.net Mon Oct 8 16:18:29 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 08 Oct 2001 08:18:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.94,2.95 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv9030/Include Modified Files: object.h Log Message: Keep track of a type's subclasses (subtypes), in tp_subclasses, which is a list of weak references to types (new-style classes). Make this accessible to Python as the function __subclasses__ which returns a list of types -- we don't want Python programmers to be able to manipulate the raw list. In order to make this possible, I also had to add weak reference support to type objects. This will eventually be used together with a trap on attribute assignment for dynamic classes for a major speed-up without losing the dynamic properties of types: when a __foo__ method is added to a class, the class and all its subclasses will get an appropriate tp_foo slot function. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.94 retrieving revision 2.95 diff -C2 -d -r2.94 -r2.95 *** object.h 2001/10/05 21:58:11 2.94 --- object.h 2001/10/08 15:18:27 2.95 *************** *** 290,293 **** --- 290,295 ---- PyObject *tp_mro; /* method resolution order */ PyObject *tp_defined; + PyObject *tp_subclasses; + PyObject *tp_weaklist; #ifdef COUNT_ALLOCS From gvanrossum@users.sourceforge.net Mon Oct 8 16:18:29 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 08 Oct 2001 08:18:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.93,2.94 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9030/Objects Modified Files: typeobject.c Log Message: Keep track of a type's subclasses (subtypes), in tp_subclasses, which is a list of weak references to types (new-style classes). Make this accessible to Python as the function __subclasses__ which returns a list of types -- we don't want Python programmers to be able to manipulate the raw list. In order to make this possible, I also had to add weak reference support to type objects. This will eventually be used together with a trap on attribute assignment for dynamic classes for a major speed-up without losing the dynamic properties of types: when a __foo__ method is added to a class, the class and all its subclasses will get an appropriate tp_foo slot function. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.93 retrieving revision 2.94 diff -C2 -d -r2.93 -r2.94 *** typeobject.c 2001/10/07 03:54:51 2.93 --- typeobject.c 2001/10/08 15:18:27 2.94 *************** *** 1119,1122 **** --- 1119,1123 ---- assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE); _PyObject_GC_UNTRACK(type); + PyObject_ClearWeakRefs((PyObject *)type); et = (etype *)type; Py_XDECREF(type->tp_base); *************** *** 1125,1128 **** --- 1126,1130 ---- Py_XDECREF(type->tp_mro); Py_XDECREF(type->tp_defined); + Py_XDECREF(type->tp_subclasses); Py_XDECREF(et->name); Py_XDECREF(et->slots); *************** *** 1130,1136 **** --- 1132,1168 ---- } + static PyObject * + type_subclasses(PyTypeObject *type, PyObject *args_ignored) + { + PyObject *list, *raw, *ref; + int i, n; + + list = PyList_New(0); + if (list == NULL) + return NULL; + raw = type->tp_subclasses; + if (raw == NULL) + return list; + assert(PyList_Check(raw)); + n = PyList_GET_SIZE(raw); + for (i = 0; i < n; i++) { + ref = PyList_GET_ITEM(raw, i); + assert(PyWeakref_CheckRef(res)); + ref = PyWeakref_GET_OBJECT(ref); + if (ref != Py_None) { + if (PyList_Append(list, ref) < 0) { + Py_DECREF(list); + return NULL; + } + } + } + return list; + } + static PyMethodDef type_methods[] = { {"mro", (PyCFunction)mro_external, METH_NOARGS, "mro() -> list\nreturn a type's method resolution order"}, + {"__subclasses__", (PyCFunction)type_subclasses, METH_NOARGS, + "__subclasses__() -> list of immediate subclasses"}, {0} }; *************** *** 1163,1166 **** --- 1195,1199 ---- VISIT(type->tp_bases); VISIT(type->tp_base); + VISIT(type->tp_subclasses); VISIT(et->slots); *************** *** 1193,1196 **** --- 1226,1230 ---- CLEAR(type->tp_bases); CLEAR(type->tp_base); + CLEAR(type->tp_subclasses); CLEAR(et->slots); *************** *** 1238,1242 **** (inquiry)type_clear, /* tp_clear */ 0, /* tp_richcompare */ ! 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ --- 1272,1276 ---- (inquiry)type_clear, /* tp_clear */ 0, /* tp_richcompare */ ! offsetof(PyTypeObject, tp_weaklist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ *************** *** 1742,1745 **** --- 1776,1780 ---- staticforward int add_operators(PyTypeObject *); + staticforward int add_subclass(PyTypeObject *base, PyTypeObject *type); int *************** *** 1859,1862 **** --- 1894,1906 ---- } + /* Link into each base class's list of subclasses */ + bases = type->tp_bases; + n = PyTuple_GET_SIZE(bases); + for (i = 0; i < n; i++) { + base = (PyTypeObject *) PyTuple_GET_ITEM(bases, i); + if (add_subclass((PyTypeObject *)base, type) < 0) + goto error; + } + /* All done -- set the ready flag */ assert(type->tp_dict != NULL); *************** *** 1868,1871 **** --- 1912,1941 ---- type->tp_flags &= ~Py_TPFLAGS_READYING; return -1; + } + + static int + add_subclass(PyTypeObject *base, PyTypeObject *type) + { + int i; + PyObject *list, *ref, *new; + + list = base->tp_subclasses; + if (list == NULL) { + base->tp_subclasses = list = PyList_New(0); + if (list == NULL) + return -1; + } + assert(PyList_Check(list)); + new = PyWeakref_NewRef((PyObject *)type, NULL); + i = PyList_GET_SIZE(list); + while (--i >= 0) { + ref = PyList_GET_ITEM(list, i); + assert(PyWeakref_CheckRef(ref)); + if (PyWeakref_GET_OBJECT(ref) == Py_None) + return PyList_SetItem(list, i, new); + } + i = PyList_Append(list, new); + Py_DECREF(new); + return i; } From jackjansen@users.sourceforge.net Mon Oct 8 16:32:14 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 08 Oct 2001 08:32:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Demo/embed embeddemo.prj,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/embed In directory usw-pr-cvs1:/tmp/cvs-serv14298/python/Mac/Demo/embed Modified Files: embeddemo.prj Log Message: Brought up to date with the current state of affairs. Index: embeddemo.prj =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/embed/embeddemo.prj,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 Binary files /tmp/cvsB0aQ4b and /tmp/cvskGJkUd differ From jackjansen@users.sourceforge.net Mon Oct 8 16:32:19 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 08 Oct 2001 08:32:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Demo/embed demo.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/embed In directory usw-pr-cvs1:/tmp/cvs-serv14354/python/Mac/Demo/embed Modified Files: demo.c Log Message: Brought up to date with the current state of affairs. Index: demo.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/embed/demo.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** demo.c 1997/01/15 16:53:34 1.1 --- demo.c 2001/10/08 15:32:17 1.2 *************** *** 4,8 **** #ifdef macintosh #include "macglue.h" - #include #endif /* macintosh */ --- 4,7 ---- *************** *** 22,25 **** --- 21,30 ---- /* Initialize the Python interpreter. Required. */ #ifdef macintosh + /* If the first option is "-q" we don't open a console */ + if ( argc > 1 && strcmp(argv[1], "-q") == 0 ) { + PyMac_SetConsoleHandler(PyMac_DummyReadHandler, PyMac_DummyWriteHandler, + PyMac_DummyWriteHandler); + /* freopen("demo output", "w", stdout); */ + } PyMac_Initialize(); #else *************** *** 46,53 **** /* Some more application specific code */ printf("\nGoodbye, cruel world\n"); - #ifdef macintosh - printf("Type return or so-\n"); - getchar(); - #endif /* Exit, cleaning up the interpreter */ Py_Exit(0); --- 51,54 ---- From jackjansen@users.sourceforge.net Mon Oct 8 16:35:28 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 08 Oct 2001 08:35:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Build PythonCore.exp,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory usw-pr-cvs1:/tmp/cvs-serv15262/python/Mac/Build Modified Files: PythonCore.exp Log Message: Mods by Alexandre Parenteau to allow embedding programs to disable the MacPython console window completely, and optionally route console output (and input) to routines provided by the embedding app. Things don't fully work yet, but at least it doesn't break anything. Index: PythonCore.exp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCore.exp,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** PythonCore.exp 2001/10/08 13:00:51 1.16 --- PythonCore.exp 2001/10/08 15:35:26 1.17 *************** *** 6,11 **** __vt__15GUSISIOUXSocket # GUSISIOUXSocket::__vt sInstance__15GUSISIOUXDevice # GUSISIOUXDevice::sInstance ! sInstance__15GUSISIOUXSocket # GUSISIOUXSocket::sInstance __dt__15GUSISIOUXDeviceFv # GUSISIOUXDevice::~GUSISIOUXDevice() GUSISetupConsoleDescriptors open__15GUSISIOUXDeviceFR13GUSIFileTokeni # GUSISIOUXDevice::open(GUSIFileToken&,int) --- 6,14 ---- __vt__15GUSISIOUXSocket # GUSISIOUXSocket::__vt sInstance__15GUSISIOUXDevice # GUSISIOUXDevice::sInstance ! initialized__15GUSISIOUXSocket # GUSISIOUXSocket::initialized __dt__15GUSISIOUXDeviceFv # GUSISIOUXDevice::~GUSISIOUXDevice() + PyMac_DummyWriteHandler + PyMac_DummyReadHandler + PyMac_SetConsoleHandler GUSISetupConsoleDescriptors open__15GUSISIOUXDeviceFR13GUSIFileTokeni # GUSISIOUXDevice::open(GUSIFileToken&,int) *************** *** 21,26 **** __dt__15GUSISIOUXSocketFv # GUSISIOUXSocket::~GUSISIOUXSocket() Initialize__15GUSISIOUXSocketFv # GUSISIOUXSocket::Initialize() ! __ct__15GUSISIOUXSocketFv # GUSISIOUXSocket::GUSISIOUXSocket() ! Instance__15GUSISIOUXSocketFv # GUSISIOUXSocket::Instance() Py_FileSystemDefaultEncoding _PyBuiltin_Init --- 24,29 ---- __dt__15GUSISIOUXSocketFv # GUSISIOUXSocket::~GUSISIOUXSocket() Initialize__15GUSISIOUXSocketFv # GUSISIOUXSocket::Initialize() ! __ct__15GUSISIOUXSocketFi # GUSISIOUXSocket::GUSISIOUXSocket(int) ! Instance__15GUSISIOUXSocketFi # GUSISIOUXSocket::Instance(int) Py_FileSystemDefaultEncoding _PyBuiltin_Init From jackjansen@users.sourceforge.net Mon Oct 8 16:35:35 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 08 Oct 2001 08:35:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Build PythonCoreCarbon.exp,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory usw-pr-cvs1:/tmp/cvs-serv15337/python/Mac/Build Modified Files: PythonCoreCarbon.exp Log Message: Mods by Alexandre Parenteau to allow embedding programs to disable the MacPython console window completely, and optionally route console output (and input) to routines provided by the embedding app. Things don't fully work yet, but at least it doesn't break anything. Index: PythonCoreCarbon.exp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCoreCarbon.exp,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** PythonCoreCarbon.exp 2001/10/08 13:01:05 1.16 --- PythonCoreCarbon.exp 2001/10/08 15:35:33 1.17 *************** *** 6,11 **** __vt__15GUSISIOUXSocket # GUSISIOUXSocket::__vt sInstance__15GUSISIOUXDevice # GUSISIOUXDevice::sInstance ! sInstance__15GUSISIOUXSocket # GUSISIOUXSocket::sInstance __dt__15GUSISIOUXDeviceFv # GUSISIOUXDevice::~GUSISIOUXDevice() GUSISetupConsoleDescriptors open__15GUSISIOUXDeviceFR13GUSIFileTokeni # GUSISIOUXDevice::open(GUSIFileToken&,int) --- 6,14 ---- __vt__15GUSISIOUXSocket # GUSISIOUXSocket::__vt sInstance__15GUSISIOUXDevice # GUSISIOUXDevice::sInstance ! initialized__15GUSISIOUXSocket # GUSISIOUXSocket::initialized __dt__15GUSISIOUXDeviceFv # GUSISIOUXDevice::~GUSISIOUXDevice() + PyMac_DummyWriteHandler + PyMac_DummyReadHandler + PyMac_SetConsoleHandler GUSISetupConsoleDescriptors open__15GUSISIOUXDeviceFR13GUSIFileTokeni # GUSISIOUXDevice::open(GUSIFileToken&,int) *************** *** 21,26 **** __dt__15GUSISIOUXSocketFv # GUSISIOUXSocket::~GUSISIOUXSocket() Initialize__15GUSISIOUXSocketFv # GUSISIOUXSocket::Initialize() ! __ct__15GUSISIOUXSocketFv # GUSISIOUXSocket::GUSISIOUXSocket() ! Instance__15GUSISIOUXSocketFv # GUSISIOUXSocket::Instance() Py_FileSystemDefaultEncoding _PyBuiltin_Init --- 24,29 ---- __dt__15GUSISIOUXSocketFv # GUSISIOUXSocket::~GUSISIOUXSocket() Initialize__15GUSISIOUXSocketFv # GUSISIOUXSocket::Initialize() ! __ct__15GUSISIOUXSocketFi # GUSISIOUXSocket::GUSISIOUXSocket(int) ! Instance__15GUSISIOUXSocketFi # GUSISIOUXSocket::Instance(int) Py_FileSystemDefaultEncoding _PyBuiltin_Init From jackjansen@users.sourceforge.net Mon Oct 8 16:35:40 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Mon, 08 Oct 2001 08:35:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Python pyGUSISIOUX.cp,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Python In directory usw-pr-cvs1:/tmp/cvs-serv15421/python/Mac/Python Modified Files: pyGUSISIOUX.cp Log Message: Mods by Alexandre Parenteau to allow embedding programs to disable the MacPython console window completely, and optionally route console output (and input) to routines provided by the embedding app. Things don't fully work yet, but at least it doesn't break anything. Index: pyGUSISIOUX.cp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Python/pyGUSISIOUX.cp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pyGUSISIOUX.cp 2001/04/25 22:07:27 1.2 --- pyGUSISIOUX.cp 2001/10/08 15:35:38 1.3 *************** *** 31,34 **** --- 31,40 ---- extern Boolean SIOUXUseWaitNextEvent; + static PyReadHandler sInConsole = 0L; + static PyWriteHandler sOutConsole = 0L; + static PyWriteHandler sErrConsole = 0L; + + inline bool hasCustomConsole(void) { return sInConsole != 0L; } + class GUSISIOUXSocket : public GUSISocket { public: *************** *** 43,54 **** bool select(bool * canRead, bool * canWrite, bool *); ! static GUSISIOUXSocket * Instance(); ! private: ! static GUSISIOUXSocket * sInstance; ! ! GUSISIOUXSocket(); ! bool initialized; ! void Initialize(); ! bool fDelayConsole; }; class GUSISIOUXDevice : public GUSIDevice { --- 49,58 ---- bool select(bool * canRead, bool * canWrite, bool *); ! static GUSISIOUXSocket * Instance(int fd); ! private: ! GUSISIOUXSocket(int fd); ! static bool initialized; ! static void Initialize(); ! int fFd; }; class GUSISIOUXDevice : public GUSIDevice { *************** *** 64,89 **** static GUSISIOUXDevice * sInstance; }; - GUSISIOUXSocket * GUSISIOUXSocket::sInstance; ! GUSISIOUXSocket * GUSISIOUXSocket::Instance() { ! if (!sInstance) ! if (sInstance = new GUSISIOUXSocket) ! sInstance->AddReference(); ! ! return sInstance; } // This declaration lies about the return type extern "C" void SIOUXHandleOneEvent(EventRecord *userevent); ! GUSISIOUXSocket::GUSISIOUXSocket() { ! if (PyMac_GetDelayConsoleFlag()) ! fDelayConsole = true; ! else ! fDelayConsole = false; ! if ( fDelayConsole ) ! initialized = 0; ! else Initialize(); /* Tell the upper layers there's no unseen output */ --- 68,84 ---- static GUSISIOUXDevice * sInstance; }; ! GUSISIOUXSocket * GUSISIOUXSocket::Instance(int fd) { ! return new GUSISIOUXSocket(fd); } // This declaration lies about the return type extern "C" void SIOUXHandleOneEvent(EventRecord *userevent); ! bool GUSISIOUXSocket::initialized = false; ! ! GUSISIOUXSocket::GUSISIOUXSocket(int fd) : fFd(fd) { ! if (!PyMac_GetDelayConsoleFlag() && !hasCustomConsole() && !initialized) Initialize(); /* Tell the upper layers there's no unseen output */ *************** *** 94,115 **** GUSISIOUXSocket::Initialize() { ! initialized = 1; ! InstallConsole(0); ! GUSISetHook(GUSI_EventHook+nullEvent, (GUSIHook)SIOUXHandleOneEvent); ! GUSISetHook(GUSI_EventHook+mouseDown, (GUSIHook)SIOUXHandleOneEvent); ! GUSISetHook(GUSI_EventHook+mouseUp, (GUSIHook)SIOUXHandleOneEvent); ! GUSISetHook(GUSI_EventHook+updateEvt, (GUSIHook)SIOUXHandleOneEvent); ! GUSISetHook(GUSI_EventHook+diskEvt, (GUSIHook)SIOUXHandleOneEvent); ! GUSISetHook(GUSI_EventHook+activateEvt, (GUSIHook)SIOUXHandleOneEvent); ! GUSISetHook(GUSI_EventHook+osEvt, (GUSIHook)SIOUXHandleOneEvent); ! PyMac_InitMenuBar(); } GUSISIOUXSocket::~GUSISIOUXSocket() { ! if ( !initialized ) return; RemoveConsole(); } ssize_t GUSISIOUXSocket::read(const GUSIScatterer & buffer) { if ( !initialized ) Initialize(); GUSIStdioFlush(); --- 89,125 ---- GUSISIOUXSocket::Initialize() { ! if(!initialized && !hasCustomConsole()) ! { ! initialized = true; ! InstallConsole(0); ! GUSISetHook(GUSI_EventHook+nullEvent, (GUSIHook)SIOUXHandleOneEvent); ! GUSISetHook(GUSI_EventHook+mouseDown, (GUSIHook)SIOUXHandleOneEvent); ! GUSISetHook(GUSI_EventHook+mouseUp, (GUSIHook)SIOUXHandleOneEvent); ! GUSISetHook(GUSI_EventHook+updateEvt, (GUSIHook)SIOUXHandleOneEvent); ! GUSISetHook(GUSI_EventHook+diskEvt, (GUSIHook)SIOUXHandleOneEvent); ! GUSISetHook(GUSI_EventHook+activateEvt, (GUSIHook)SIOUXHandleOneEvent); ! GUSISetHook(GUSI_EventHook+osEvt, (GUSIHook)SIOUXHandleOneEvent); ! PyMac_InitMenuBar(); ! } } GUSISIOUXSocket::~GUSISIOUXSocket() { ! if ( !initialized || hasCustomConsole() ) ! return; ! ! initialized = false; RemoveConsole(); } ssize_t GUSISIOUXSocket::read(const GUSIScatterer & buffer) { + if(hasCustomConsole()) + { + if(fFd == 0) + return buffer.SetLength( + sInConsole((char *) buffer.Buffer(), (int)buffer.Length())); + + return 0; + } + if ( !initialized ) Initialize(); GUSIStdioFlush(); *************** *** 122,125 **** --- 132,145 ---- ssize_t GUSISIOUXSocket::write(const GUSIGatherer & buffer) { + if(hasCustomConsole()) + { + if(fFd == 1) + return sOutConsole((char *) buffer.Buffer(), (int)buffer.Length()); + else if(fFd == 2) + return sErrConsole((char *) buffer.Buffer(), (int)buffer.Length()); + + return 0; + } + ssize_t rv; *************** *** 199,211 **** GUSISocket * GUSISIOUXDevice::open(GUSIFileToken &, int) { ! return GUSISIOUXSocket::Instance(); } void GUSISetupConsoleDescriptors() { GUSIDescriptorTable * table = GUSIDescriptorTable::Instance(); - GUSISIOUXSocket * SIOUX = GUSISIOUXSocket::Instance(); ! table->InstallSocket(SIOUX); ! table->InstallSocket(SIOUX); ! table->InstallSocket(SIOUX); } --- 219,250 ---- GUSISocket * GUSISIOUXDevice::open(GUSIFileToken &, int) { ! return GUSISIOUXSocket::Instance(1); } void GUSISetupConsoleDescriptors() { GUSIDescriptorTable * table = GUSIDescriptorTable::Instance(); ! table->InstallSocket(GUSISIOUXSocket::Instance(0)); ! table->InstallSocket(GUSISIOUXSocket::Instance(1)); ! table->InstallSocket(GUSISIOUXSocket::Instance(2)); ! } ! ! void PyMac_SetConsoleHandler(PyReadHandler stdinH, PyWriteHandler stdoutH, PyWriteHandler stderrH) ! { ! if(stdinH && stdoutH && stderrH) ! { ! sInConsole = stdinH; ! sOutConsole = stdoutH; ! sErrConsole = stderrH; ! } ! } ! ! long PyMac_DummyReadHandler(char *buffer, long n) ! { ! return 0; ! } ! ! long PyMac_DummyWriteHandler(char *buffer, long n) ! { ! return 0; } From fdrake@users.sourceforge.net Mon Oct 8 17:03:22 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 08 Oct 2001 09:03:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libcfgparser.tex,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv23369/lib Modified Files: libcfgparser.tex Log Message: Update the description of getboolean() to reflect the changes made by SF patch #467580. Index: libcfgparser.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcfgparser.tex,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** libcfgparser.tex 2001/10/01 17:04:10 1.18 --- libcfgparser.tex 2001/10/08 16:03:20 1.19 *************** *** 164,170 **** \begin{methoddesc}{getboolean}{section, option} A convenience method which coerces the \var{option} in the specified ! \var{section} to a Boolean value. Note that the only accepted values ! for the option are \samp{0} and \samp{1}, any others will raise ! \exception{ValueError}. \end{methoddesc} --- 164,172 ---- \begin{methoddesc}{getboolean}{section, option} A convenience method which coerces the \var{option} in the specified ! \var{section} to a Boolean value. Note that the accepted values ! for the option are \code{1}, \code{yes}, \code{true}, and \code{on}, ! which cause this method to return true, and \code{0}, \code{no}, ! \code{false}, and \code{off}, which cause it to return false. Any ! other value will cause it to raise \exception{ValueError}. \end{methoddesc} From gvanrossum@users.sourceforge.net Mon Oct 8 17:35:47 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 08 Oct 2001 09:35:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.83,1.84 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv1312 Modified Files: test_descr.py Log Message: Change all occurrences of verify(x == y) into vereq(x, y), since when this type of test fails, vereq() does a better job of reporting than verify(). Change vereq(x, y) to use "not x == y" rather than "x != y" -- it makes a difference is some overloading tests. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.83 retrieving revision 1.84 diff -C2 -d -r1.83 -r1.84 *** test_descr.py 2001/10/04 05:48:13 1.83 --- test_descr.py 2001/10/08 16:35:45 1.84 *************** *** 5,43 **** def vereq(a, b): ! if a != b: ! raise TestFailed, "%r != %r" % (a, b) def testunop(a, res, expr="len(a)", meth="__len__"): if verbose: print "checking", expr dict = {'a': a} ! verify(eval(expr, dict) == res) t = type(a) [...2153 lines suppressed...] a.bar.append(4) ! verify(d.bar == [1,2,3]) def binopoverride(): --- 2173,2187 ---- a.foo = 12 b = copy.copy(a) ! vereq(b.__dict__, a.__dict__) a.bar = [1,2,3] c = copy.copy(a) ! vereq(c.bar, a.bar) verify(c.bar is a.bar) d = copy.deepcopy(a) ! vereq(d.__dict__, a.__dict__) a.bar.append(4) ! vereq(d.bar, [1,2,3]) def binopoverride(): From tim_one@users.sourceforge.net Mon Oct 8 17:49:34 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 08 Oct 2001 09:49:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.94,2.95 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv4840/python/Objects Modified Files: typeobject.c Log Message: type_subclasses(): debug build was broken due to typo in new assert(). Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.94 retrieving revision 2.95 diff -C2 -d -r2.94 -r2.95 *** typeobject.c 2001/10/08 15:18:27 2.94 --- typeobject.c 2001/10/08 16:49:26 2.95 *************** *** 1148,1152 **** for (i = 0; i < n; i++) { ref = PyList_GET_ITEM(raw, i); ! assert(PyWeakref_CheckRef(res)); ref = PyWeakref_GET_OBJECT(ref); if (ref != Py_None) { --- 1148,1152 ---- for (i = 0; i < n; i++) { ref = PyList_GET_ITEM(raw, i); ! assert(PyWeakref_CheckRef(ref)); ref = PyWeakref_GET_OBJECT(ref); if (ref != Py_None) { From fdrake@users.sourceforge.net Mon Oct 8 18:13:14 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 08 Oct 2001 10:13:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_cfgparser.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv15375 Modified Files: test_cfgparser.py Log Message: Added tests that check getboolean() with the newly allowed values from SF patch #467580. Index: test_cfgparser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_cfgparser.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_cfgparser.py 2001/07/06 17:22:48 1.8 --- test_cfgparser.py 2001/10/08 17:13:11 1.9 *************** *** 79,82 **** --- 79,101 ---- + def boolean(src): + print "Testing interpretation of boolean Values..." + cf = ConfigParser.ConfigParser() + sio = StringIO.StringIO(src) + cf.readfp(sio) + for x in range(1, 5): + verify(cf.getboolean('BOOLTEST', 't%d' % (x)) == 1) + for x in range(1, 5): + verify(cf.getboolean('BOOLTEST', 'f%d' % (x)) == 0) + for x in range(1, 5): + try: + cf.getboolean('BOOLTEST', 'e%d' % (x)) + except ValueError: + pass + else: + raise TestFailed( + "getboolean() failed to report a non boolean value") + + def interpolation(src): print "Testing value interpolation..." *************** *** 181,184 **** --- 200,221 ---- """) case_sensitivity() + boolean(r""" + [BOOLTEST] + T1=1 + T2=TRUE + T3=True + T4=oN + T5=yes + F1=0 + F2=FALSE + F3=False + F4=oFF + F5=nO + E1=2 + E2=foo + E3=-1 + E4=0.1 + E5=FALSE AND MORE + """) interpolation(r""" [Foo] From fdrake@users.sourceforge.net Mon Oct 8 18:13:14 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 08 Oct 2001 10:13:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_cfgparser,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv15375/output Modified Files: test_cfgparser Log Message: Added tests that check getboolean() with the newly allowed values from SF patch #467580. Index: test_cfgparser =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_cfgparser,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_cfgparser 2001/02/26 21:55:34 1.4 --- test_cfgparser 2001/10/08 17:13:12 1.5 *************** *** 2,5 **** --- 2,6 ---- Testing basic accessors... Testing case sensitivity... + Testing interpretation of boolean Values... Testing value interpolation... Testing parse errors... From jhylton@users.sourceforge.net Mon Oct 8 21:33:22 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Mon, 08 Oct 2001 13:33:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts trace.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv20602 Modified Files: trace.py Log Message: Replace all instances of err.strerror with err. The strerror attribute contained only partial information about the exception and produced some very confusing error messages. By passing err (the exception object itself) and letting it convert itself to a string, the error messages are better. Index: trace.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/trace.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** trace.py 2001/05/08 04:20:52 1.4 --- trace.py 2001/10/08 20:33:20 1.5 *************** *** 354,358 **** except IOError, err: print >> sys.stderr, "trace: Could not open %s for reading " \ ! "because: %s - skipping" % (`filename`, err.strerror) continue --- 354,358 ---- except IOError, err: print >> sys.stderr, "trace: Could not open %s for reading " \ ! "because: %s - skipping" % (`filename`, err) continue *************** *** 362,366 **** sys.stderr.write( '%s: Could not open %s for writing because: %s" \ ! "- skipping\n' % ("trace", `listfilename`, err.strerror)) continue --- 362,366 ---- sys.stderr.write( '%s: Could not open %s for writing because: %s" \ ! "- skipping\n' % ("trace", `listfilename`, err)) continue *************** *** 417,421 **** except IOError, err: sys.stderr.write("cannot save counts/modules " \ ! "files because %s" % err.strerror) if summary and sums: --- 417,421 ---- except IOError, err: sys.stderr.write("cannot save counts/modules " \ ! "files because %s" % err) if summary and sums: *************** *** 664,668 **** except IOError, err: _err_exit("Cannot run file %s because: %s" % \ ! (`sys.argv[0]`, err.strerror)) elif count: --- 664,668 ---- except IOError, err: _err_exit("Cannot run file %s because: %s" % \ ! (`sys.argv[0]`, err)) elif count: *************** *** 672,676 **** except IOError, err: _err_exit("Cannot run file %s because: %s" % \ ! (`sys.argv[0]`, err.strerror)) except SystemExit: pass --- 672,676 ---- except IOError, err: _err_exit("Cannot run file %s because: %s" % \ ! (`sys.argv[0]`, err)) except SystemExit: pass *************** *** 700,704 **** except IOError, err: _err_exit("Cannot save counts file %s because: %s" % \ ! (`counts_file`, err.strerror)) elif report: --- 700,704 ---- except IOError, err: _err_exit("Cannot save counts file %s because: %s" % \ ! (`counts_file`, err)) elif report: From gvanrossum@users.sourceforge.net Mon Oct 8 23:49:14 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 08 Oct 2001 15:49:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/idle help.txt,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/idle In directory usw-pr-cvs1:/tmp/cvs-serv21411 Modified Files: help.txt Log Message: Update outdated text about how to fix the font. Index: help.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/idle/help.txt,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** help.txt 2001/01/19 03:30:58 1.9 --- help.txt 2001/10/08 22:49:12 1.10 *************** *** 124,131 **** Other preferences: ! To change the font on Windows, open EditorWindow.py and change ! text['font'] = ("lucida console", 8) ! to, e.g., ! text['font'] = ("courier new", 10) To change keyboard bindings, edit Bindings.py --- 124,132 ---- Other preferences: ! Most preferences can be changed by editing one of the ! configuration text files: config.txt (generic) or one of ! config-unix.txt, config-win.txt, config.mac.txt (platform ! specific). User-specific preferences can be stored in ! $HOME/.idle, which overrides the config*.txt files. To change keyboard bindings, edit Bindings.py From tim_one@users.sourceforge.net Tue Oct 9 06:31:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 08 Oct 2001 22:31:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.272,1.273 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv8331/python/Misc Modified Files: NEWS Log Message: A brand new implementation of Profile.calibrate(). This measures an actual run of the profiler, instead of timing a simplified simulation of part of what the profiler does. It computes a constant about 60% higher on my Win98SE box than the old method, and the new constant appears much more realistic. Deleted the undocumented simple(), instrumented(), and profiler_simulation() methods (which existed only to support the previous calibration method). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.272 retrieving revision 1.273 diff -C2 -d -r1.272 -r1.273 *** NEWS 2001/10/07 03:12:08 1.272 --- NEWS 2001/10/09 05:31:56 1.273 *************** *** 48,51 **** --- 48,55 ---- without losing information). + - Profile.calibrate() has a new implementation that should deliver + a better system-specific calibration constant. Calibration must still + be done manually (see the docs for the profile module). + - quopri's encode and decode methods take an optional header parameter, which indicates whether output is intended for the header 'Q' encoding. From tim_one@users.sourceforge.net Tue Oct 9 06:31:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 08 Oct 2001 22:31:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv8331/python/Lib Modified Files: profile.py Log Message: A brand new implementation of Profile.calibrate(). This measures an actual run of the profiler, instead of timing a simplified simulation of part of what the profiler does. It computes a constant about 60% higher on my Win98SE box than the old method, and the new constant appears much more realistic. Deleted the undocumented simple(), instrumented(), and profiler_simulation() methods (which existed only to support the previous calibration method). Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** profile.py 2001/10/07 08:49:02 1.39 --- profile.py 2001/10/09 05:31:56 1.40 *************** *** 191,196 **** timer = self.timer t = timer() ! t = t[0] + t[1] - self.t # No Calibration constant ! # t = t[0] + t[1] - self.t - .00053 # Calibration constant if self.dispatch[event](self, frame,t): --- 191,195 ---- timer = self.timer t = timer() ! t = t[0] + t[1] - self.t # - .00053 calibration constant if self.dispatch[event](self, frame,t): *************** *** 208,212 **** def trace_dispatch_i(self, frame, event, arg): timer = self.timer ! t = timer() - self.t # - 1 # calibration constant if self.dispatch[event](self, frame,t): self.t = timer() --- 207,211 ---- def trace_dispatch_i(self, frame, event, arg): timer = self.timer ! t = timer() - self.t # - 16e-6 # calibration constant if self.dispatch[event](self, frame,t): self.t = timer() *************** *** 220,224 **** def trace_dispatch_mac(self, frame, event, arg): timer = self.timer ! t = timer()/60.0 - self.t # - 1 # Integer calibration constant if self.dispatch[event](self, frame,t): self.t = timer()/60.0 --- 219,223 ---- def trace_dispatch_mac(self, frame, event, arg): timer = self.timer ! t = timer()/60.0 - self.t # - 1 # calibration constant if self.dispatch[event](self, frame,t): self.t = timer()/60.0 *************** *** 468,510 **** #************************************************************** ! def calibrate(self, m): ! # Modified by Tim Peters get_time = self.get_time - n = m - s = get_time() - while n: - self.simple() - n = n - 1 - f = get_time() - my_simple = f - s - #print "Simple =", my_simple, ! n = m ! s = get_time() ! while n: ! self.instrumented() ! n = n - 1 ! f = get_time() ! my_inst = f - s ! # print "Instrumented =", my_inst ! avg_cost = (my_inst - my_simple)/m ! #print "Delta/call =", avg_cost, "(profiler fixup constant)" ! return avg_cost ! # simulate a program with no profiler activity ! def simple(self): ! a = 1 ! pass ! # simulate a program with call/return event processing ! def instrumented(self): ! a = 1 ! self.profiler_simulation(a, a, a) ! # simulate an event processing activity (from user's perspective) ! def profiler_simulation(self, x, y, z): ! t = self.timer() ! ## t = t[0] + t[1] ! self.ut = t #**************************************************************************** --- 467,531 ---- #************************************************************** ! def calibrate(self, m, verbose=0): get_time = self.get_time ! # Set up a test case to be run with and without profiling. Include ! # lots of calls, because we're trying to quantify stopwatch overhead. ! # Do not raise any exceptions, though, because we want to know ! # exactly how many profile events are generated (one call event, + ! # one return event, per Python-level call). ! def f1(n): ! for i in range(n): ! x = 1 ! def f(m, f1=f1): ! for i in range(m): ! f1(100) ! f(m) # warm up the cache ! ! # elapsed_noprofile <- time f(m) takes without profiling. ! t0 = get_time() ! f(m) ! t1 = get_time() ! elapsed_noprofile = t1 - t0 ! if verbose: ! print "elapsed time without profiling =", elapsed_noprofile ! ! # elapsed_profile <- time f(m) takes with profiling. The difference ! # is profiling overhead, only some of which the profiler subtracts ! # out on its own. ! p = Profile() ! t0 = get_time() ! p.runctx('f(m)', globals(), locals()) ! t1 = get_time() ! elapsed_profile = t1 - t0 ! if verbose: ! print "elapsed time with profiling =", elapsed_profile ! ! # reported_time <- "CPU seconds" the profiler charged to f and f1. ! total_calls = 0.0 ! reported_time = 0.0 ! for (filename, line, funcname), (cc, ns, tt, ct, callers) in \ ! p.timings.items(): ! if funcname in ("f", "f1"): ! total_calls += cc ! reported_time += tt ! ! if verbose: ! print "'CPU seconds' profiler reported =", reported_time ! print "total # calls =", total_calls ! if total_calls != m + 1: ! raise ValueError("internal error: total calls = %d" % total_calls) ! ! # reported_time - elapsed_noprofile = overhead the profiler wasn't ! # able to measure. Divide by twice the number of calls (since there ! # are two profiler events per call in this test) to get the hidden ! # overhead per event. ! mean = (reported_time - elapsed_noprofile) / 2.0 / total_calls ! if verbose: ! print "mean stopwatch overhead per profile event =", mean ! return mean #**************************************************************************** From loewis@users.sourceforge.net Tue Oct 9 11:10:36 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 09 Oct 2001 03:10:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib asyncore.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv6721 Modified Files: asyncore.py Log Message: Patch #468647: Fix exception propagation in asyncore. Index: asyncore.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asyncore.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** asyncore.py 2001/10/03 17:07:25 1.20 --- asyncore.py 2001/10/09 10:10:33 1.21 *************** *** 86,109 **** try: obj = map[fd] - try: - obj.handle_read_event() - except ExitNow: - raise ExitNow - except: - obj.handle_error() except KeyError: ! pass for fd in w: try: obj = map[fd] - try: - obj.handle_write_event() - except ExitNow: - raise ExitNow - except: - obj.handle_error() except KeyError: ! pass def poll2 (timeout=0.0, map=None): --- 86,111 ---- try: obj = map[fd] except KeyError: ! continue ! ! try: ! obj.handle_read_event() ! except ExitNow: ! raise ExitNow ! except: ! obj.handle_error() for fd in w: try: obj = map[fd] except KeyError: ! continue ! ! try: ! obj.handle_write_event() ! except ExitNow: ! raise ExitNow ! except: ! obj.handle_error() def poll2 (timeout=0.0, map=None): *************** *** 128,142 **** try: obj = map[fd] - try: - if (flags & poll.POLLIN): - obj.handle_read_event() - if (flags & poll.POLLOUT): - obj.handle_write_event() - except ExitNow: - raise ExitNow - except: - obj.handle_error() except KeyError: ! pass def poll3 (timeout=0.0, map=None): --- 130,145 ---- try: obj = map[fd] except KeyError: ! continue ! ! try: ! if (flags & poll.POLLIN): ! obj.handle_read_event() ! if (flags & poll.POLLOUT): ! obj.handle_write_event() ! except ExitNow: ! raise ExitNow ! except: ! obj.handle_error() def poll3 (timeout=0.0, map=None): *************** *** 161,175 **** try: obj = map[fd] - try: - if (flags & select.POLLIN): - obj.handle_read_event() - if (flags & select.POLLOUT): - obj.handle_write_event() - except ExitNow: - raise ExitNow - except: - obj.handle_error() except KeyError: ! pass def loop (timeout=30.0, use_poll=0, map=None): --- 164,179 ---- try: obj = map[fd] except KeyError: ! continue ! ! try: ! if (flags & select.POLLIN): ! obj.handle_read_event() ! if (flags & select.POLLOUT): ! obj.handle_write_event() ! except ExitNow: ! raise ExitNow ! except: ! obj.handle_error() def loop (timeout=30.0, use_poll=0, map=None): From loewis@users.sourceforge.net Tue Oct 9 11:47:01 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 09 Oct 2001 03:47:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules xxmodule.c,2.22,2.23 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv14529 Modified Files: xxmodule.c Log Message: Add additional fields to Xxo_Type declaration. Fixes bug #469250. Index: xxmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/xxmodule.c,v retrieving revision 2.22 retrieving revision 2.23 diff -C2 -d -r2.22 -r2.23 *** xxmodule.c 2000/09/01 23:29:27 2.22 --- xxmodule.c 2001/10/09 10:46:58 2.23 *************** *** 113,116 **** --- 113,147 ---- 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*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + 0, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_defined*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ }; /* --------------------------------------------------------------------- */ From loewis@users.sourceforge.net Tue Oct 9 11:54:33 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 09 Oct 2001 03:54:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules zlibmodule.c,2.42,2.43 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv15949 Modified Files: zlibmodule.c Log Message: Update URL. Fixes bug #468118. Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.42 retrieving revision 2.43 diff -C2 -d -r2.42 -r2.43 *** zlibmodule.c 2001/09/08 16:23:34 2.42 --- zlibmodule.c 2001/10/09 10:54:31 2.43 *************** *** 1,4 **** /* zlibmodule.c -- gzip-compatible data compression */ ! /* See http://www.info-zip.org/pub/infozip/zlib/ */ /* Windows users: read Python's PCbuild\readme.txt */ --- 1,4 ---- /* zlibmodule.c -- gzip-compatible data compression */ ! /* See http://www.gzip.org/zlib/ */ /* Windows users: read Python's PCbuild\readme.txt */ From gvanrossum@users.sourceforge.net Tue Oct 9 12:07:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 09 Oct 2001 04:07:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.84,1.85 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv19027/Lib/test Modified Files: test_descr.py Log Message: It turned out not so difficult to support old-style numbers (those without the Py_TPFLAGS_CHECKTYPES flag) in the wrappers. This required a few changes in test_descr.py to cope with the fact that the complex type has __int__, __long__ and __float__ methods that always raise an exception. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.84 retrieving revision 1.85 diff -C2 -d -r1.84 -r1.85 *** test_descr.py 2001/10/08 16:35:45 1.84 --- test_descr.py 2001/10/09 11:07:24 1.85 *************** *** 366,373 **** testbinop(a, b, res, expr, name) for name, expr in unops.items(): ! name = "__%s__" % name ! if hasattr(a, name): ! res = eval(expr, dict) ! testunop(a, res, expr, name) def ints(): --- 366,374 ---- testbinop(a, b, res, expr, name) for name, expr in unops.items(): ! if name not in skip: ! name = "__%s__" % name ! if hasattr(a, name): ! res = eval(expr, dict) ! testunop(a, res, expr, name) def ints(): *************** *** 385,389 **** def complexes(): if verbose: print "Testing complex operations..." ! numops(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge']) class Number(complex): __slots__ = ['prec'] --- 386,390 ---- def complexes(): if verbose: print "Testing complex operations..." ! numops(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge', 'int', 'long', 'float']) class Number(complex): __slots__ = ['prec'] From gvanrossum@users.sourceforge.net Tue Oct 9 12:07:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 09 Oct 2001 04:07:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.95,2.96 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv19027/Objects Modified Files: typeobject.c Log Message: It turned out not so difficult to support old-style numbers (those without the Py_TPFLAGS_CHECKTYPES flag) in the wrappers. This required a few changes in test_descr.py to cope with the fact that the complex type has __int__, __long__ and __float__ methods that always raise an exception. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.95 retrieving revision 2.96 diff -C2 -d -r2.95 -r2.96 *** typeobject.c 2001/10/08 16:49:26 2.95 --- typeobject.c 2001/10/09 11:07:24 2.96 *************** *** 1980,1983 **** --- 1980,1999 ---- static PyObject * + wrap_binaryfunc_l(PyObject *self, PyObject *args, void *wrapped) + { + binaryfunc func = (binaryfunc)wrapped; + PyObject *other; + + if (!PyArg_ParseTuple(args, "O", &other)) + return NULL; + if (!(self->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES) && + self->ob_type != other->ob_type) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + return (*func)(self, other); + } + + static PyObject * wrap_binaryfunc_r(PyObject *self, PyObject *args, void *wrapped) { *************** *** 1987,1990 **** --- 2003,2011 ---- if (!PyArg_ParseTuple(args, "O", &other)) return NULL; + if (!(self->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES) && + self->ob_type != other->ob_type) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } return (*func)(other, self); } *************** *** 1994,1998 **** static struct wrapperbase tab_##NAME[] = { \ {"__" #NAME "__", \ ! (wrapperfunc)wrap_binaryfunc, \ "x.__" #NAME "__(y) <==> " #OP}, \ {"__r" #NAME "__", \ --- 2015,2019 ---- static struct wrapperbase tab_##NAME[] = { \ {"__" #NAME "__", \ ! (wrapperfunc)wrap_binaryfunc_l, \ "x.__" #NAME "__(y) <==> " #OP}, \ {"__r" #NAME "__", \ *************** *** 2779,2787 **** } ! /* We don't support "old-style numbers" because their binary ! operators require that both arguments have the same type; ! the wrappers here only work for new-style numbers. */ ! if ((type->tp_flags & Py_TPFLAGS_CHECKTYPES) && ! (nb = type->tp_as_number) != NULL) { ADD(nb->nb_add, tab_add); ADD(nb->nb_subtract, tab_sub); --- 2800,2804 ---- } ! if ((nb = type->tp_as_number) != NULL) { ADD(nb->nb_add, tab_add); ADD(nb->nb_subtract, tab_sub); *************** *** 2818,2822 **** ADD(nb->nb_inplace_xor, tab_ixor); ADD(nb->nb_inplace_or, tab_ior); ! if (type->tp_flags & Py_TPFLAGS_CHECKTYPES) { ADD(nb->nb_floor_divide, tab_floordiv); ADD(nb->nb_true_divide, tab_truediv); --- 2835,2839 ---- ADD(nb->nb_inplace_xor, tab_ixor); ADD(nb->nb_inplace_or, tab_ior); ! if (type->tp_flags & Py_TPFLAGS_HAVE_CLASS) { ADD(nb->nb_floor_divide, tab_floordiv); ADD(nb->nb_true_divide, tab_truediv); From loewis@users.sourceforge.net Tue Oct 9 12:50:57 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 09 Oct 2001 04:50:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/lib-tk Tix.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory usw-pr-cvs1:/tmp/cvs-serv30068 Modified Files: Tix.py Log Message: Add entry parameter to HList.item_cget. Fixes bug #466981. Index: Tix.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/Tix.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Tix.py 2001/08/13 14:12:35 1.3 --- Tix.py 2001/10/09 11:50:55 1.4 *************** *** 731,736 **** return self.tk.splitlist(c) ! def item_cget(self, col, opt): ! return self.tk.call(self._w, 'item', 'cget', col, opt) def item_configure(self, entry, col, cnf={}, **kw): --- 731,736 ---- return self.tk.splitlist(c) ! def item_cget(self, entry, col, opt): ! return self.tk.call(self._w, 'item', 'cget', entry, col, opt) def item_configure(self, entry, col, cnf={}, **kw): From loewis@users.sourceforge.net Tue Oct 9 12:53:49 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Tue, 09 Oct 2001 04:53:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.117,1.118 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv31007 Modified Files: ACKS Log Message: Add Cesar Eduardo Barros, for asyncore patches. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.117 retrieving revision 1.118 diff -C2 -d -r1.117 -r1.118 *** ACKS 2001/10/05 14:12:23 1.117 --- ACKS 2001/10/09 11:53:47 1.118 *************** *** 23,26 **** --- 23,27 ---- Stig Bakken Greg Ball + Cesar Eduardo Barros Des Barry Ulf Bartelt From fdrake@users.sourceforge.net Tue Oct 9 15:58:26 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 09 Oct 2001 07:58:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libcfgparser.tex,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv24763/lib Modified Files: libcfgparser.tex Log Message: Note that the values for Boolean options are case-insensitive. Index: libcfgparser.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcfgparser.tex,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** libcfgparser.tex 2001/10/08 16:03:20 1.19 --- libcfgparser.tex 2001/10/09 14:58:24 1.20 *************** *** 167,172 **** for the option are \code{1}, \code{yes}, \code{true}, and \code{on}, which cause this method to return true, and \code{0}, \code{no}, ! \code{false}, and \code{off}, which cause it to return false. Any ! other value will cause it to raise \exception{ValueError}. \end{methoddesc} --- 167,173 ---- for the option are \code{1}, \code{yes}, \code{true}, and \code{on}, which cause this method to return true, and \code{0}, \code{no}, ! \code{false}, and \code{off}, which cause it to return false. These ! values are checked in a case-insensitive manner. Any other value will ! cause it to raise \exception{ValueError}. \end{methoddesc} From bwarsaw@users.sourceforge.net Tue Oct 9 16:46:33 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 09 Oct 2001 08:46:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib smtpd.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv8202/Lib Modified Files: smtpd.py Log Message: SMTPServer.__init__(): The asyncore.dispatcher base class has a method set_reuse_addr() that does the setsockopt fiddling. Use it instead. Index: smtpd.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/smtpd.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** smtpd.py 2001/10/05 17:10:31 1.9 --- smtpd.py 2001/10/09 15:46:31 1.10 *************** *** 278,284 **** self.create_socket(socket.AF_INET, socket.SOCK_STREAM) # try to re-use a server port if possible ! self.socket.setsockopt( ! socket.SOL_SOCKET, socket.SO_REUSEADDR, ! self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) | 1) self.bind(localaddr) self.listen(5) --- 278,282 ---- self.create_socket(socket.AF_INET, socket.SOCK_STREAM) # try to re-use a server port if possible ! self.set_reuse_addr() self.bind(localaddr) self.listen(5) From bwarsaw@users.sourceforge.net Tue Oct 9 16:48:34 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 09 Oct 2001 08:48:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email Message.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv8730/Lib/email Modified Files: Message.py Log Message: get_all(): We never returned failobj if we found no matching headers. Fix that, and also make the docstring describe failobj. Index: Message.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Message.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Message.py 2001/10/04 17:05:11 1.4 --- Message.py 2001/10/09 15:48:29 1.5 *************** *** 228,231 **** --- 228,233 ---- message, and may contain duplicates. Any fields deleted and re-inserted are alwyas appended to the header list. + + If no such fields exist, failobj is returned (defaults to None). """ values = [] *************** *** 234,237 **** --- 236,241 ---- if k.lower() == name: values.append(v) + if not values: + return failobj return values From bwarsaw@users.sourceforge.net Tue Oct 9 16:49:37 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 09 Oct 2001 08:49:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_email.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv8997/Lib/test Modified Files: test_email.py Log Message: Add a test for get_all() returning failobj. msg_20.txt is a sample message with multiple CC: fields, used in the get_all() test. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_email.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_email.py 2001/10/04 18:18:37 1.6 --- test_email.py 2001/10/09 15:49:35 1.7 *************** *** 51,54 **** --- 51,60 ---- # Test various aspects of the Message class's API class TestMessageAPI(TestEmailBase): + def test_get_all(self): + eq = self.assertEqual + msg = self._msgobj('msg_20.txt') + eq(msg.get_all('cc'), ['ccc@zzz.org', 'ddd@zzz.org', 'eee@zzz.org']) + eq(msg.get_all('xx', 'n/a'), 'n/a') + def test_get_charsets(self): eq = self.assertEqual From bwarsaw@users.sourceforge.net Tue Oct 9 16:49:37 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 09 Oct 2001 08:49:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/data msg_20.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/data In directory usw-pr-cvs1:/tmp/cvs-serv8997/Lib/test/data Added Files: msg_20.txt Log Message: Add a test for get_all() returning failobj. msg_20.txt is a sample message with multiple CC: fields, used in the get_all() test. --- NEW FILE: msg_20.txt --- Return-Path: Delivered-To: bbb@zzz.org Received: by mail.zzz.org (Postfix, from userid 889) id 27CEAD38CC; Fri, 4 May 2001 14:05:44 -0400 (EDT) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15090.61304.110929.45684@aaa.zzz.org> From: bbb@ddd.com (John X. Doe) To: bbb@zzz.org Cc: ccc@zzz.org CC: ddd@zzz.org cc: eee@zzz.org Subject: This is a test message Date: Fri, 4 May 2001 14:05:44 -0400 Hi, Do you like this message? -Me From jhylton@users.sourceforge.net Tue Oct 9 17:18:47 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 09 Oct 2001 09:18:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib urllib2.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv17496 Modified Files: urllib2.py Log Message: Fix [ #465502 ] urllib2: urlopen unicode problem When checking for strings use, ! if isinstance(uri, (types.StringType, types.UnicodeType)): Also get rid of some dodgy code that tried to guess whether attributes were callable or not. Index: urllib2.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/urllib2.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** urllib2.py 2001/08/27 20:16:53 1.21 --- urllib2.py 2001/10/09 16:18:45 1.22 *************** *** 90,93 **** --- 90,94 ---- import socket import httplib + import inspect import re import base64 *************** *** 253,257 **** def add_handler(self, handler): added = 0 ! for meth in get_methods(handler): if meth[-5:] == '_open': protocol = meth[:-5] --- 254,258 ---- def add_handler(self, handler): added = 0 ! for meth in dir(handler): if meth[-5:] == '_open': protocol = meth[:-5] *************** *** 304,308 **** def open(self, fullurl, data=None): # accept a URL or a Request object ! if isinstance(fullurl, types.StringType): req = Request(fullurl, data) else: --- 305,309 ---- def open(self, fullurl, data=None): # accept a URL or a Request object ! if isinstance(fullurl, (types.StringType, types.UnicodeType)): req = Request(fullurl, data) else: *************** *** 347,378 **** return self._call_chain(*args) - def is_callable(obj): - # not quite like builtin callable (which I didn't know existed), - # not entirely sure it needs to be different - if type(obj) in (types.BuiltinFunctionType, - types.BuiltinMethodType, types.LambdaType, - types.MethodType): - return 1 - if isinstance(obj, types.InstanceType): - return hasattr(obj, '__call__') - return 0 - - def get_methods(inst): - methods = {} - classes = [] - classes.append(inst.__class__) - while classes: - klass = classes[0] - del classes[0] - classes = classes + list(klass.__bases__) - for name in dir(klass): - attr = getattr(klass, name) - if isinstance(attr, types.UnboundMethodType): - methods[name] = 1 - for name in dir(inst): - if is_callable(getattr(inst, name)): - methods[name] = 1 - return methods.keys() - # XXX probably also want an abstract factory that knows things like # the fact that a ProxyHandler needs to get inserted first. --- 348,351 ---- *************** *** 400,409 **** for klass in default_classes: for check in handlers: ! if isinstance(check, types.ClassType): if issubclass(check, klass): - skip.append(klass) - elif isinstance(check, types.InstanceType): - if isinstance(check, klass): skip.append(klass) for klass in skip: default_classes.remove(klass) --- 373,381 ---- for klass in default_classes: for check in handlers: ! if inspect.isclass(check): if issubclass(check, klass): skip.append(klass) + elif isinstance(check, klass): + skip.append(klass) for klass in skip: default_classes.remove(klass) *************** *** 413,417 **** for h in handlers: ! if isinstance(h, types.ClassType): h = h() opener.add_handler(h) --- 385,389 ---- for h in handlers: ! if inspect.isclass(h): h = h() opener.add_handler(h) *************** *** 546,550 **** def add_password(self, realm, uri, user, passwd): # uri could be a single URI or a sequence ! if isinstance(uri, types.StringType): uri = [uri] uri = tuple(map(self.reduce_uri, uri)) --- 518,522 ---- def add_password(self, realm, uri, user, passwd): # uri could be a single URI or a sequence ! if isinstance(uri, (types.StringType, types.UnicodeType)): uri = [uri] uri = tuple(map(self.reduce_uri, uri)) *************** *** 1068,1072 **** opener = OpenerDirector() for ph in self.proxy_handlers: ! if isinstance(ph, types.ClassType): ph = ph() opener.add_handler(ph) --- 1040,1044 ---- opener = OpenerDirector() for ph in self.proxy_handlers: ! if inspect.isclass(ph): ph = ph() opener.add_handler(ph) *************** *** 1089,1120 **** 'file:/etc/passwd', 'file://nonsensename/etc/passwd', ! 'ftp://www.python.org/pub/tmp/httplib.py', ! 'ftp://www.python.org/pub/tmp/imageop.c', 'ftp://www.python.org/pub/tmp/blat', 'http://www.espn.com/', # redirect 'http://www.python.org/Spanish/Inquistion/', ! ('http://grail.cnri.reston.va.us/cgi-bin/faqw.py', 'query=pythonistas&querytype=simple&casefold=yes&req=search'), 'http://www.python.org/', ! 'ftp://prep.ai.mit.edu/welcome.msg', ! 'ftp://www.python.org/pub/tmp/figure.prn', ! 'ftp://www.python.org/pub/tmp/interp.pl', ! 'http://checkproxy.cnri.reston.va.us/test/test.html', ] ! if localhost is not None: ! urls = urls + [ ! 'file://%s/etc/passwd' % localhost, ! 'http://%s/simple/' % localhost, ! 'http://%s/digest/' % localhost, ! 'http://%s/not/found.h' % localhost, ! ] ! bauth = HTTPBasicAuthHandler() ! bauth.add_password('basic_test_realm', localhost, 'jhylton', ! 'password') ! dauth = HTTPDigestAuthHandler() ! dauth.add_password('digest_test_realm', localhost, 'jhylton', ! 'password') --- 1061,1088 ---- 'file:/etc/passwd', 'file://nonsensename/etc/passwd', ! 'ftp://www.python.org/pub/python/misc/sousa.au', 'ftp://www.python.org/pub/tmp/blat', 'http://www.espn.com/', # redirect 'http://www.python.org/Spanish/Inquistion/', ! ('http://www.python.org/cgi-bin/faqw.py', 'query=pythonistas&querytype=simple&casefold=yes&req=search'), 'http://www.python.org/', ! 'ftp://gatekeeper.research.compaq.com/pub/DEC/SRC/research-reports/00README-Legal-Rules-Regs', ] ! ## if localhost is not None: ! ## urls = urls + [ ! ## 'file://%s/etc/passwd' % localhost, ! ## 'http://%s/simple/' % localhost, ! ## 'http://%s/digest/' % localhost, ! ## 'http://%s/not/found.h' % localhost, ! ## ] ! ## bauth = HTTPBasicAuthHandler() ! ## bauth.add_password('basic_test_realm', localhost, 'jhylton', ! ## 'password') ! ## dauth = HTTPDigestAuthHandler() ! ## dauth.add_password('digest_test_realm', localhost, 'jhylton', ! ## 'password') *************** *** 1122,1135 **** cfh.setTimeout(1) ! # XXX try out some custom proxy objects too! ! def at_cnri(req): ! host = req.get_host() ! print host ! if host[-18:] == '.cnri.reston.va.us': ! return 1 ! p = CustomProxy('http', at_cnri, 'proxy.cnri.reston.va.us') ! ph = CustomProxyHandler(p) ! #install_opener(build_opener(dauth, bauth, cfh, GopherHandler, ph)) for url in urls: --- 1090,1104 ---- cfh.setTimeout(1) ! ## # XXX try out some custom proxy objects too! ! ## def at_cnri(req): ! ## host = req.get_host() ! ## print host ! ## if host[-18:] == '.cnri.reston.va.us': ! ## return 1 ! ## p = CustomProxy('http', at_cnri, 'proxy.cnri.reston.va.us') ! ## ph = CustomProxyHandler(p) ! ## install_opener(build_opener(dauth, bauth, cfh, GopherHandler, ph)) ! install_opener(build_opener(cfh, GopherHandler)) for url in urls: From fdrake@users.sourceforge.net Tue Oct 9 19:01:25 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 09 Oct 2001 11:01:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/doc doc.tex,1.54,1.55 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/doc In directory usw-pr-cvs1:/tmp/cvs-serv16087/doc Modified Files: doc.tex Log Message: New markup: \note{...} and \warning{...} Index: doc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/doc/doc.tex,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -d -r1.54 -r1.55 *** doc.tex 2001/09/26 18:43:20 1.54 --- doc.tex 2001/10/09 18:01:23 1.55 *************** *** 860,863 **** --- 860,871 ---- \end{macrodesc} + \begin{macrodesc}{note}{\p{text}} + An especially important bit of information about an API that a + user should be aware of when using whatever bit of API the + note pertains to. This should be the last thing in the + paragraph as the end of the note is not visually marked in + any way. + \end{macrodesc} + \begin{macrodesc}{pep}{\p{number}} A reference to a Python Enhancement Proposal. This generates *************** *** 988,991 **** --- 996,1008 ---- \macro{versionadded}. The location should be selected so the explanation makes sense and may vary as needed. + \end{macrodesc} + + \begin{macrodesc}{warning}{\p{text}} + An important bit of information about an API that a user should + be very aware of when using whatever bit of API the warning + pertains to. This should be the last thing in the paragraph as + the end of the warning is not visually marked in any way. This + differs from \macro{note} in that it is recommended over + \macro{note} for information regarding security. \end{macrodesc} From fdrake@users.sourceforge.net Tue Oct 9 19:01:25 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 09 Oct 2001 11:01:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/perl python.perl,1.110,1.111 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory usw-pr-cvs1:/tmp/cvs-serv16087/perl Modified Files: python.perl Log Message: New markup: \note{...} and \warning{...} Index: python.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/python.perl,v retrieving revision 1.110 retrieving revision 1.111 diff -C2 -d -r1.110 -r1.111 *** python.perl 2001/09/26 18:46:36 1.110 --- python.perl 2001/10/09 18:01:23 1.111 *************** *** 237,240 **** --- 237,250 ---- sub do_cmd_textit{ return use_wrappers(@_[0], '', ''); } + sub do_cmd_note{ + return use_wrappers( + @_[0], + "Note:\n", + ''); } + sub do_cmd_warning{ + return use_wrappers( + @_[0], + "Warning:\n", + ''); } sub do_cmd_moreargs{ From fdrake@users.sourceforge.net Tue Oct 9 19:01:25 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 09 Oct 2001 11:01:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs python.sty,1.82,1.83 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv16087/texinputs Modified Files: python.sty Log Message: New markup: \note{...} and \warning{...} Index: python.sty =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/python.sty,v retrieving revision 1.82 retrieving revision 1.83 diff -C2 -d -r1.82 -r1.83 *** python.sty 2001/09/26 18:46:36 1.82 --- python.sty 2001/10/09 18:01:23 1.83 *************** *** 882,885 **** --- 882,888 ---- } + \newcommand{\note}[1]{\strong{Note:} #1} + \newcommand{\warning}[1]{\strong{Warning:} #1} + % Deprecation stuff. % Should be extended to allow an index / list of deprecated stuff. But From fdrake@users.sourceforge.net Tue Oct 9 19:01:25 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 09 Oct 2001 11:01:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv conversion.xml,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv16087/tools/sgmlconv Modified Files: conversion.xml Log Message: New markup: \note{...} and \warning{...} Index: conversion.xml =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/conversion.xml,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** conversion.xml 2001/09/27 17:01:59 1.21 --- conversion.xml 2001/10/09 18:01:23 1.22 *************** *** 56,59 **** --- 56,65 ---- + + + + + + __le__, __lt__ - etc.) or mapping multiple slots to a single method (sq_item, - mp_subscript <--> __getitem__). */ ! static void ! override_slots(PyTypeObject *type, PyObject *dict) ! { ! PySequenceMethods *sq = type->tp_as_sequence; ! PyMappingMethods *mp = type->tp_as_mapping; ! PyNumberMethods *nb = type->tp_as_number; ! ! #define SQSLOT(OPNAME, SLOTNAME, FUNCNAME) \ ! if (dict == NULL || PyDict_GetItemString(dict, OPNAME)) { \ ! sq->SLOTNAME = FUNCNAME; \ ! } ! #define MPSLOT(OPNAME, SLOTNAME, FUNCNAME) \ ! if (dict == NULL || PyDict_GetItemString(dict, OPNAME)) { \ ! mp->SLOTNAME = FUNCNAME; \ ! } ! #define NBSLOT(OPNAME, SLOTNAME, FUNCNAME) \ ! if (dict == NULL || PyDict_GetItemString(dict, OPNAME)) { \ ! nb->SLOTNAME = FUNCNAME; \ ! } ! #define TPSLOT(OPNAME, SLOTNAME, FUNCNAME) \ ! if (dict == NULL || PyDict_GetItemString(dict, OPNAME)) { \ ! type->SLOTNAME = FUNCNAME; \ ! } ! SQSLOT("__len__", sq_length, slot_sq_length); ! SQSLOT("__add__", sq_concat, slot_sq_concat); ! SQSLOT("__mul__", sq_repeat, slot_sq_repeat); ! SQSLOT("__getitem__", sq_item, slot_sq_item); ! SQSLOT("__getslice__", sq_slice, slot_sq_slice); ! SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item); ! SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item); ! SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice); ! SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice); ! SQSLOT("__contains__", sq_contains, slot_sq_contains); ! SQSLOT("__iadd__", sq_inplace_concat, slot_sq_inplace_concat); ! SQSLOT("__imul__", sq_inplace_repeat, slot_sq_inplace_repeat); ! MPSLOT("__len__", mp_length, slot_mp_length); ! MPSLOT("__getitem__", mp_subscript, slot_mp_subscript); ! MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript); ! MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript); ! NBSLOT("__add__", nb_add, slot_nb_add); ! NBSLOT("__sub__", nb_subtract, slot_nb_subtract); ! NBSLOT("__mul__", nb_multiply, slot_nb_multiply); ! NBSLOT("__div__", nb_divide, slot_nb_divide); ! NBSLOT("__mod__", nb_remainder, slot_nb_remainder); ! NBSLOT("__divmod__", nb_divmod, slot_nb_divmod); ! NBSLOT("__pow__", nb_power, slot_nb_power); ! NBSLOT("__neg__", nb_negative, slot_nb_negative); ! NBSLOT("__pos__", nb_positive, slot_nb_positive); ! NBSLOT("__abs__", nb_absolute, slot_nb_absolute); ! NBSLOT("__nonzero__", nb_nonzero, slot_nb_nonzero); ! NBSLOT("__invert__", nb_invert, slot_nb_invert); ! NBSLOT("__lshift__", nb_lshift, slot_nb_lshift); ! NBSLOT("__rshift__", nb_rshift, slot_nb_rshift); ! NBSLOT("__and__", nb_and, slot_nb_and); ! NBSLOT("__xor__", nb_xor, slot_nb_xor); ! NBSLOT("__or__", nb_or, slot_nb_or); ! NBSLOT("__coerce__", nb_coerce, slot_nb_coerce); ! NBSLOT("__int__", nb_int, slot_nb_int); ! NBSLOT("__long__", nb_long, slot_nb_long); ! NBSLOT("__float__", nb_float, slot_nb_float); ! NBSLOT("__oct__", nb_oct, slot_nb_oct); ! NBSLOT("__hex__", nb_hex, slot_nb_hex); ! NBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add); ! NBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract); ! NBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply); ! NBSLOT("__idiv__", nb_inplace_divide, slot_nb_inplace_divide); ! NBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder); ! NBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power); ! NBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift); ! NBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift); ! NBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and); ! NBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor); ! NBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or); ! NBSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide); ! NBSLOT("__truediv__", nb_true_divide, slot_nb_true_divide); NBSLOT("__ifloordiv__", nb_inplace_floor_divide, ! slot_nb_inplace_floor_divide); NBSLOT("__itruediv__", nb_inplace_true_divide, ! slot_nb_inplace_true_divide); ! if (dict == NULL || ! PyDict_GetItemString(dict, "__str__") || ! PyDict_GetItemString(dict, "__repr__")) ! type->tp_print = NULL; ! TPSLOT("__cmp__", tp_compare, _PyObject_SlotCompare); ! TPSLOT("__repr__", tp_repr, slot_tp_repr); ! TPSLOT("__hash__", tp_hash, slot_tp_hash); ! TPSLOT("__call__", tp_call, slot_tp_call); ! TPSLOT("__str__", tp_str, slot_tp_str); ! TPSLOT("__getattribute__", tp_getattro, slot_tp_getattro); ! TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook); ! TPSLOT("__setattr__", tp_setattro, slot_tp_setattro); ! TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare); ! TPSLOT("__le__", tp_richcompare, slot_tp_richcompare); ! TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare); ! TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare); ! TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare); ! TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare); ! TPSLOT("__iter__", tp_iter, slot_tp_iter); ! TPSLOT("next", tp_iternext, slot_tp_iternext); ! TPSLOT("__get__", tp_descr_get, slot_tp_descr_get); ! TPSLOT("__set__", tp_descr_set, slot_tp_descr_set); ! TPSLOT("__init__", tp_init, slot_tp_init); ! TPSLOT("__new__", tp_new, slot_tp_new); } --- 3667,3930 ---- } ! /* Table mapping __foo__ names to tp_foo offsets and slot_tp_foo wrapper ! functions. The offsets here are relative to the 'etype' structure, which ! incorporates the additional structures used for numbers, sequences and ! mappings. Note that multiple names may map to the same slot (e.g. __eq__, ! __ne__ etc. all map to tp_richcompare) and one name may map to multiple ! slots (e.g. __str__ affects tp_str as well as tp_repr). */ ! typedef struct { ! char *name; ! int offset; ! void *function; ! wrapperfunc wrapper; ! } slotdef; ! #undef TPSLOT ! #undef ETSLOT ! #undef SQSLOT ! #undef MPSLOT ! #undef NBSLOT ! #undef BINSLOT ! #undef RBINSLOT ! #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ! {NAME, offsetof(PyTypeObject, SLOT), FUNCTION, WRAPPER} ! #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ! {NAME, offsetof(etype, SLOT), FUNCTION, WRAPPER} ! #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ! ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER) ! #define MPSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ! ETSLOT(NAME, as_mapping.SLOT, FUNCTION, WRAPPER) ! #define NBSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ! ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER) ! #define BINSLOT(NAME, SLOT, FUNCTION) \ ! ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l) ! #define RBINSLOT(NAME, SLOT, FUNCTION) \ ! ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r) ! static slotdef slotdefs[] = { ! SQSLOT("__len__", sq_length, slot_sq_length, wrap_inquiry), ! SQSLOT("__add__", sq_concat, slot_sq_concat, wrap_binaryfunc), ! SQSLOT("__mul__", sq_repeat, slot_sq_repeat, wrap_intargfunc), ! SQSLOT("__rmul__", sq_repeat, slot_sq_repeat, wrap_intargfunc), ! SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item), ! SQSLOT("__getslice__", sq_slice, slot_sq_slice, wrap_intintargfunc), ! SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem), ! SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem), ! SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice, ! wrap_intintobjargproc), ! SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice, wrap_delslice), ! SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc), ! SQSLOT("__iadd__", sq_inplace_concat, slot_sq_inplace_concat, ! wrap_binaryfunc), ! SQSLOT("__imul__", sq_inplace_repeat, slot_sq_inplace_repeat, ! wrap_intargfunc), ! MPSLOT("__len__", mp_length, slot_mp_length, wrap_inquiry), ! MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, wrap_sq_item), ! MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript, ! wrap_objobjargproc), ! MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript, ! wrap_delitem), ! BINSLOT("__add__", nb_add, slot_nb_add), ! RBINSLOT("__radd__", nb_add, slot_nb_add), ! BINSLOT("__sub__", nb_subtract, slot_nb_subtract), ! RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract), ! BINSLOT("__mul__", nb_multiply, slot_nb_multiply), ! RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply), ! BINSLOT("__div__", nb_divide, slot_nb_divide), ! RBINSLOT("__rdiv__", nb_divide, slot_nb_divide), ! BINSLOT("__mod__", nb_remainder, slot_nb_remainder), ! RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder), ! BINSLOT("__divmod__", nb_divmod, slot_nb_divmod), ! RBINSLOT("__rdivmod__", nb_divmod, slot_nb_divmod), ! NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc), ! NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r), ! NBSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc), ! NBSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc), ! NBSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc), ! NBSLOT("__nonzero__", nb_nonzero, slot_nb_nonzero, wrap_unaryfunc), ! NBSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc), ! BINSLOT("__lshift__", nb_lshift, slot_nb_lshift), ! RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift), ! BINSLOT("__rshift__", nb_rshift, slot_nb_rshift), ! RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift), ! BINSLOT("__and__", nb_and, slot_nb_and), ! RBINSLOT("__rand__", nb_and, slot_nb_and), ! BINSLOT("__xor__", nb_xor, slot_nb_xor), ! RBINSLOT("__rxor__", nb_xor, slot_nb_xor), ! BINSLOT("__or__", nb_or, slot_nb_or), ! RBINSLOT("__ror__", nb_or, slot_nb_or), ! NBSLOT("__coerce__", nb_coerce, slot_nb_coerce, wrap_coercefunc), ! NBSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc), ! NBSLOT("__long__", nb_long, slot_nb_long, wrap_unaryfunc), ! NBSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc), ! NBSLOT("__oct__", nb_oct, slot_nb_oct, wrap_unaryfunc), ! NBSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc), ! NBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, ! wrap_binaryfunc), ! NBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract, ! wrap_binaryfunc), ! NBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply, ! wrap_binaryfunc), ! NBSLOT("__idiv__", nb_inplace_divide, slot_nb_inplace_divide, ! wrap_binaryfunc), ! NBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder, ! wrap_binaryfunc), ! NBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power, ! wrap_ternaryfunc), ! NBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift, ! wrap_binaryfunc), ! NBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift, ! wrap_binaryfunc), ! NBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and, ! wrap_binaryfunc), ! NBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor, ! wrap_binaryfunc), ! NBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or, ! wrap_binaryfunc), ! BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide), ! RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide), ! BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide), ! RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide), NBSLOT("__ifloordiv__", nb_inplace_floor_divide, ! slot_nb_inplace_floor_divide, wrap_binaryfunc), NBSLOT("__itruediv__", nb_inplace_true_divide, ! slot_nb_inplace_true_divide, wrap_binaryfunc), ! TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc), ! TPSLOT("__str__", tp_print, NULL, NULL), ! TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc), ! TPSLOT("__repr__", tp_print, NULL, NULL), ! TPSLOT("__cmp__", tp_compare, _PyObject_SlotCompare, wrap_cmpfunc), ! TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc), ! TPSLOT("__call__", tp_call, slot_tp_call, wrap_call), ! TPSLOT("__getattribute__", tp_getattro, slot_tp_getattro, ! wrap_binaryfunc), ! TPSLOT("__getattribute__", tp_getattr, NULL, NULL), ! TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL), ! TPSLOT("__getattr__", tp_getattr, NULL, NULL), ! TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr), ! TPSLOT("__setattr__", tp_setattr, NULL, NULL), ! TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr), ! TPSLOT("__delattr__", tp_setattr, NULL, NULL), ! TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt), ! TPSLOT("__le__", tp_richcompare, slot_tp_richcompare, richcmp_le), ! TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq), ! TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne), ! TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt), ! TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge), ! TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc), ! TPSLOT("next", tp_iternext, slot_tp_iternext, wrap_next), ! TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get), ! TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set), ! TPSLOT("__init__", tp_init, slot_tp_init, wrap_init), ! TPSLOT("__new__", tp_new, slot_tp_new, NULL), ! {NULL} ! }; ! static int ! update_slot(PyTypeObject *type, PyObject *name, PyObject *value) ! { ! char *s; ! int n; ! slotdef *p; ! void **ptr; ! ! assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE); ! if (value == NULL) ! return 0; /* Can't unset a slot */ ! s = PyString_AsString(name); ! n = PyString_Size(name); ! if (s == NULL || n < 0) { ! /* Shouldn't happen, but can't be bothered */ ! PyErr_Clear(); ! return 0; ! } ! if (!(s[0] == '_' && s[1] == '_' && s[n-1] == '_' && s[n-2] == '_')) ! return 0; ! for (p = slotdefs; p->name; p++) { ! if (!strcmp(p->name, s)) { ! ptr = (void **) ((char *)type + p->offset); ! *ptr = p->function; ! } ! } ! return 0; ! } ! ! static void ** ! slotptr(PyTypeObject *type, int offset) ! { ! char *ptr; ! ! assert(offset >= 0); ! assert(offset < offsetof(etype, as_buffer)); ! if (offset >= offsetof(etype, as_mapping)) { ! ptr = (void *)type->tp_as_mapping; ! offset -= offsetof(etype, as_mapping); ! } ! else if (offset >= offsetof(etype, as_sequence)) { ! ptr = (void *)type->tp_as_sequence; ! offset -= offsetof(etype, as_sequence); ! } ! else if (offset >= offsetof(etype, as_number)) { ! ptr = (void *)type->tp_as_number; ! offset -= offsetof(etype, as_number); ! } ! else { ! ptr = (void *)type; ! } ! if (ptr != NULL) ! ptr += offset; ! return (void **)ptr; ! } ! ! static void ! fixup_slot_dispatchers(PyTypeObject *type) ! { ! slotdef *p; ! PyObject *mro, *descr; ! PyTypeObject *base; ! PyWrapperDescrObject *d; ! int i, n; ! void **ptr; ! ! for (p = slotdefs; p->name; p++) { ! ptr = slotptr(type, p->offset); ! if (ptr) ! *ptr = NULL; ! } ! mro = type->tp_mro; ! assert(PyTuple_Check(mro)); ! n = PyTuple_GET_SIZE(mro); ! for (p = slotdefs; p->name; p++) { ! for (i = 0; i < n; i++) { ! base = (PyTypeObject *)PyTuple_GET_ITEM(mro, i); ! assert(PyType_Check(base)); ! descr = PyDict_GetItemString( ! base->tp_defined, p->name); ! if (descr == NULL) ! continue; ! ptr = slotptr(type, p->offset); ! if (ptr == NULL) ! continue; ! if (descr->ob_type == &PyWrapperDescr_Type) { ! d = (PyWrapperDescrObject *)descr; ! if (d->d_base->wrapper == p->wrapper) { ! if (*ptr == NULL) { ! *ptr = d->d_wrapped; ! continue; ! } ! if (p->wrapper == wrap_binaryfunc_r) ! continue; ! } ! } ! *ptr = p->function; ! break; ! } ! } } From bwarsaw@users.sourceforge.net Tue Oct 9 20:41:20 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 09 Oct 2001 12:41:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email MIMEAudio.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv12097 Added Files: MIMEAudio.py Log Message: An audio/* class, like MIMEImage, contributed by Anthony Baxter. Rewritten for style and the email package naming conventions by Barry. --- NEW FILE: MIMEAudio.py --- # Author: Anthony Baxter """Class representing audio/* type MIME documents. """ import sndhdr from cStringIO import StringIO import MIMEBase import Errors import Encoders _sndhdr_MIMEmap = {'au' : 'basic', 'wav' :'x-wav', 'aiff':'x-aiff', 'aifc':'x-aiff', } # There are others in sndhdr that don't have MIME types. :( # Additional ones to be added to sndhdr? midi, mp3, realaudio, wma?? def _whatsnd(data): """Try to identify a sound file type. sndhdr.what() has a pretty cruddy interface, unfortunately. This is why we re-do it here. It would be easier to reverse engineer the Unix 'file' command and use the standard 'magic' file, as shipped with a modern Unix. """ hdr = data[:512] fakefile = StringIO(hdr) for testfn in sndhdr.tests: res = testfn(hdr, fakefile) if res is not None: return _sndhdr_MIMEmap.get(res[0]) return None class MIMEAudio(MIMEBase.MIMEBase): """Class for generating audio/* MIME documents.""" def __init__(self, _audiodata, _subtype=None, _encoder=Encoders.encode_base64, **_params): """Create an audio/* type MIME document. _audiodata is a string containing the raw audio data. If this data can be decoded by the standard Python `sndhdr' module, then the subtype will be automatically included in the Content-TYpe: header. Otherwise, you can specify the specific audio subtype via the _subtype parameter. If _subtype is not given, and no subtype can be guessed, a TypeError is raised. _encoder is a function which will perform the actual encoding for transport of the image data. It takes one argument, which is this Image instance. It should use get_payload() and set_payload() to change the payload to the encoded form. It should also add any Content-Transfer-Encoding: or other headers to the message as necessary. The default encoding is Base64. Any additional keyword arguments are passed to the base class constructor, which turns them into parameters on the Content-Type: header. """ if _subtype is None: _subtype = _whatsnd(_audiodata) if _subtype is None: raise TypeError, 'Could not find audio MIME subtype' MIMEBase.MIMEBase.__init__(self, 'audio', _subtype, **_params) self.set_payload(_audiodata) _encoder(self) From gvanrossum@users.sourceforge.net Tue Oct 9 21:17:59 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 09 Oct 2001 13:17:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.97,2.98 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv21807 Modified Files: typeobject.c Log Message: The slot definition table entry for mp_getitem had a bogus wrapper function, which caused test_minidom to fail. Fixed this. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.97 retrieving revision 2.98 diff -C2 -d -r2.97 -r2.98 *** typeobject.c 2001/10/09 19:39:46 2.97 --- typeobject.c 2001/10/09 20:17:57 2.98 *************** *** 3724,3728 **** MPSLOT("__len__", mp_length, slot_mp_length, wrap_inquiry), ! MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, wrap_sq_item), MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript, wrap_objobjargproc), --- 3724,3729 ---- MPSLOT("__len__", mp_length, slot_mp_length, wrap_inquiry), ! MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, ! wrap_binaryfunc), MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript, wrap_objobjargproc), From gvanrossum@users.sourceforge.net Tue Oct 9 21:36:46 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 09 Oct 2001 13:36:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.85,1.86 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv26829 Modified Files: test_descr.py Log Message: Add a bunch of tests for a list subclass that would have caught the previous embarrassment (typeobject.c checking crashing minidom). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.85 retrieving revision 1.86 diff -C2 -d -r1.85 -r1.86 *** test_descr.py 2001/10/09 11:07:24 1.85 --- test_descr.py 2001/10/09 20:36:44 1.86 *************** *** 1767,1770 **** --- 1767,1792 ---- vereq(u[0:0], u"") + class sublist(list): + pass + a = sublist(range(5)) + vereq(a, range(5)) + a.append("hello") + vereq(a, range(5) + ["hello"]) + a[5] = 5 + vereq(a, range(6)) + a.extend(range(6, 20)) + vereq(a, range(20)) + a[-5:] = [] + vereq(a, range(15)) + del a[10:15] + vereq(len(a), 10) + vereq(a, range(10)) + vereq(list(a), range(10)) + vereq(a[0], 0) + vereq(a[9], 9) + vereq(a[-10], 0) + vereq(a[-1], 9) + vereq(a[:5], range(5)) + class CountedInput(file): """Counts lines read by self.readline(). From tim_one@users.sourceforge.net Tue Oct 9 21:51:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 09 Oct 2001 13:51:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.273,1.274 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv29499/python/Misc Modified Files: NEWS Log Message: Allow the profiler's calibration constant to be specified in the constructor call, or via setting an instance or class vrbl. Rewrote the calibration docs. Modern boxes are so friggin' fast, and a profiler event does so much work anyway, that the cost of looking up an instance vrbl (the bias constant) per profile event just isn't a big deal. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.273 retrieving revision 1.274 diff -C2 -d -r1.273 -r1.274 *** NEWS 2001/10/09 05:31:56 1.273 --- NEWS 2001/10/09 20:51:19 1.274 *************** *** 49,54 **** - Profile.calibrate() has a new implementation that should deliver ! a better system-specific calibration constant. Calibration must still ! be done manually (see the docs for the profile module). - quopri's encode and decode methods take an optional header parameter, --- 49,63 ---- - Profile.calibrate() has a new implementation that should deliver ! a much better system-specific calibration constant. The constant can ! now be specified in an instance constructor, or as a Profile class or ! instance variable, instead of by editing profile.py's source code. ! Calibration must still be done manually (see the docs for the profile ! module). ! ! Note that Profile.calibrate() must be overriden by subclasses. ! Improving the accuracy required exploiting detailed knowledge of ! profiler internals; the earlier method abstracted away the details ! and measured a simplified model instead, but consequently computed ! a constant too small by a factor of 2 on some modern machines. - quopri's encode and decode methods take an optional header parameter, From tim_one@users.sourceforge.net Tue Oct 9 21:51:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 09 Oct 2001 13:51:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libprofile.tex,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv29499/python/Doc/lib Modified Files: libprofile.tex Log Message: Allow the profiler's calibration constant to be specified in the constructor call, or via setting an instance or class vrbl. Rewrote the calibration docs. Modern boxes are so friggin' fast, and a profiler event does so much work anyway, that the cost of looking up an instance vrbl (the bias constant) per profile event just isn't a big deal. Index: libprofile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libprofile.tex,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** libprofile.tex 2001/10/07 03:12:08 1.37 --- libprofile.tex 2001/10/09 20:51:19 1.38 *************** *** 554,561 **** \section{Calibration \label{profile-calibration}} ! The profiler class has a hard coded constant that is added to each event handling time to compensate for the overhead of calling the time ! function, and socking away the results. The following procedure can ! be used to obtain this constant for a given platform (see discussion in section Limitations above). --- 554,562 ---- \section{Calibration \label{profile-calibration}} ! The profiler subtracts a constant from each event handling time to compensate for the overhead of calling the time ! function, and socking away the results. By default, the constant is 0. ! The following procedure can ! be used to obtain a better constant for a given platform (see discussion in section Limitations above). *************** *** 563,626 **** import profile pr = profile.Profile() ! print pr.calibrate(100) ! print pr.calibrate(100) ! print pr.calibrate(100) ! \end{verbatim} ! ! The argument to \method{calibrate()} is the number of times to try to ! do the sample calls to get the CPU times. If your computer is ! \emph{very} fast, you might have to do: ! ! \begin{verbatim} ! pr.calibrate(1000) \end{verbatim} ! or even: ! ! \begin{verbatim} ! pr.calibrate(10000) ! \end{verbatim} The object of this exercise is to get a fairly consistent result. ! When you have a consistent answer, you are ready to use that number in ! the source code. For a Sun Sparcstation 1000 running Solaris 2.3, the ! magical number is about .00053. If you have a choice, you are better ! off with a smaller constant, and your results will ``less often'' show ! up as negative in profile statistics. ! The following shows how the trace_dispatch() method in the Profile ! class should be modified to install the calibration constant on a Sun ! Sparcstation 1000: \begin{verbatim} ! def trace_dispatch(self, frame, event, arg): ! t = self.timer() ! t = t[0] + t[1] - self.t - .00053 # Calibration constant ! if self.dispatch[event](frame,t): ! t = self.timer() ! self.t = t[0] + t[1] ! else: ! r = self.timer() ! self.t = r[0] + r[1] - t # put back unrecorded delta ! return ! \end{verbatim} ! Note that if there is no calibration constant, then the line ! containing the callibration constant should simply say: ! \begin{verbatim} ! t = t[0] + t[1] - self.t # no calibration constant \end{verbatim} ! You can also achieve the same results using a derived class (and the ! profiler will actually run equally fast!!), but the above method is ! the simplest to use. I could have made the profiler ``self ! calibrating,'' but it would have made the initialization of the ! profiler class slower, and would have required some \emph{very} fancy ! coding, or else the use of a variable where the constant \samp{.00053} ! was placed in the code shown. This is a \strong{VERY} critical ! performance section, and there is no reason to use a variable lookup ! at this point, when a constant can be used. --- 564,606 ---- import profile pr = profile.Profile() ! for i in range(5): ! print pr.calibrate(10000) \end{verbatim} ! The method executes the number of Python calls given by the argument, ! directly and again under the profiler, measuring the time for both. ! It then computes the hidden overhead per profiler event, and returns ! that as a float. For example, on an 800 MHz Pentium running ! Windows 2000, and using Python's time.clock() as the timer, ! the magical number is about 12.5e-6. The object of this exercise is to get a fairly consistent result. ! If your computer is \emph{very} fast, or your timer function has poor ! resolution, you might have to pass 100000, or even 1000000, to get ! consistent results. ! When you have a consistent answer, ! there are three ways you can use it:\footnote{Prior to Python 2.2, it ! was necessary to edit the profiler source code to embed the bias as ! a literal number. You still can, but that method is no longer ! described, because no longer needed.} \begin{verbatim} ! import profile ! # 1. Apply computed bias to all Profile instances created hereafter. ! profile.Profile.bias = ! # 2. Apply computed bias to a specific Profile instance. ! pr = profile.Profile() ! pr.bias = your_computed_bias ! # 3. Specify computed bias in instance constructor. ! pr = profile.Profile(bias=your_computed_bias) \end{verbatim} ! If you have a choice, you are better off choosing a smaller constant, and ! then your results will ``less often'' show up as negative in profile ! statistics. From tim_one@users.sourceforge.net Tue Oct 9 21:51:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 09 Oct 2001 13:51:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv29499/python/Lib Modified Files: profile.py Log Message: Allow the profiler's calibration constant to be specified in the constructor call, or via setting an instance or class vrbl. Rewrote the calibration docs. Modern boxes are so friggin' fast, and a profiler event does so much work anyway, that the cost of looking up an instance vrbl (the bias constant) per profile event just isn't a big deal. Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** profile.py 2001/10/09 05:31:56 1.40 --- profile.py 2001/10/09 20:51:19 1.41 *************** *** 140,148 **** """ ! def __init__(self, timer=None): self.timings = {} self.cur = None self.cmd = "" if not timer: if os.name == 'mac': --- 140,154 ---- """ ! bias = 0 # calibration constant ! ! def __init__(self, timer=None, bias=None): self.timings = {} self.cur = None self.cmd = "" + if bias is None: + bias = self.bias + self.bias = bias # Materialize in local dict for lookup speed. + if not timer: if os.name == 'mac': *************** *** 191,195 **** timer = self.timer t = timer() ! t = t[0] + t[1] - self.t # - .00053 calibration constant if self.dispatch[event](self, frame,t): --- 197,201 ---- timer = self.timer t = timer() ! t = t[0] + t[1] - self.t - self.bias if self.dispatch[event](self, frame,t): *************** *** 199,204 **** r = timer() self.t = r[0] + r[1] - t # put back unrecorded delta - return - # Dispatch routine for best timer program (return = scalar, fastest if --- 205,208 ---- *************** *** 207,216 **** def trace_dispatch_i(self, frame, event, arg): timer = self.timer ! t = timer() - self.t # - 16e-6 # calibration constant if self.dispatch[event](self, frame,t): self.t = timer() else: self.t = timer() - t # put back unrecorded delta - return # Dispatch routine for macintosh (timer returns time in ticks of --- 211,219 ---- def trace_dispatch_i(self, frame, event, arg): timer = self.timer ! t = timer() - self.t - self.bias if self.dispatch[event](self, frame,t): self.t = timer() else: self.t = timer() - t # put back unrecorded delta # Dispatch routine for macintosh (timer returns time in ticks of *************** *** 219,229 **** def trace_dispatch_mac(self, frame, event, arg): timer = self.timer ! t = timer()/60.0 - self.t # - 1 # calibration constant ! if self.dispatch[event](self, frame,t): self.t = timer()/60.0 else: self.t = timer()/60.0 - t # put back unrecorded delta - return - # SLOW generic dispatch routine for timer returning lists of numbers --- 222,230 ---- def trace_dispatch_mac(self, frame, event, arg): timer = self.timer ! t = timer()/60.0 - self.t - self.bias ! if self.dispatch[event](self, frame, t): self.t = timer()/60.0 else: self.t = timer()/60.0 - t # put back unrecorded delta # SLOW generic dispatch routine for timer returning lists of numbers *************** *** 231,241 **** def trace_dispatch_l(self, frame, event, arg): get_time = self.get_time ! t = get_time() - self.t ! if self.dispatch[event](self, frame,t): self.t = get_time() else: self.t = get_time() - t # put back unrecorded delta - return # In the event handlers, the first 3 elements of self.cur are unpacked --- 232,241 ---- def trace_dispatch_l(self, frame, event, arg): get_time = self.get_time ! t = get_time() - self.t - self.bias ! if self.dispatch[event](self, frame, t): self.t = get_time() else: self.t = get_time() - t # put back unrecorded delta # In the event handlers, the first 3 elements of self.cur are unpacked *************** *** 431,437 **** # re-starts the stopwatch before the user's code really gets to # continue. The following code tries to measure the difference on ! # a per-event basis. The result can the be placed in the ! # Profile.dispatch_event() routine for the given platform. Note ! # that this difference is only significant if there are a lot of # events, and relatively little user code per event. For example, # code with small functions will typically benefit from having the --- 431,437 ---- # re-starts the stopwatch before the user's code really gets to # continue. The following code tries to measure the difference on ! # a per-event basis. ! # ! # Note that this difference is only significant if there are a lot of # events, and relatively little user code per event. For example, # code with small functions will typically benefit from having the *************** *** 462,471 **** # event/time ratio (i.e., the profiler would run slower, fur a very # low "value added" feature.) - # - # Plugging in the calibration constant doesn't slow down the - # profiler very much, and the accuracy goes way up. #************************************************************** def calibrate(self, m, verbose=0): get_time = self.get_time --- 462,479 ---- # event/time ratio (i.e., the profiler would run slower, fur a very # low "value added" feature.) #************************************************************** def calibrate(self, m, verbose=0): + if self.__class__ is not Profile: + raise TypeError("Subclasses must override .calibrate().") + + saved_bias = self.bias + self.bias = 0 + try: + return self._callibrate_inner(m, verbose) + finally: + self.bias = saved_bias + + def _callibrate_inner(self, m, verbose): get_time = self.get_time From fdrake@users.sourceforge.net Tue Oct 9 21:53:50 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 09 Oct 2001 13:53:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pprint.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv32030/Lib Modified Files: pprint.py Log Message: Remove obsolete email address. Index: pprint.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pprint.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** pprint.py 2001/09/04 19:43:26 1.15 --- pprint.py 2001/10/09 20:53:48 1.16 *************** *** 1,4 **** # Author: Fred L. Drake, Jr. ! # fdrake@cnri.reston.va.us, fdrake@acm.org # # This is a simple little module I wrote to make life easier. I didn't --- 1,4 ---- # Author: Fred L. Drake, Jr. ! # fdrake@acm.org # # This is a simple little module I wrote to make life easier. I didn't From tim_one@users.sourceforge.net Tue Oct 9 21:54:25 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 09 Oct 2001 13:54:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libprofile.tex,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv32171/python/Doc/lib Modified Files: libprofile.tex Log Message: A copy-and-paste job forget the "paste" half. Index: libprofile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libprofile.tex,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** libprofile.tex 2001/10/09 20:51:19 1.38 --- libprofile.tex 2001/10/09 20:54:23 1.39 *************** *** 590,594 **** # 1. Apply computed bias to all Profile instances created hereafter. ! profile.Profile.bias = # 2. Apply computed bias to a specific Profile instance. --- 590,594 ---- # 1. Apply computed bias to all Profile instances created hereafter. ! profile.Profile.bias = your_computed_bias # 2. Apply computed bias to a specific Profile instance. From tim_one@users.sourceforge.net Tue Oct 9 22:01:33 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 09 Oct 2001 14:01:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv2464/python/Lib Modified Files: profile.py Log Message: Repair key stutter + auto-complete ugliness. Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** profile.py 2001/10/09 20:51:19 1.41 --- profile.py 2001/10/09 21:01:31 1.42 *************** *** 471,479 **** self.bias = 0 try: ! return self._callibrate_inner(m, verbose) finally: self.bias = saved_bias ! def _callibrate_inner(self, m, verbose): get_time = self.get_time --- 471,479 ---- self.bias = 0 try: ! return self._calibrate_inner(m, verbose) finally: self.bias = saved_bias ! def _calibrate_inner(self, m, verbose): get_time = self.get_time From akuchling@users.sourceforge.net Tue Oct 9 22:13:10 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Tue, 09 Oct 2001 14:13:10 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0247.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv5139 Modified Files: pep-0247.txt Log Message: Set digest_size to None for variable-size hashes Index: pep-0247.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0247.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pep-0247.txt 2001/09/24 15:37:19 1.6 --- pep-0247.txt 2001/10/09 21:13:07 1.7 *************** *** 55,59 **** and accessing its 'digest_size' attribute, but it can be convenient to have this value available from the module. ! Hashes with a variable output size will set this variable to 0. Hashing objects require a single attribute: --- 55,60 ---- and accessing its 'digest_size' attribute, but it can be convenient to have this value available from the module. ! Hashes with a variable output size will set this variable to ! None. Hashing objects require a single attribute: *************** *** 66,70 **** output size, this output size must be chosen when the hashing object is created, and this attribute must contain the ! selected size. Therefore 0 is *not* a legal value for this attribute. --- 67,71 ---- output size, this output size must be chosen when the hashing object is created, and this attribute must contain the ! selected size. Therefore None is *not* a legal value for this attribute. *************** *** 120,130 **** to objects; added .hexdigest() method. 2001-09-20: Removed reset() method completely. Acknowledgements ! Thanks to Andrew Archibald, Rich Salz, Itamar Shtull-Trauring, and ! the readers of the python-crypto list for their comments on this ! PEP. --- 121,132 ---- to objects; added .hexdigest() method. 2001-09-20: Removed reset() method completely. + 2001-09-28: Set digest_size to None for variable-size hashes. Acknowledgements ! Thanks to Aahz, Andrew Archibald, Rich Salz, Itamar ! Shtull-Trauring, and the readers of the python-crypto list for ! their comments on this PEP. From tim_one@users.sourceforge.net Tue Oct 9 23:22:39 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 09 Oct 2001 15:22:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild python20.wse,1.92,1.93 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv26042/python/PCbuild Modified Files: python20.wse Log Message: If all of Python, IDLE and Tcl/Tk are being installed, and the user has not disabled file-extension registration, arrange for .py and .pyw files to have an "Edit with IDLE" context (right-click) menu entry, selecting which executes IDLE w/ the -e switch followed by the selected file's path. Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.92 retrieving revision 1.93 diff -C2 -d -r1.92 -r1.93 *** python20.wse 2001/09/28 21:53:42 1.92 --- python20.wse 2001/10/09 22:22:36 1.93 *************** *** 2506,2509 **** --- 2506,2551 ---- item: End Block end + item: Remark + end + item: Remark + Text=If we're installing IDLE, also set an Edit context menu action to use IDLE, for .py and .pyw files. + end + item: If/While Statement + Variable=COMPONENTS + Value=B + Flags=00000010 + end + item: If/While Statement + Variable=USE_HKCR + Value=1 + end + item: Edit Registry + Total Keys=1 + Key=Python.NoConFile\shell\Edit with IDLE\command + New Value=%MAINDIR%\pythonw.exe %MAINDIR%\Tools\idle\idle.pyw -e "%%1" + end + item: Edit Registry + Total Keys=1 + Key=Python.File\shell\Edit with IDLE\command + New Value=%MAINDIR%\pythonw.exe %MAINDIR%\Tools\idle\idle.pyw -e "%%1" + end + item: Else Statement + end + item: Edit Registry + Total Keys=1 + Key=Software\CLASSES\Python.NoConFile\shell\Edit with IDLE\command + New Value=%MAINDIR%\pythonw.exe %MAINDIR%\Tools\idle\idle.pyw -e "%%1" + Root=1 + end + item: Edit Registry + Total Keys=1 + Key=Software\CLASSES\Python.File\shell\Edit with IDLE\command + New Value=%MAINDIR%\pythonw.exe %MAINDIR%\Tools\idle\idle.pyw -e "%%1" + Root=1 + end + item: End Block + end + item: End Block + end item: End Block end From tim_one@users.sourceforge.net Tue Oct 9 23:39:43 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 09 Oct 2001 15:39:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.274,1.275 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv31784/python/Misc Modified Files: NEWS Log Message: Add item about new "Edit with IDLE" menu entry created by Windows installer. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.274 retrieving revision 1.275 diff -C2 -d -r1.274 -r1.275 *** NEWS 2001/10/09 20:51:19 1.274 --- NEWS 2001/10/09 22:39:40 1.275 *************** *** 84,87 **** --- 84,91 ---- Windows + - Installer: If you install IDLE, and don't disable file-extension + registration, a new "Edit with IDLE" context (right-click) menu entry + is created for .py and .pyw files. + - The signal module now supports SIGBREAK on Windows, thanks to Steven Scott. Note that SIGBREAK is unique to Windows. The default SIGBREAK From jackjansen@users.sourceforge.net Wed Oct 10 00:08:46 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 09 Oct 2001 16:08:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Demo/embed demo.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/embed In directory usw-pr-cvs1:/tmp/cvs-serv7254/Python/Mac/Demo/embed Modified Files: demo.c Log Message: Fixed the embedding demo to correctly show the use of overriding the console writer. Index: demo.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/embed/demo.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** demo.c 2001/10/08 15:32:17 1.2 --- demo.c 2001/10/09 23:08:44 1.3 *************** *** 2,34 **** #include "Python.h" - #ifdef macintosh #include "macglue.h" - #endif /* macintosh */ static char *argv0; main(argc, argv) int argc; char **argv; { - #ifdef macintosh /* So the user can set argc/argv to something interesting */ argc = ccommand(&argv); - #endif /* Save a copy of argv0 */ argv0 = argv[0]; - /* Initialize the Python interpreter. Required. */ - #ifdef macintosh /* If the first option is "-q" we don't open a console */ if ( argc > 1 && strcmp(argv[1], "-q") == 0 ) { PyMac_SetConsoleHandler(PyMac_DummyReadHandler, PyMac_DummyWriteHandler, PyMac_DummyWriteHandler); ! /* freopen("demo output", "w", stdout); */ ! } PyMac_Initialize(); - #else - Py_Initialize(); - #endif /* Define sys.argv. It is up to the application if you --- 2,42 ---- #include "Python.h" #include "macglue.h" static char *argv0; + long my_writehandler(char *buf, long count) + { + long mycount; + unsigned char mybuf[255]; + + mycount = count; + if (mycount > 255 ) mycount = 255; + mybuf[0] = (unsigned char)mycount; + strncpy((char *)mybuf+1, buf, mycount); + DebugStr(mybuf); + return count; + } + main(argc, argv) int argc; char **argv; { /* So the user can set argc/argv to something interesting */ argc = ccommand(&argv); /* Save a copy of argv0 */ argv0 = argv[0]; /* If the first option is "-q" we don't open a console */ if ( argc > 1 && strcmp(argv[1], "-q") == 0 ) { PyMac_SetConsoleHandler(PyMac_DummyReadHandler, PyMac_DummyWriteHandler, PyMac_DummyWriteHandler); ! } else ! if ( argc > 1 && strcmp(argv[1], "-d") == 0 ) { ! PyMac_SetConsoleHandler(PyMac_DummyReadHandler, my_writehandler, ! my_writehandler); ! } ! /* Initialize the Python interpreter. Required. */ PyMac_Initialize(); /* Define sys.argv. It is up to the application if you From jackjansen@users.sourceforge.net Wed Oct 10 00:09:02 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 09 Oct 2001 16:09:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Demo/embed embeddemo.prj,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo/embed In directory usw-pr-cvs1:/tmp/cvs-serv7318/Python/Mac/Demo/embed Modified Files: embeddemo.prj Log Message: Fixed the embedding demo to correctly show the use of overriding the console writer. Index: embeddemo.prj =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/embed/embeddemo.prj,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 Binary files /tmp/cvs6ziJ51 and /tmp/cvswrBuYV differ From jackjansen@users.sourceforge.net Wed Oct 10 00:14:08 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 09 Oct 2001 16:14:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Demo embed.html,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo In directory usw-pr-cvs1:/tmp/cvs-serv8651/Python/Mac/Demo Modified Files: embed.html Log Message: Updated, and added a very terse description of PyMac_SetConsoleHandler(). Index: embed.html =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/embed.html,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** embed.html 2000/09/10 12:02:16 1.5 --- embed.html 2001/10/09 23:14:06 1.6 *************** *** 7,13 ****
Note: if you have a binary-only release of MacPython you will not ! have this demo installed. Install the developer option (in the standard installer) or go to ! Jack's MacPython Page ! to download either a source release if you want to embed Python in other applications.

--- 7,12 ----


Note: if you have a binary-only release of MacPython you will not ! have this demo installed. Install the developer option (in the standard installer) or ! a source release if you want to embed Python in other applications.

*************** *** 24,29 **** it so should your program and vice versa. !

  • The console-behaviour (close-on-exit, etc) is controlled by Python, ! but you are of course free to change that after calling PyMac_Initialize(). --- 23,28 ---- it so should your program and vice versa. !
  • The console-behaviour (close-on-exit, etc) is controlled by Python ! but you can overwrite this with PyMac_SetConsoleHandler(). *************** *** 38,46 **** found in the embed folder.

    ! Note: you may think that you do not have the project file ! PythonCore but actually you do: the standard installation ! process deposits it in the Extensions folder in the system ! folder under the name PythonCore version. Add that file ! to the project replacing PythonCore.

    --- 37,44 ---- found in the embed folder.

    ! This example code also shows how to override the console: if you pass the ! -q argument in the argument box output is thrown away. If you ! pass the -d option the output is sent to DebugStr ! (so be sure to use this only when running the example under a debugger). From jhylton@users.sourceforge.net Wed Oct 10 02:45:04 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 09 Oct 2001 18:45:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_grammar.py,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20923 Modified Files: test_grammar.py Log Message: SF patch [ #468662 ] Allow jython to complete test_grammar The behavior of co_varnames in the presence of nested argument tuples is not consistent across Python and Jython. Test each platform separately. Index: test_grammar.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_grammar.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** test_grammar.py 2001/09/26 12:43:38 1.38 --- test_grammar.py 2001/10/10 01:45:02 1.39 *************** *** 3,6 **** --- 3,7 ---- from test_support import * + import sys print '1. Parser' *************** *** 150,156 **** verify(f2.func_code.co_varnames == ('one_argument',)) verify(f3.func_code.co_varnames == ('two', 'arguments')) ! verify(f4.func_code.co_varnames == ('two', '.2', 'compound', 'argument', ! 'list')) ! verify(f5.func_code.co_varnames == ('.0', 'two', 'compound', 'first')) def a1(one_arg,): pass def a2(two, args,): pass --- 151,163 ---- verify(f2.func_code.co_varnames == ('one_argument',)) verify(f3.func_code.co_varnames == ('two', 'arguments')) ! if sys.platform.startswith('java'): ! verify(f4.func_code.co_varnames == ! ('two', '(compound, (argument, list))',)) ! verify(f5.func_code.co_varnames == ! ('(compound, first)', 'two', 'compound', 'first')) ! else: ! verify(f4.func_code.co_varnames == ('two', '.2', 'compound', ! 'argument', 'list')) ! verify(f5.func_code.co_varnames == ('.0', 'two', 'compound', 'first')) def a1(one_arg,): pass def a2(two, args,): pass *************** *** 159,163 **** def v2(a, b, *rest): pass def v3(a, (b, c), *rest): return a, b, c, rest ! verify(v3.func_code.co_varnames == ('a', '.2', 'rest', 'b', 'c')) verify(v3(1, (2, 3), 4) == (1, 2, 3, (4,))) def d01(a=1): pass --- 166,173 ---- def v2(a, b, *rest): pass def v3(a, (b, c), *rest): return a, b, c, rest ! if sys.platform.startswith('java'): ! verify(v3.func_code.co_varnames == ('a', '(b, c)', 'rest', 'b', 'c')) ! else: ! verify(v3.func_code.co_varnames == ('a', '.2', 'rest', 'b', 'c')) verify(v3(1, (2, 3), 4) == (1, 2, 3, (4,))) def d01(a=1): pass From jhylton@users.sourceforge.net Wed Oct 10 03:51:11 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 09 Oct 2001 19:51:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.64,2.65 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv6494 Modified Files: getargs.c Log Message: Use AS_STRING() following the check and avoid an extra call. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.64 retrieving revision 2.65 diff -C2 -d -r2.64 -r2.65 *** getargs.c 2001/09/10 01:54:43 2.64 --- getargs.c 2001/10/10 02:51:08 2.65 *************** *** 648,652 **** *p = 0; else if (PyString_Check(arg)) ! *p = PyString_AsString(arg); #ifdef Py_USING_UNICODE else if (PyUnicode_Check(arg)) { --- 648,652 ---- *p = 0; else if (PyString_Check(arg)) ! *p = PyString_AS_STRING(arg); #ifdef Py_USING_UNICODE else if (PyUnicode_Check(arg)) { From jhylton@users.sourceforge.net Wed Oct 10 03:51:59 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 09 Oct 2001 19:51:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.65,2.66 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv6673 Modified Files: getargs.c Log Message: One more place where PyString_AsString() was used after a PyString_Check() had already succeeded. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.65 retrieving revision 2.66 diff -C2 -d -r2.65 -r2.66 *** getargs.c 2001/10/10 02:51:08 2.65 --- getargs.c 2001/10/10 02:51:57 2.66 *************** *** 554,558 **** char *p = va_arg(*p_va, char *); if (PyString_Check(arg) && PyString_Size(arg) == 1) ! *p = PyString_AsString(arg)[0]; else return converterr("char", arg, msgbuf); --- 554,558 ---- char *p = va_arg(*p_va, char *); if (PyString_Check(arg) && PyString_Size(arg) == 1) ! *p = PyString_AS_STRING(arg)[0]; else return converterr("char", arg, msgbuf); From jhylton@users.sourceforge.net Wed Oct 10 04:19:41 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 09 Oct 2001 20:19:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.168,1.169 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv13517 Modified Files: socketmodule.c Log Message: Fix two memory leaks in socket.ssl(). XXX [1] These changes aren't tested very thoroughly, because regrtest doesn't do any SSL tests. I've done some trivial tests on my own, but don't really know how to use the key and cert files. In one case, an SSL-level error causes Python to dump core. I'll get the fixed in the next round of changes. XXX [2] The checkin removes the x_attr member of the SSLObject struct. I'm not sure if this is kosher for backwards compatibility at the binary level. Perhaps its safer to keep the member but keep it assigned to NULL. And the leaks? newSSLObject() called PyDict_New(), stored the result in x_attr without checking it, and later stored NULL in x_attr without doing anything to the dict. So the dict always leaks. There is no further reference to x_attr, so I just removed it completely. The error cases in newSSLObject() passed the return value of PyString_FromString() directly to PyErr_SetObject(). PyErr_SetObject() expects a borrowed reference, so the string leaked. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.168 retrieving revision 1.169 diff -C2 -d -r1.168 -r1.169 *** socketmodule.c 2001/08/29 21:37:09 1.168 --- socketmodule.c 2001/10/10 03:19:39 1.169 *************** *** 492,496 **** PyObject_HEAD PySocketSockObject *Socket; /* Socket on which we're layered */ - PyObject *x_attr; /* Attributes dictionary */ SSL_CTX* ctx; SSL* ssl; --- 492,495 ---- *************** *** 2500,2551 **** { SSLObject *self; self = PyObject_New(SSLObject, &SSL_Type); /* Create new object */ if (self == NULL){ ! PyErr_SetObject(SSLErrorObject, ! PyString_FromString("newSSLObject error")); ! return NULL; } memset(self->server, '\0', sizeof(char) * 256); memset(self->issuer, '\0', sizeof(char) * 256); - self->x_attr = PyDict_New(); self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */ if (self->ctx == NULL) { ! PyErr_SetObject(SSLErrorObject, ! PyString_FromString("SSL_CTX_new error")); ! PyObject_Del(self); ! return NULL; } ! if ( (key_file && !cert_file) || (!key_file && cert_file) ) ! { ! PyErr_SetObject(SSLErrorObject, ! PyString_FromString( ! "Both the key & certificate files must be specified")); ! PyObject_Del(self); ! return NULL; } ! if (key_file && cert_file) ! { if (SSL_CTX_use_PrivateKey_file(self->ctx, key_file, ! SSL_FILETYPE_PEM) < 1) ! { ! PyErr_SetObject(SSLErrorObject, ! PyString_FromString( ! "SSL_CTX_use_PrivateKey_file error")); ! PyObject_Del(self); ! return NULL; } if (SSL_CTX_use_certificate_chain_file(self->ctx, ! cert_file) < 1) ! { ! PyErr_SetObject(SSLErrorObject, ! PyString_FromString( ! "SSL_CTX_use_certificate_chain_file error")); ! PyObject_Del(self); ! return NULL; } } --- 2499,2537 ---- { SSLObject *self; + PyObject *error = NULL; self = PyObject_New(SSLObject, &SSL_Type); /* Create new object */ if (self == NULL){ ! error = PyString_FromString("newSSLObject error"); ! goto fail; } memset(self->server, '\0', sizeof(char) * 256); memset(self->issuer, '\0', sizeof(char) * 256); self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */ if (self->ctx == NULL) { ! error = PyString_FromString("SSL_CTX_new error"); ! goto fail; } ! if ((key_file && !cert_file) || (!key_file && cert_file)) { ! error = PyString_FromString( ! "Both the key & certificate files must be specified"); ! goto fail; } ! if (key_file && cert_file) { if (SSL_CTX_use_PrivateKey_file(self->ctx, key_file, ! SSL_FILETYPE_PEM) < 1) { ! error = PyString_FromString( ! "SSL_CTX_use_PrivateKey_file error"); ! goto fail; } if (SSL_CTX_use_certificate_chain_file(self->ctx, ! cert_file) < 1) { ! error = PyString_FromString( ! "SSL_CTX_use_certificate_chain_file error"); ! goto fail; } } *************** *** 2557,2566 **** SSL_set_connect_state(self->ssl); if ((SSL_connect(self->ssl)) == -1) { ! /* Actually negotiate SSL connection */ ! PyErr_SetObject(SSLErrorObject, ! PyString_FromString("SSL_connect error")); ! PyObject_Del(self); ! return NULL; } self->ssl->debug = 1; --- 2543,2551 ---- SSL_set_connect_state(self->ssl); + /* Actually negotiate SSL connection */ + /* XXX If SSL_connect() returns 0, it's also a failure. */ if ((SSL_connect(self->ssl)) == -1) { ! error = PyString_FromString("SSL_connect error"); ! goto fail; } self->ssl->debug = 1; *************** *** 2572,2579 **** self->issuer, 256); } - self->x_attr = NULL; self->Socket = Sock; Py_INCREF(self->Socket); return self; } --- 2557,2570 ---- self->issuer, 256); } self->Socket = Sock; Py_INCREF(self->Socket); return self; + fail: + if (error) { + PyErr_SetObject(SSLErrorObject, error); + Py_DECREF(error); + } + Py_DECREF(self); + return NULL; } *************** *** 2630,2634 **** SSL_free(self->ssl); SSL_CTX_free(self->ctx); - Py_XDECREF(self->x_attr); Py_XDECREF(self->Socket); PyObject_Del(self); --- 2621,2624 ---- From jhylton@users.sourceforge.net Wed Oct 10 04:33:26 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 09 Oct 2001 20:33:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.169,1.170 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv16299 Modified Files: socketmodule.c Log Message: A bit of reformatting to match the standard style Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.169 retrieving revision 1.170 diff -C2 -d -r1.169 -r1.170 *** socketmodule.c 2001/10/10 03:19:39 1.169 --- socketmodule.c 2001/10/10 03:33:24 1.170 *************** *** 2580,2588 **** if (!PyArg_ParseTuple(args, "O!zz:ssl", &PySocketSock_Type, (PyObject*)&Sock, ! &key_file, &cert_file) ) return NULL; rv = newSSLObject(Sock, key_file, cert_file); ! if ( rv == NULL ) return NULL; return (PyObject *)rv; --- 2580,2588 ---- if (!PyArg_ParseTuple(args, "O!zz:ssl", &PySocketSock_Type, (PyObject*)&Sock, ! &key_file, &cert_file)) return NULL; rv = newSSLObject(Sock, key_file, cert_file); ! if (rv == NULL) return NULL; return (PyObject *)rv; *************** *** 2608,2616 **** static PyMethodDef SSLMethods[] = { ! { "write", (PyCFunction)SSL_SSLwrite, 1 }, ! { "read", (PyCFunction)SSL_SSLread, 1 }, ! { "server", (PyCFunction)SSL_server, 1 }, ! { "issuer", (PyCFunction)SSL_issuer, 1 }, ! { NULL, NULL} }; --- 2608,2616 ---- static PyMethodDef SSLMethods[] = { ! {"write", (PyCFunction)SSL_SSLwrite, 1}, ! {"read", (PyCFunction)SSL_SSLread, 1}, ! {"server", (PyCFunction)SSL_server, 1}, ! {"issuer", (PyCFunction)SSL_issuer, 1}, ! {NULL, NULL} }; From jhylton@users.sourceforge.net Wed Oct 10 04:37:08 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 09 Oct 2001 20:37:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.170,1.171 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv17099 Modified Files: socketmodule.c Log Message: In newSSLObject(), initialize the various members of an SSLObject to NULL. In SSL_dealloc(), free/dealloc them only if they're non-NULL. Fixes some obvious core dumps, but not sure yet if there are more semantics to the SSL calls that would affect the dealloc. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.170 retrieving revision 1.171 diff -C2 -d -r1.170 -r1.171 *** socketmodule.c 2001/10/10 03:33:24 1.170 --- socketmodule.c 2001/10/10 03:37:05 1.171 *************** *** 2508,2511 **** --- 2508,2515 ---- memset(self->server, '\0', sizeof(char) * 256); memset(self->issuer, '\0', sizeof(char) * 256); + self->server_cert = NULL; + self->ssl = NULL; + self->ctx = NULL; + self->Socket = NULL; self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */ *************** *** 2619,2624 **** if (self->server_cert) /* Possible not to have one? */ X509_free (self->server_cert); ! SSL_free(self->ssl); ! SSL_CTX_free(self->ctx); Py_XDECREF(self->Socket); PyObject_Del(self); --- 2623,2630 ---- if (self->server_cert) /* Possible not to have one? */ X509_free (self->server_cert); ! if (self->ssl) ! SSL_free(self->ssl); ! if (self->ctx) ! SSL_CTX_free(self->ctx); Py_XDECREF(self->Socket); PyObject_Del(self); From tim_one@users.sourceforge.net Wed Oct 10 05:16:22 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 09 Oct 2001 21:16:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-riscos riscospath.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-riscos In directory usw-pr-cvs1:/tmp/cvs-serv25866/python/Lib/plat-riscos Modified Files: riscospath.py Log Message: SF bug [#469732] os.path.walk docstring inconsistent. We have 5 implementations of walk(), and 5 different docstrings. Combined 'em. Let's see how long it takes before they're all different again! Index: riscospath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-riscos/riscospath.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** riscospath.py 2001/09/17 15:16:09 1.5 --- riscospath.py 2001/10/10 04:16:20 1.6 *************** *** 351,359 **** def walk(top, func, arg): ! """ ! walk(top,func,args) 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". ! """ try: names= os.listdir(top) --- 351,368 ---- def walk(top, func, arg): ! """Directory tree walk with callback function. ! ! For each directory in the directory tree rooted at top (including top ! itself, but excluding '.' and '..'), call func(arg, dirname, fnames). ! dirname is the name of the directory, and fnames a list of the names of ! the files and subdirectories in dirname (excluding '.' and '..'). func ! may modify the fnames list in-place (e.g. via del or slice assignment), ! and walk will only recurse into the subdirectories whose names remain in ! fnames; this can be used to implement a filter, or to impose a specific ! order of visiting. No semantics are defined for, or required of, arg, ! beyond that arg is always passed to func. It can be used, e.g., to pass ! a filename pattern, or a mutable object designed to accumulate ! statistics. Passing None for arg is common.""" ! try: names= os.listdir(top) From tim_one@users.sourceforge.net Wed Oct 10 05:16:22 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 09 Oct 2001 21:16:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib dospath.py,1.24,1.25 macpath.py,1.30,1.31 ntpath.py,1.42,1.43 posixpath.py,1.45,1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv25866/python/Lib Modified Files: dospath.py macpath.py ntpath.py posixpath.py Log Message: SF bug [#469732] os.path.walk docstring inconsistent. We have 5 implementations of walk(), and 5 different docstrings. Combined 'em. Let's see how long it takes before they're all different again! Index: dospath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dospath.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** dospath.py 2001/09/17 15:16:09 1.24 --- dospath.py 2001/10/10 04:16:20 1.25 *************** *** 184,194 **** def walk(top, func, arg): ! """Directory tree walk. ! For each directory under top (including top itself, but excluding ! '.' and '..'), func(arg, dirname, filenames) is called, where ! dirname is the name of the directory and filenames is the list ! files files (and subdirectories etc.) in the directory. ! The func may modify the filenames list, to implement a filter, ! or to impose a different order of visiting.""" try: --- 184,200 ---- def walk(top, func, arg): ! """Directory tree walk with callback function. ! ! For each directory in the directory tree rooted at top (including top ! itself, but excluding '.' and '..'), call func(arg, dirname, fnames). ! dirname is the name of the directory, and fnames a list of the names of ! the files and subdirectories in dirname (excluding '.' and '..'). func ! may modify the fnames list in-place (e.g. via del or slice assignment), ! and walk will only recurse into the subdirectories whose names remain in ! fnames; this can be used to implement a filter, or to impose a specific ! order of visiting. No semantics are defined for, or required of, arg, ! beyond that arg is always passed to func. It can be used, e.g., to pass ! a filename pattern, or a mutable object designed to accumulate ! statistics. Passing None for arg is common.""" try: Index: macpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/macpath.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** macpath.py 2001/09/17 15:16:09 1.30 --- macpath.py 2001/10/10 04:16:20 1.31 *************** *** 202,212 **** def walk(top, func, arg): ! """Directory tree walk. ! For each directory under top (including top itself), ! func(arg, dirname, filenames) is called, where ! dirname is the name of the directory and filenames is the list ! of files (and subdirectories etc.) in the directory. ! The func may modify the filenames list, to implement a filter, ! or to impose a different order of visiting.""" try: --- 202,218 ---- def walk(top, func, arg): ! """Directory tree walk with callback function. ! ! For each directory in the directory tree rooted at top (including top ! itself, but excluding '.' and '..'), call func(arg, dirname, fnames). ! dirname is the name of the directory, and fnames a list of the names of ! the files and subdirectories in dirname (excluding '.' and '..'). func ! may modify the fnames list in-place (e.g. via del or slice assignment), ! and walk will only recurse into the subdirectories whose names remain in ! fnames; this can be used to implement a filter, or to impose a specific ! order of visiting. No semantics are defined for, or required of, arg, ! beyond that arg is always passed to func. It can be used, e.g., to pass ! a filename pattern, or a mutable object designed to accumulate ! statistics. Passing None for arg is common.""" try: Index: ntpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ntpath.py,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** ntpath.py 2001/09/17 15:16:09 1.42 --- ntpath.py 2001/10/10 04:16:20 1.43 *************** *** 292,300 **** def walk(top, func, arg): ! """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.""" try: names = os.listdir(top) --- 292,309 ---- def walk(top, func, arg): ! """Directory tree walk with callback function. ! For each directory in the directory tree rooted at top (including top ! itself, but excluding '.' and '..'), call func(arg, dirname, fnames). ! dirname is the name of the directory, and fnames a list of the names of ! the files and subdirectories in dirname (excluding '.' and '..'). func ! may modify the fnames list in-place (e.g. via del or slice assignment), ! and walk will only recurse into the subdirectories whose names remain in ! fnames; this can be used to implement a filter, or to impose a specific ! order of visiting. No semantics are defined for, or required of, arg, ! beyond that arg is always passed to func. It can be used, e.g., to pass ! a filename pattern, or a mutable object designed to accumulate ! statistics. Passing None for arg is common.""" ! try: names = os.listdir(top) Index: posixpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/posixpath.py,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** posixpath.py 2001/09/18 02:26:39 1.45 --- posixpath.py 2001/10/10 04:16:20 1.46 *************** *** 259,266 **** def walk(top, func, arg): ! """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". ! """ try: names = os.listdir(top) --- 259,276 ---- def walk(top, func, arg): ! """Directory tree walk with callback function. ! ! For each directory in the directory tree rooted at top (including top ! itself, but excluding '.' and '..'), call func(arg, dirname, fnames). ! dirname is the name of the directory, and fnames a list of the names of ! the files and subdirectories in dirname (excluding '.' and '..'). func ! may modify the fnames list in-place (e.g. via del or slice assignment), ! and walk will only recurse into the subdirectories whose names remain in ! fnames; this can be used to implement a filter, or to impose a specific ! order of visiting. No semantics are defined for, or required of, arg, ! beyond that arg is always passed to func. It can be used, e.g., to pass ! a filename pattern, or a mutable object designed to accumulate ! statistics. Passing None for arg is common.""" ! try: names = os.listdir(top) From gvanrossum@users.sourceforge.net Wed Oct 10 15:29:01 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 10 Oct 2001 07:29:01 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv31523 Modified Files: PLAN.txt Log Message: Fred's done with weakrefs Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PLAN.txt,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** PLAN.txt 2001/10/04 19:46:06 1.13 --- PLAN.txt 2001/10/10 14:28:58 1.14 *************** *** 13,18 **** update the tp_XXX slot in each derived class when the base class __XXX__ gets set or deleted. More work, but more gain (zero waste ! in slot_tp_XXX when __XXX__ is not overridden). This is currently ! awaiting Fred turning the weak ref API into a standard object API. Add __del__ handlers? --- 13,17 ---- update the tp_XXX slot in each derived class when the base class __XXX__ gets set or deleted. More work, but more gain (zero waste ! in slot_tp_XXX when __XXX__ is not overridden). Add __del__ handlers? From montanaro@users.sourceforge.net Wed Oct 10 16:56:36 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Wed, 10 Oct 2001 08:56:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv25433 Modified Files: xmlrpclib.py Log Message: allow long ints to be marshalled as ints - no check is made to the incoming value, so the programmer will have to catch OverflowError. I'm not sure what /F's perspective is on this. Perhaps it should be caught and mapped to an xmlrpclib-specific exception. None of the other type-specific dump methods seem to do any exception handling though. Index: xmlrpclib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xmlrpclib.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** xmlrpclib.py 2001/10/02 18:33:11 1.11 --- xmlrpclib.py 2001/10/10 15:56:34 1.12 *************** *** 34,37 **** --- 34,38 ---- # 2001-10-01 fl Remove containers from memo cache when done with them # 2001-10-01 fl Use faster escape method (80% dumps speedup) + # 2001-10-10 sm Allow long ints to be passed as ints if they don't overflow # # Copyright (c) 1999-2001 by Secret Labs AB. *************** *** 464,467 **** --- 465,473 ---- self.write("%s\n" % value) dispatch[IntType] = dump_int + + def dump_long(self, value): + val = int(value) + self.write("%s\n" % val) + dispatch[LongType] = dump_long def dump_double(self, value): From jackjansen@users.sourceforge.net Wed Oct 10 22:58:35 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 10 Oct 2001 14:58:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Build PythonStandalone.mcp,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory usw-pr-cvs1:/tmp/cvs-serv24691/Python/Mac/Build Modified Files: PythonStandalone.mcp Log Message: Some of the lesser used targets still used FMADD/FMSUB instructions. Fixed. Index: PythonStandalone.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonStandalone.mcp,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 Binary files /tmp/cvscVmbIe and /tmp/cvs4YreEi differ From jackjansen@users.sourceforge.net Wed Oct 10 22:59:11 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 10 Oct 2001 14:59:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Build PythonStandSmall.mcp,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory usw-pr-cvs1:/tmp/cvs-serv24753/Python/Mac/Build Modified Files: PythonStandSmall.mcp Log Message: Some of the lesser used targets still used FMADD/FMSUB instructions. Fixed. Index: PythonStandSmall.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonStandSmall.mcp,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 Binary files /tmp/cvscyC4yb and /tmp/cvsQLrGqf differ From jackjansen@users.sourceforge.net Wed Oct 10 23:03:29 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 10 Oct 2001 15:03:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.132,2.133 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv26029/Python/Objects Modified Files: fileobject.c Log Message: Rather gross workaround for a bug in the mac GUSI I/O library: lseek(fp, 0L, SEEK_CUR) can make a filedescriptor unusable. This workaround is expected to last only a few weeks (until GUSI is fixed), but without it test_email fails. Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.132 retrieving revision 2.133 diff -C2 -d -r2.132 -r2.133 *** fileobject.c 2001/10/05 20:51:38 2.132 --- fileobject.c 2001/10/10 22:03:27 2.133 *************** *** 524,530 **** need to take the amount of buffered data into account. (Yet another reason why stdio stinks. :-) */ pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR); ! if (pos >= 0) pos = ftell(f->f_fp); if (pos < 0) clearerr(f->f_fp); --- 524,536 ---- need to take the amount of buffered data into account. (Yet another reason why stdio stinks. :-) */ + #ifdef USE_GUSI2 + pos = lseek(fileno(f->f_fp), 1L, SEEK_CUR); + pos = lseek(fileno(f->f_fp), -1L, SEEK_CUR); + #else pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR); ! #endif ! if (pos >= 0) { pos = ftell(f->f_fp); + } if (pos < 0) clearerr(f->f_fp); From guido@python.org Wed Oct 10 23:12:06 2001 From: guido@python.org (Guido van Rossum) Date: Wed, 10 Oct 2001 18:12:06 -0400 Subject: [Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,1.11,1.12 In-Reply-To: Your message of "Wed, 10 Oct 2001 08:56:36 PDT." References: Message-ID: <200110102212.f9AMC7021549@odiug.digicool.com> > allow long ints to be marshalled as ints - no check is made to the incoming > value, so the programmer will have to catch OverflowError. I'm not sure > what /F's perspective is on this. Perhaps it should be caught and mapped to > an xmlrpclib-specific exception. None of the other type-specific dump > methods seem to do any exception handling though. In 2.2, why don't we just marshal str(value)? If the receiving side can handle bigints (as 2.2 can), it will automatically do the right thing, right? Or does xmlrpc have a restriction on the size of 111111111111111111111111111111111111111111? --Guido van Rossum (home page: http://www.python.org/~guido/) > Index: xmlrpclib.py > =================================================================== > RCS file: /cvsroot/python/python/dist/src/Lib/xmlrpclib.py,v > retrieving revision 1.11 > retrieving revision 1.12 > diff -C2 -d -r1.11 -r1.12 > *** xmlrpclib.py 2001/10/02 18:33:11 1.11 > --- xmlrpclib.py 2001/10/10 15:56:34 1.12 > *************** > *** 34,37 **** > --- 34,38 ---- > # 2001-10-01 fl Remove containers from memo cache when done with them > # 2001-10-01 fl Use faster escape method (80% dumps speedup) > + # 2001-10-10 sm Allow long ints to be passed as ints if they don't overflow > # > # Copyright (c) 1999-2001 by Secret Labs AB. > *************** > *** 464,467 **** > --- 465,473 ---- > self.write("%s\n" % value) > dispatch[IntType] = dump_int > + > + def dump_long(self, value): > + val = int(value) > + self.write("%s\n" % val) > + dispatch[LongType] = dump_long > > def dump_double(self, value): > > > _______________________________________________ > Python-checkins mailing list > Python-checkins@python.org > http://mail.python.org/mailman/listinfo/python-checkins From jhylton@users.sourceforge.net Wed Oct 10 23:33:34 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 10 Oct 2001 15:33:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.171,1.172 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv4370 Modified Files: socketmodule.c Log Message: USe PyObject_SetString() instead of PyObject_SetObject() in newSSLObject(). Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.171 retrieving revision 1.172 diff -C2 -d -r1.171 -r1.172 *** socketmodule.c 2001/10/10 03:37:05 1.171 --- socketmodule.c 2001/10/10 22:33:32 1.172 *************** *** 2499,2507 **** { SSLObject *self; ! PyObject *error = NULL; self = PyObject_New(SSLObject, &SSL_Type); /* Create new object */ if (self == NULL){ ! error = PyString_FromString("newSSLObject error"); goto fail; } --- 2499,2507 ---- { SSLObject *self; ! char *errstr = NULL; self = PyObject_New(SSLObject, &SSL_Type); /* Create new object */ if (self == NULL){ ! errstr = "newSSLObject error"; goto fail; } *************** *** 2515,2525 **** self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */ if (self->ctx == NULL) { ! error = PyString_FromString("SSL_CTX_new error"); goto fail; } if ((key_file && !cert_file) || (!key_file && cert_file)) { ! error = PyString_FromString( ! "Both the key & certificate files must be specified"); goto fail; } --- 2515,2524 ---- self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */ if (self->ctx == NULL) { ! errstr = "SSL_CTX_new error"; goto fail; } if ((key_file && !cert_file) || (!key_file && cert_file)) { ! errstr = "Both the key & certificate files must be specified"; goto fail; } *************** *** 2528,2533 **** if (SSL_CTX_use_PrivateKey_file(self->ctx, key_file, SSL_FILETYPE_PEM) < 1) { ! error = PyString_FromString( ! "SSL_CTX_use_PrivateKey_file error"); goto fail; } --- 2527,2531 ---- if (SSL_CTX_use_PrivateKey_file(self->ctx, key_file, SSL_FILETYPE_PEM) < 1) { ! errstr = "SSL_CTX_use_PrivateKey_file error"; goto fail; } *************** *** 2535,2540 **** if (SSL_CTX_use_certificate_chain_file(self->ctx, cert_file) < 1) { ! error = PyString_FromString( ! "SSL_CTX_use_certificate_chain_file error"); goto fail; } --- 2533,2537 ---- if (SSL_CTX_use_certificate_chain_file(self->ctx, cert_file) < 1) { ! errstr = "SSL_CTX_use_certificate_chain_file error"; goto fail; } *************** *** 2550,2554 **** /* XXX If SSL_connect() returns 0, it's also a failure. */ if ((SSL_connect(self->ssl)) == -1) { ! error = PyString_FromString("SSL_connect error"); goto fail; } --- 2547,2551 ---- /* XXX If SSL_connect() returns 0, it's also a failure. */ if ((SSL_connect(self->ssl)) == -1) { ! errstr = "SSL_connect error"; goto fail; } *************** *** 2565,2572 **** return self; fail: ! if (error) { ! PyErr_SetObject(SSLErrorObject, error); ! Py_DECREF(error); ! } Py_DECREF(self); return NULL; --- 2562,2567 ---- return self; fail: ! if (errstr) ! PyErr_SetString(SSLErrorObject, errstr); Py_DECREF(self); return NULL; From jhylton@users.sourceforge.net Wed Oct 10 23:37:51 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 10 Oct 2001 15:37:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.172,1.173 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv5857 Modified Files: socketmodule.c Log Message: Do simple error checking before doing any SSL calls. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.172 retrieving revision 1.173 diff -C2 -d -r1.172 -r1.173 *** socketmodule.c 2001/10/10 22:33:32 1.172 --- socketmodule.c 2001/10/10 22:37:48 1.173 *************** *** 2513,2524 **** self->Socket = NULL; ! self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */ ! if (self->ctx == NULL) { ! errstr = "SSL_CTX_new error"; goto fail; } ! if ((key_file && !cert_file) || (!key_file && cert_file)) { ! errstr = "Both the key & certificate files must be specified"; goto fail; } --- 2513,2524 ---- self->Socket = NULL; ! if ((key_file && !cert_file) || (!key_file && cert_file)) { ! errstr = "Both the key & certificate files must be specified"; goto fail; } ! self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */ ! if (self->ctx == NULL) { ! errstr = "SSL_CTX_new error"; goto fail; } From skip@pobox.com (Skip Montanaro) Wed Oct 10 23:45:24 2001 From: skip@pobox.com (Skip Montanaro) (Skip Montanaro) Date: Wed, 10 Oct 2001 17:45:24 -0500 Subject: [Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,1.11,1.12 In-Reply-To: <200110102212.f9AMC7021549@odiug.digicool.com> References: <200110102212.f9AMC7021549@odiug.digicool.com> Message-ID: <15300.53124.337406.782115@beluga.mojam.com> Guido> In 2.2, why don't we just marshal str(value)? If the receiving Guido> side can handle bigints (as 2.2 can), it will automatically do Guido> the right thing, right? Or does xmlrpc have a restriction on the Guido> size of 111111111111111111111111111111111111111111? Yes, that's it precisely (four-byte signed ints). The XML-RPC spec is probably worth a quick glance for any Pythoneers not familiar with it. It's quite short. http://www.xmlrpc.com/spec Skip From jhylton@users.sourceforge.net Thu Oct 11 00:55:46 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 10 Oct 2001 16:55:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.173,1.174 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv24881 Modified Files: socketmodule.c Log Message: Lots of code reorganization with a few small API changes. Change all the local names that start with SSL to start with PySSL. The OpenSSL library defines lots of calls that start with "SSL_". The calls for Python's SSL objects also started with "SSL_". This choice made it really confusing to figure out which calls were to the library and which calls were local to the file. Add PySSL_SetError() that sets an exception based on the information from SSL_get_error(). This function will eventually replace all the calls that set it with an error message that is based on the name of the call that failed rather than the reason it failed. (Example: If SSL_connect() failed it used to report "SSL_connect error" now it will offer a specific message about why SSL_connect failed.) XXX It might be helpful to augment the error message generated below with the name of the SSL function that generated the error. I expect it's obvious most of the time. Remove several unnecessary INCREFs in the module's constructor call. PyDict_SetItem() and friends do the INCREF for you. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.173 retrieving revision 1.174 diff -C2 -d -r1.173 -r1.174 *** socketmodule.c 2001/10/10 22:37:48 1.173 --- socketmodule.c 2001/10/10 23:55:43 1.174 *************** *** 283,287 **** #ifdef USE_SSL ! static PyObject *SSLErrorObject; #endif /* USE_SSL */ --- 283,287 ---- #ifdef USE_SSL ! static PyObject *PySSLErrorObject; #endif /* USE_SSL */ *************** *** 499,509 **** char issuer[256]; ! } SSLObject; ! staticforward PyTypeObject SSL_Type; ! staticforward PyObject *SSL_SSLwrite(SSLObject *self, PyObject *args); ! staticforward PyObject *SSL_SSLread(SSLObject *self, PyObject *args); ! #define SSLObject_Check(v) ((v)->ob_type == &SSL_Type) #endif /* USE_SSL */ --- 499,509 ---- char issuer[256]; ! } PySSLObject; ! staticforward PyTypeObject PySSL_Type; ! staticforward PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args); ! staticforward PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args); ! #define PySSLObject_Check(v) ((v)->ob_type == &PySSL_Type) #endif /* USE_SSL */ *************** *** 2491,2507 **** Get host and port for a sockaddr."; #ifdef USE_SSL /* This is a C function to be called for new object initialization */ ! static SSLObject * ! newSSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file) { ! SSLObject *self; char *errstr = NULL; ! self = PyObject_New(SSLObject, &SSL_Type); /* Create new object */ if (self == NULL){ ! errstr = "newSSLObject error"; goto fail; } --- 2491,2576 ---- Get host and port for a sockaddr."; + /* XXX It might be helpful to augment the error message generated + below with the name of the SSL function that generated the error. + I expect it's obvious most of the time. + */ #ifdef USE_SSL + static PyObject * + PySSL_SetError(SSL *ssl, int ret) + { + PyObject *v, *n, *s; + char *errstr; + int err; + + assert(ret <= 0); + + err = SSL_get_error(ssl, ret); + n = PyInt_FromLong(err); + if (n == NULL) + return NULL; + v = PyTuple_New(2); + if (v == NULL) { + Py_DECREF(n); + return NULL; + } + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_ZERO_RETURN: + errstr = "TLS/SSL connection has been closed"; + break; + case SSL_ERROR_WANT_READ: + errstr = "The operation did not complete (read)"; + break; + case SSL_ERROR_WANT_WRITE: + errstr = "The operation did not complete (write)"; + break; + case SSL_ERROR_WANT_X509_LOOKUP: + errstr = "The operation did not complete (X509 lookup)"; + break; + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + { + unsigned long e = ERR_get_error(); + if (e == 0) { + /* an EOF was observed that violates the protocol */ + errstr = "EOF occurred in violation of protocol"; + } else if (e == -1) { + /* the underlying BIO reported an I/O error */ + Py_DECREF(v); + Py_DECREF(n); + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } else { + /* XXX Protected by global interpreter lock */ + errstr = ERR_error_string(e, NULL); + } + break; + } + default: + errstr = "Invalid error code"; + } + s = PyString_FromString(errstr); + if (s == NULL) { + Py_DECREF(v); + Py_DECREF(n); + } + PyTuple_SET_ITEM(v, 0, n); + PyTuple_SET_ITEM(v, 1, s); + PyErr_SetObject(PySSLErrorObject, v); + return NULL; + } /* This is a C function to be called for new object initialization */ ! static PySSLObject * ! newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file) { ! PySSLObject *self; char *errstr = NULL; + int ret; ! self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */ if (self == NULL){ ! errstr = "newPySSLObject error"; goto fail; } *************** *** 2524,2528 **** } ! if (key_file && cert_file) { if (SSL_CTX_use_PrivateKey_file(self->ctx, key_file, SSL_FILETYPE_PEM) < 1) { --- 2593,2597 ---- } ! if (key_file) { if (SSL_CTX_use_PrivateKey_file(self->ctx, key_file, SSL_FILETYPE_PEM) < 1) { *************** *** 2546,2551 **** /* Actually negotiate SSL connection */ /* XXX If SSL_connect() returns 0, it's also a failure. */ ! if ((SSL_connect(self->ssl)) == -1) { ! errstr = "SSL_connect error"; goto fail; } --- 2615,2621 ---- /* Actually negotiate SSL connection */ /* XXX If SSL_connect() returns 0, it's also a failure. */ ! ret = SSL_connect(self->ssl); ! if (ret <= 0) { ! PySSL_SetError(self->ssl, ret); goto fail; } *************** *** 2563,2567 **** fail: if (errstr) ! PyErr_SetString(SSLErrorObject, errstr); Py_DECREF(self); return NULL; --- 2633,2637 ---- fail: if (errstr) ! PyErr_SetString(PySSLErrorObject, errstr); Py_DECREF(self); return NULL; *************** *** 2572,2586 **** PySocket_ssl(PyObject *self, PyObject *args) { ! SSLObject *rv; PySocketSockObject *Sock; ! char *key_file; ! char *cert_file; ! if (!PyArg_ParseTuple(args, "O!zz:ssl", &PySocketSock_Type, (PyObject*)&Sock, &key_file, &cert_file)) return NULL; ! rv = newSSLObject(Sock, key_file, cert_file); if (rv == NULL) return NULL; --- 2642,2656 ---- PySocket_ssl(PyObject *self, PyObject *args) { ! PySSLObject *rv; PySocketSockObject *Sock; ! char *key_file = NULL; ! char *cert_file = NULL; ! if (!PyArg_ParseTuple(args, "O!|zz:ssl", &PySocketSock_Type, (PyObject*)&Sock, &key_file, &cert_file)) return NULL; ! rv = newPySSLObject(Sock, key_file, cert_file); if (rv == NULL) return NULL; *************** *** 2592,2596 **** static PyObject * ! SSL_server(SSLObject *self, PyObject *args) { return PyString_FromString(self->server); --- 2662,2666 ---- static PyObject * ! PySSL_server(PySSLObject *self, PyObject *args) { return PyString_FromString(self->server); *************** *** 2598,2602 **** static PyObject * ! SSL_issuer(SSLObject *self, PyObject *args) { return PyString_FromString(self->issuer); --- 2668,2672 ---- static PyObject * ! PySSL_issuer(PySSLObject *self, PyObject *args) { return PyString_FromString(self->issuer); *************** *** 2606,2618 **** /* SSL object methods */ ! static PyMethodDef SSLMethods[] = { ! {"write", (PyCFunction)SSL_SSLwrite, 1}, ! {"read", (PyCFunction)SSL_SSLread, 1}, ! {"server", (PyCFunction)SSL_server, 1}, ! {"issuer", (PyCFunction)SSL_issuer, 1}, {NULL, NULL} }; ! static void SSL_dealloc(SSLObject *self) { if (self->server_cert) /* Possible not to have one? */ --- 2676,2688 ---- /* SSL object methods */ ! static PyMethodDef PySSLMethods[] = { ! {"write", (PyCFunction)PySSL_SSLwrite, 1}, ! {"read", (PyCFunction)PySSL_SSLread, 1}, ! {"server", (PyCFunction)PySSL_server, 1}, ! {"issuer", (PyCFunction)PySSL_issuer, 1}, {NULL, NULL} }; ! static void PySSL_dealloc(PySSLObject *self) { if (self->server_cert) /* Possible not to have one? */ *************** *** 2626,2644 **** } ! static PyObject *SSL_getattr(SSLObject *self, char *name) { ! return Py_FindMethod(SSLMethods, (PyObject *)self, name); } ! staticforward PyTypeObject SSL_Type = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ "SSL", /*tp_name*/ ! sizeof(SSLObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ ! (destructor)SSL_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ ! (getattrfunc)SSL_getattr, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ --- 2696,2714 ---- } ! static PyObject *PySSL_getattr(PySSLObject *self, char *name) { ! return Py_FindMethod(PySSLMethods, (PyObject *)self, name); } ! staticforward PyTypeObject PySSL_Type = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ "SSL", /*tp_name*/ ! sizeof(PySSLObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ ! (destructor)PySSL_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ ! (getattrfunc)PySSL_getattr, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ *************** *** 2652,2656 **** ! static PyObject *SSL_SSLwrite(SSLObject *self, PyObject *args) { char *data; --- 2722,2726 ---- ! static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args) { char *data; *************** *** 2664,2668 **** } ! static PyObject *SSL_SSLread(SSLObject *self, PyObject *args) { PyObject *buf; --- 2734,2738 ---- } ! static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args) { PyObject *buf; *************** *** 2687,2691 **** break; default: ! return PyErr_SetFromErrno(SSLErrorObject); } --- 2757,2761 ---- break; default: ! return PyErr_SetFromErrno(PySSLErrorObject); } *************** *** 2694,2698 **** if (count < 0) { Py_DECREF(buf); ! return PyErr_SetFromErrno(SSLErrorObject); } --- 2764,2768 ---- if (count < 0) { Py_DECREF(buf); ! return PyErr_SetFromErrno(PySSLErrorObject); } *************** *** 2905,2909 **** #endif /* RISCOS */ #ifdef USE_SSL ! SSL_Type.ob_type = &PyType_Type; #endif m = Py_InitModule3("_socket", PySocket_methods, module_doc); --- 2975,2979 ---- #endif /* RISCOS */ #ifdef USE_SSL ! PySSL_Type.ob_type = &PyType_Type; #endif m = Py_InitModule3("_socket", PySocket_methods, module_doc); *************** *** 2925,2940 **** SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); ! SSLErrorObject = PyErr_NewException("socket.sslerror", NULL, NULL); ! if (SSLErrorObject == NULL) return; ! PyDict_SetItemString(d, "sslerror", SSLErrorObject); ! Py_INCREF(&SSL_Type); if (PyDict_SetItemString(d, "SSLType", ! (PyObject *)&SSL_Type) != 0) return; #endif /* USE_SSL */ PySocketSock_Type.ob_type = &PyType_Type; PySocketSock_Type.tp_doc = sockettype_doc; - Py_INCREF(&PySocketSock_Type); if (PyDict_SetItemString(d, "SocketType", (PyObject *)&PySocketSock_Type) != 0) --- 2995,3008 ---- SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); ! PySSLErrorObject = PyErr_NewException("socket.sslerror", NULL, NULL); ! if (PySSLErrorObject == NULL) return; ! PyDict_SetItemString(d, "sslerror", PySSLErrorObject); if (PyDict_SetItemString(d, "SSLType", ! (PyObject *)&PySSL_Type) != 0) return; #endif /* USE_SSL */ PySocketSock_Type.ob_type = &PyType_Type; PySocketSock_Type.tp_doc = sockettype_doc; if (PyDict_SetItemString(d, "SocketType", (PyObject *)&PySocketSock_Type) != 0) From jhylton@users.sourceforge.net Thu Oct 11 01:00:20 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 10 Oct 2001 17:00:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.174,1.175 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv25613 Modified Files: socketmodule.c Log Message: Add a bunch of SSL error constants Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.174 retrieving revision 1.175 diff -C2 -d -r1.174 -r1.175 *** socketmodule.c 2001/10/10 23:55:43 1.174 --- socketmodule.c 2001/10/11 00:00:17 1.175 *************** *** 3002,3005 **** --- 3002,3017 ---- (PyObject *)&PySSL_Type) != 0) return; + PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN", + SSL_ERROR_ZERO_RETURN); + PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ", + SSL_ERROR_WANT_READ); + PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE", + SSL_ERROR_WANT_WRITE); + PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP", + SSL_ERROR_WANT_X509_LOOKUP); + PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL", + SSL_ERROR_SYSCALL); + PyModule_AddIntConstant(m, "SSL_ERROR_SSL", + SSL_ERROR_SSL); #endif /* USE_SSL */ PySocketSock_Type.ob_type = &PyType_Type; From jhylton@users.sourceforge.net Thu Oct 11 15:09:05 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 11 Oct 2001 07:09:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_binascii.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv27691 Modified Files: test_binascii.py Log Message: Add test of hexlify on Unicode strings Index: test_binascii.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_binascii.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_binascii.py 2001/09/04 19:14:14 1.9 --- test_binascii.py 2001/10/11 14:09:03 1.10 *************** *** 111,112 **** --- 111,116 ---- else: print 'expected TypeError not raised' + + # Verify the treatment of Unicode strings + verify(binascii.hexlify(u'a') == '61', "hexlify failed for Unicode") + From jhylton@users.sourceforge.net Thu Oct 11 15:40:39 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 11 Oct 2001 07:40:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.66,2.67 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv6142 Modified Files: getargs.c Log Message: Undo part of 2.59: 't' case of convertsimple() should not use convertbuffer(). convertbuffer() uses the buffer interface's getreadbuffer(), but 't' should use getcharbuffer(). Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.66 retrieving revision 2.67 diff -C2 -d -r2.66 -r2.67 *** getargs.c 2001/10/10 02:51:57 2.66 --- getargs.c 2001/10/11 14:40:37 2.67 *************** *** 636,640 **** char *buf; int count = convertbuffer(arg, p, &buf); - if (count < 0) return converterr(buf, arg, msgbuf); --- 636,639 ---- *************** *** 937,941 **** case 't': { /* 8-bit character buffer, read-only access */ const char **p = va_arg(*p_va, const char **); ! char *buf; int count; --- 936,940 ---- case 't': { /* 8-bit character buffer, read-only access */ const char **p = va_arg(*p_va, const char **); ! PyBufferProcs *pb = arg->ob_type->tp_as_buffer; int count; *************** *** 945,956 **** arg, msgbuf); if (!PyType_HasFeature(arg->ob_type, ! Py_TPFLAGS_HAVE_GETCHARBUFFER)) return converterr( "string or read-only character buffer", arg, msgbuf); ! count = convertbuffer(arg, (void **)p, &buf); if (count < 0) ! return converterr(buf, arg, msgbuf); *va_arg(*p_va, int *) = count; break; --- 944,962 ---- arg, msgbuf); if (!PyType_HasFeature(arg->ob_type, ! Py_TPFLAGS_HAVE_GETCHARBUFFER) || ! pb == NULL || pb->bf_getcharbuffer == NULL || ! pb->bf_getsegcount == NULL) return converterr( "string or read-only character buffer", arg, msgbuf); ! if (pb->bf_getsegcount(arg, NULL) != 1) ! return converterr( ! "string or single-segment read-only buffer", ! arg, msgbuf); ! ! count = pb->bf_getcharbuffer(arg, 0, p); if (count < 0) ! return converterr("(unspecified)", arg, msgbuf); *va_arg(*p_va, int *) = count; break; From bwarsaw@users.sourceforge.net Thu Oct 11 16:43:02 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 11 Oct 2001 08:43:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email Parser.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv27728 Modified Files: Parser.py Log Message: HeaderParser: A new subclass of Parser which only parses the message headers. It does not parse the body of the message, instead simply assigning it as a string to the container's payload. This can be much faster when you're only interested in a message's header. Index: Parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Parser.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Parser.py 2001/10/04 17:05:11 1.4 --- Parser.py 2001/10/11 15:43:00 1.5 *************** *** 159,160 **** --- 159,176 ---- else: container.add_payload(fp.read()) + + + + class HeaderParser(Parser): + """A subclass of Parser, this one only meaningfully parses message headers. + + This class can be used if all you're interested in is the headers of a + message. While it consumes the message body, it does not parse it, but + simply makes it available as a string payload. + + Parsing with this subclass can be considerably faster if all you're + interested in is the message headers. + """ + def _parsebody(self, container, fp): + # Consume but do not parse, the body + container.set_payload(fp.read()) From bwarsaw@users.sourceforge.net Thu Oct 11 16:44:54 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 11 Oct 2001 08:44:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_email.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv28459 Modified Files: test_email.py Log Message: Add a test for the HeaderParser class. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_email.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_email.py 2001/10/09 19:23:57 1.8 --- test_email.py 2001/10/11 15:44:50 1.9 *************** *** 11,15 **** import email ! from email.Parser import Parser from email.Generator import Generator, DecodedGenerator from email.Message import Message --- 11,15 ---- import email ! from email.Parser import Parser, HeaderParser from email.Generator import Generator, DecodedGenerator from email.Message import Message *************** *** 889,892 **** --- 889,907 ---- + class TestParsers(unittest.TestCase): + def test_header_parser(self): + eq = self.assertEqual + # Parse only the headers of a complex multipart MIME document + p = HeaderParser() + fp = openfile('msg_02.txt') + msg = p.parse(fp) + eq(msg['from'], 'ppp-request@zzz.org') + eq(msg['to'], 'ppp@zzz.org') + eq(msg.get_type(), 'multipart/mixed') + eq(msg.is_multipart(), 0) + self.failUnless(isinstance(msg.get_payload(), StringType)) + + + def suite(): suite = unittest.TestSuite() *************** *** 905,908 **** --- 920,924 ---- suite.addTest(unittest.makeSuite(TestMiscellaneous)) suite.addTest(unittest.makeSuite(TestIterators)) + suite.addTest(unittest.makeSuite(TestParsers)) return suite From bwarsaw@users.sourceforge.net Thu Oct 11 16:45:07 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 11 Oct 2001 08:45:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib emailparser.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv28614 Modified Files: emailparser.tex Log Message: Describe the HeaderParser class. Index: emailparser.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailparser.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** emailparser.tex 2001/09/26 22:21:52 1.2 --- emailparser.tex 2001/10/11 15:45:05 1.3 *************** *** 25,28 **** --- 25,39 ---- message object trees in any way it find necessary. + The primary parser class is \class{Parser} which parses both the + headers and the payload of the message. In the case of + \mimetype{multipart} messages, it will recursively parse the body of + the container message. The \module{email.Parser} module also provides + a second class, called \class{HeaderParser} which can be used if + you're only interested in the headers of the message. + \class{HeaderParser} can be much faster in this situations, since it + does not attempt to parse the message body, instead setting the + payload to the raw body as a string. \class{HeaderParser} has the + same API as the \class{Parser} class. + \subsubsection{Parser class API} From jhylton@users.sourceforge.net Thu Oct 11 17:17:25 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 11 Oct 2001 09:17:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libsocket.tex,1.54,1.55 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv8022 Modified Files: libsocket.tex Log Message: Document that keyfile and certfile are now optional. XXX Forgot to mention this in the last socketmodule.c checkin. Index: libsocket.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsocket.tex,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -d -r1.54 -r1.55 *** libsocket.tex 2001/09/27 04:17:20 1.54 --- libsocket.tex 2001/10/11 16:17:22 1.55 *************** *** 266,270 **** \end{funcdesc} ! \begin{funcdesc}{ssl}{sock, keyfile, certfile} Initiate a SSL connection over the socket \var{sock}. \var{keyfile} is the name of a PEM formatted file that contains your private --- 266,270 ---- \end{funcdesc} ! \begin{funcdesc}{ssl}{sock\optional{, keyfile, certfile}} Initiate a SSL connection over the socket \var{sock}. \var{keyfile} is the name of a PEM formatted file that contains your private From jhylton@users.sourceforge.net Thu Oct 11 17:36:37 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 11 Oct 2001 09:36:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.175,1.176 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv15275 Modified Files: socketmodule.c Log Message: Convert socket methods to use METH_O and METH_NOARGS where possible. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.175 retrieving revision 1.176 diff -C2 -d -r1.175 -r1.176 *** socketmodule.c 2001/10/11 00:00:17 1.175 --- socketmodule.c 2001/10/11 16:36:35 1.176 *************** *** 926,930 **** static PyObject * ! PySocketSock_accept(PySocketSockObject *s, PyObject *args) { char addrbuf[256]; --- 926,930 ---- static PyObject * ! PySocketSock_accept(PySocketSockObject *s) { char addrbuf[256]; *************** *** 935,940 **** PyObject *res = NULL; - if (!PyArg_ParseTuple(args, ":accept")) - return NULL; if (!getsockaddrlen(s, &addrlen)) return NULL; --- 935,938 ---- *************** *** 984,988 **** static PyObject * ! PySocketSock_setblocking(PySocketSockObject *s, PyObject *args) { int block; --- 982,986 ---- static PyObject * ! PySocketSock_setblocking(PySocketSockObject *s, PyObject *arg) { int block; *************** *** 992,996 **** #endif #endif ! if (!PyArg_ParseTuple(args, "i:setblocking", &block)) return NULL; Py_BEGIN_ALLOW_THREADS --- 990,995 ---- #endif #endif ! block = PyInt_AsLong(arg); ! if (block == -1 && PyErr_Occurred()) return NULL; Py_BEGIN_ALLOW_THREADS *************** *** 1159,1170 **** static PyObject * ! PySocketSock_bind(PySocketSockObject *s, PyObject *args) { struct sockaddr *addr; int addrlen; int res; ! PyObject *addro; ! if (!PyArg_ParseTuple(args, "O:bind", &addro)) ! return NULL; if (!getsockaddrarg(s, addro, &addr, &addrlen)) return NULL; --- 1158,1167 ---- static PyObject * ! PySocketSock_bind(PySocketSockObject *s, PyObject *addro) { struct sockaddr *addr; int addrlen; int res; ! if (!getsockaddrarg(s, addro, &addr, &addrlen)) return NULL; *************** *** 1191,1199 **** static PyObject * ! PySocketSock_close(PySocketSockObject *s, PyObject *args) { SOCKET_T fd; ! if (!PyArg_ParseTuple(args, ":close")) ! return NULL; if ((fd = s->sock_fd) != -1) { s->sock_fd = -1; --- 1188,1195 ---- static PyObject * ! PySocketSock_close(PySocketSockObject *s) { SOCKET_T fd; ! if ((fd = s->sock_fd) != -1) { s->sock_fd = -1; *************** *** 1215,1226 **** static PyObject * ! PySocketSock_connect(PySocketSockObject *s, PyObject *args) { struct sockaddr *addr; int addrlen; int res; ! PyObject *addro; ! if (!PyArg_ParseTuple(args, "O:connect", &addro)) ! return NULL; if (!getsockaddrarg(s, addro, &addr, &addrlen)) return NULL; --- 1211,1220 ---- static PyObject * ! PySocketSock_connect(PySocketSockObject *s, PyObject *addro) { struct sockaddr *addr; int addrlen; int res; ! if (!getsockaddrarg(s, addro, &addr, &addrlen)) return NULL; *************** *** 1244,1255 **** static PyObject * ! PySocketSock_connect_ex(PySocketSockObject *s, PyObject *args) { struct sockaddr *addr; int addrlen; int res; ! PyObject *addro; ! if (!PyArg_ParseTuple(args, "O:connect_ex", &addro)) ! return NULL; if (!getsockaddrarg(s, addro, &addr, &addrlen)) return NULL; --- 1238,1247 ---- static PyObject * ! PySocketSock_connect_ex(PySocketSockObject *s, PyObject *addro) { struct sockaddr *addr; int addrlen; int res; ! if (!getsockaddrarg(s, addro, &addr, &addrlen)) return NULL; *************** *** 1272,1279 **** static PyObject * ! PySocketSock_fileno(PySocketSockObject *s, PyObject *args) { - if (!PyArg_ParseTuple(args, ":fileno")) - return NULL; #if SIZEOF_SOCKET_T <= SIZEOF_LONG return PyInt_FromLong((long) s->sock_fd); --- 1264,1269 ---- static PyObject * ! PySocketSock_fileno(PySocketSockObject *s) { #if SIZEOF_SOCKET_T <= SIZEOF_LONG return PyInt_FromLong((long) s->sock_fd); *************** *** 1293,1302 **** static PyObject * ! PySocketSock_dup(PySocketSockObject *s, PyObject *args) { SOCKET_T newfd; PyObject *sock; ! if (!PyArg_ParseTuple(args, ":dup")) ! return NULL; newfd = dup(s->sock_fd); if (newfd < 0) --- 1283,1291 ---- static PyObject * ! PySocketSock_dup(PySocketSockObject *s) { SOCKET_T newfd; PyObject *sock; ! newfd = dup(s->sock_fd); if (newfd < 0) *************** *** 1322,1326 **** static PyObject * ! PySocketSock_getsockname(PySocketSockObject *s, PyObject *args) { char addrbuf[256]; --- 1311,1315 ---- static PyObject * ! PySocketSock_getsockname(PySocketSockObject *s) { char addrbuf[256]; *************** *** 1328,1333 **** socklen_t addrlen; - if (!PyArg_ParseTuple(args, ":getsockname")) - return NULL; if (!getsockaddrlen(s, &addrlen)) return NULL; --- 1317,1320 ---- *************** *** 1352,1356 **** static PyObject * ! PySocketSock_getpeername(PySocketSockObject *s, PyObject *args) { char addrbuf[256]; --- 1339,1343 ---- static PyObject * ! PySocketSock_getpeername(PySocketSockObject *s) { char addrbuf[256]; *************** *** 1358,1363 **** socklen_t addrlen; - if (!PyArg_ParseTuple(args, ":getpeername")) - return NULL; if (!getsockaddrlen(s, &addrlen)) return NULL; --- 1345,1348 ---- *************** *** 1383,1391 **** static PyObject * ! PySocketSock_listen(PySocketSockObject *s, PyObject *args) { int backlog; int res; ! if (!PyArg_ParseTuple(args, "i:listen", &backlog)) return NULL; Py_BEGIN_ALLOW_THREADS --- 1368,1378 ---- static PyObject * ! PySocketSock_listen(PySocketSockObject *s, PyObject *arg) { int backlog; int res; ! ! backlog = PyInt_AsLong(arg); ! if (backlog == -1 && PyErr_Occurred()) return NULL; Py_BEGIN_ALLOW_THREADS *************** *** 1607,1615 **** static PyObject * ! PySocketSock_shutdown(PySocketSockObject *s, PyObject *args) { int how; int res; ! if (!PyArg_ParseTuple(args, "i:shutdown", &how)) return NULL; Py_BEGIN_ALLOW_THREADS --- 1594,1604 ---- static PyObject * ! PySocketSock_shutdown(PySocketSockObject *s, PyObject *arg) { int how; int res; ! ! how = PyInt_AsLong(arg); ! if (how == -1 && PyErr_Occurred()) return NULL; Py_BEGIN_ALLOW_THREADS *************** *** 1632,1660 **** static PyMethodDef PySocketSock_methods[] = { ! {"accept", (PyCFunction)PySocketSock_accept, METH_VARARGS, accept_doc}, ! {"bind", (PyCFunction)PySocketSock_bind, METH_VARARGS, bind_doc}, ! {"close", (PyCFunction)PySocketSock_close, METH_VARARGS, close_doc}, ! {"connect", (PyCFunction)PySocketSock_connect, METH_VARARGS, connect_doc}, ! {"connect_ex", (PyCFunction)PySocketSock_connect_ex, METH_VARARGS, connect_ex_doc}, #ifndef NO_DUP ! {"dup", (PyCFunction)PySocketSock_dup, METH_VARARGS, dup_doc}, #endif ! {"fileno", (PyCFunction)PySocketSock_fileno, METH_VARARGS, fileno_doc}, #ifdef HAVE_GETPEERNAME ! {"getpeername", (PyCFunction)PySocketSock_getpeername, METH_VARARGS, ! getpeername_doc}, #endif ! {"getsockname", (PyCFunction)PySocketSock_getsockname, METH_VARARGS, ! getsockname_doc}, {"getsockopt", (PyCFunction)PySocketSock_getsockopt, METH_VARARGS, getsockopt_doc}, ! {"listen", (PyCFunction)PySocketSock_listen, METH_VARARGS, listen_doc}, #ifndef NO_DUP --- 1621,1649 ---- static PyMethodDef PySocketSock_methods[] = { ! {"accept", (PyNoArgsFunction)PySocketSock_accept, METH_NOARGS, accept_doc}, ! {"bind", (PyCFunction)PySocketSock_bind, METH_O, bind_doc}, ! {"close", (PyNoArgsFunction)PySocketSock_close, METH_NOARGS, close_doc}, ! {"connect", (PyCFunction)PySocketSock_connect, METH_O, connect_doc}, ! {"connect_ex", (PyCFunction)PySocketSock_connect_ex, METH_O, connect_ex_doc}, #ifndef NO_DUP ! {"dup", (PyNoArgsFunction)PySocketSock_dup, METH_NOARGS, dup_doc}, #endif ! {"fileno", (PyNoArgsFunction)PySocketSock_fileno, METH_NOARGS, fileno_doc}, #ifdef HAVE_GETPEERNAME ! {"getpeername", (PyNoArgsFunction)PySocketSock_getpeername, ! METH_NOARGS, getpeername_doc}, #endif ! {"getsockname", (PyNoArgsFunction)PySocketSock_getsockname, ! METH_NOARGS, getsockname_doc}, {"getsockopt", (PyCFunction)PySocketSock_getsockopt, METH_VARARGS, getsockopt_doc}, ! {"listen", (PyCFunction)PySocketSock_listen, METH_O, listen_doc}, #ifndef NO_DUP *************** *** 1670,1678 **** {"sendto", (PyCFunction)PySocketSock_sendto, METH_VARARGS, sendto_doc}, ! {"setblocking", (PyCFunction)PySocketSock_setblocking, METH_VARARGS, setblocking_doc}, {"setsockopt", (PyCFunction)PySocketSock_setsockopt, METH_VARARGS, setsockopt_doc}, ! {"shutdown", (PyCFunction)PySocketSock_shutdown, METH_VARARGS, shutdown_doc}, #ifdef RISCOS --- 1659,1667 ---- {"sendto", (PyCFunction)PySocketSock_sendto, METH_VARARGS, sendto_doc}, ! {"setblocking", (PyCFunction)PySocketSock_setblocking, METH_O, setblocking_doc}, {"setsockopt", (PyCFunction)PySocketSock_setsockopt, METH_VARARGS, setsockopt_doc}, ! {"shutdown", (PyCFunction)PySocketSock_shutdown, METH_O, shutdown_doc}, #ifdef RISCOS From jhylton@users.sourceforge.net Thu Oct 11 18:23:36 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 11 Oct 2001 10:23:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.176,1.177 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv755 Modified Files: socketmodule.c Log Message: Commit parts of SF patch #462759 Use #define X509_NAME_MAXLEN for server/issuer length on an SSL object. Update doc strings for socket.ssl() and ssl methods read() and write(). PySSL_SSLwrite(): Check return value and raise exception on error. Use int for len instead of size_t. (All the function the size_t obj was passed to our from expected an int!) PySSL_SSLread(): Check return value of PyArg_ParseTuple()! More robust checks of return values from SSL_read(). Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.176 retrieving revision 1.177 diff -C2 -d -r1.176 -r1.177 *** socketmodule.c 2001/10/11 16:36:35 1.176 --- socketmodule.c 2001/10/11 17:23:34 1.177 *************** *** 489,492 **** --- 489,494 ---- #ifdef USE_SSL + #define X509_NAME_MAXLEN 256 + typedef struct { PyObject_HEAD *************** *** 496,501 **** X509* server_cert; BIO* sbio; ! char server[256]; ! char issuer[256]; } PySSLObject; --- 498,503 ---- X509* server_cert; BIO* sbio; ! char server[X509_NAME_MAXLEN]; ! char issuer[X509_NAME_MAXLEN]; } PySSLObject; *************** *** 2564,2569 **** goto fail; } ! memset(self->server, '\0', sizeof(char) * 256); ! memset(self->issuer, '\0', sizeof(char) * 256); self->server_cert = NULL; self->ssl = NULL; --- 2566,2571 ---- goto fail; } ! memset(self->server, '\0', sizeof(char) * X509_NAME_MAXLEN); ! memset(self->issuer, '\0', sizeof(char) * X509_NAME_MAXLEN); self->server_cert = NULL; self->ssl = NULL; *************** *** 2613,2619 **** if ((self->server_cert = SSL_get_peer_certificate(self->ssl))) { X509_NAME_oneline(X509_get_subject_name(self->server_cert), ! self->server, 256); X509_NAME_oneline(X509_get_issuer_name(self->server_cert), ! self->issuer, 256); } self->Socket = Sock; --- 2615,2621 ---- if ((self->server_cert = SSL_get_peer_certificate(self->ssl))) { X509_NAME_oneline(X509_get_subject_name(self->server_cert), ! self->server, X509_NAME_MAXLEN); X509_NAME_oneline(X509_get_issuer_name(self->server_cert), ! self->issuer, X509_NAME_MAXLEN); } self->Socket = Sock; *************** *** 2648,2655 **** static char ssl_doc[] = ! "ssl(socket, keyfile, certfile) -> sslobject"; static PyObject * ! PySSL_server(PySSLObject *self, PyObject *args) { return PyString_FromString(self->server); --- 2650,2659 ---- static char ssl_doc[] = ! "ssl(socket, [keyfile, certfile]) -> sslobject"; ! ! /* SSL object methods */ static PyObject * ! PySSL_server(PySSLObject *self) { return PyString_FromString(self->server); *************** *** 2657,2661 **** static PyObject * ! PySSL_issuer(PySSLObject *self, PyObject *args) { return PyString_FromString(self->issuer); --- 2661,2665 ---- static PyObject * ! PySSL_issuer(PySSLObject *self) { return PyString_FromString(self->issuer); *************** *** 2663,2676 **** - /* SSL object methods */ - - static PyMethodDef PySSLMethods[] = { - {"write", (PyCFunction)PySSL_SSLwrite, 1}, - {"read", (PyCFunction)PySSL_SSLread, 1}, - {"server", (PyCFunction)PySSL_server, 1}, - {"issuer", (PyCFunction)PySSL_issuer, 1}, - {NULL, NULL} - }; - static void PySSL_dealloc(PySSLObject *self) { --- 2667,2670 ---- *************** *** 2685,2718 **** } - static PyObject *PySSL_getattr(PySSLObject *self, char *name) - { - return Py_FindMethod(PySSLMethods, (PyObject *)self, name); - } - - staticforward PyTypeObject PySSL_Type = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "SSL", /*tp_name*/ - sizeof(PySSLObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)PySSL_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc)PySSL_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - }; - - - static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args) { char *data; ! size_t len; if (!PyArg_ParseTuple(args, "s#:write", &data, &len)) --- 2679,2686 ---- } static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args) { char *data; ! int len; if (!PyArg_ParseTuple(args, "s#:write", &data, &len)) *************** *** 2720,2726 **** len = SSL_write(self->ssl, data, len); ! return PyInt_FromLong((long)len); } static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args) { --- 2688,2703 ---- len = SSL_write(self->ssl, data, len); ! if (len > 0) ! return PyInt_FromLong(len); ! else ! return PySSL_SetError(self->ssl, len); } + static char PySSL_SSLwrite_doc[] = + "write(s) -> len\n\ + \n\ + Writes the string s into the SSL object. Returns the number\n\ + of bytes written."; + static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args) { *************** *** 2728,2763 **** int count = 0; int len = 1024; - int res; ! PyArg_ParseTuple(args, "|i:read", &len); if (!(buf = PyString_FromStringAndSize((char *) 0, len))) ! return NULL; /* Error object should already be set */ count = SSL_read(self->ssl, PyString_AsString(buf), len); ! res = SSL_get_error(self->ssl, count); ! ! switch (res) { ! case SSL_ERROR_NONE: ! assert(count > 0); ! break; ! case SSL_ERROR_ZERO_RETURN: /* normal EOF */ ! assert(count == 0); ! break; ! default: ! return PyErr_SetFromErrno(PySSLErrorObject); ! } ! ! fflush(stderr); ! ! if (count < 0) { Py_DECREF(buf); ! return PyErr_SetFromErrno(PySSLErrorObject); } - if (count != len && _PyString_Resize(&buf, count) < 0) return NULL; return buf; } #endif /* USE_SSL */ --- 2705,2763 ---- int count = 0; int len = 1024; ! if (!PyArg_ParseTuple(args, "|i:read", &len)) ! return NULL; if (!(buf = PyString_FromStringAndSize((char *) 0, len))) ! return NULL; count = SSL_read(self->ssl, PyString_AsString(buf), len); ! if (count <= 0) { Py_DECREF(buf); ! return PySSL_SetError(self->ssl, count); } if (count != len && _PyString_Resize(&buf, count) < 0) return NULL; return buf; } + + static char PySSL_SSLread_doc[] = + "read([len]) -> string\n\ + \n\ + Read up to len bytes from the SSL socket."; + + static PyMethodDef PySSLMethods[] = { + {"write", (PyCFunction)PySSL_SSLwrite, 1, + PySSL_SSLwrite_doc}, + {"read", (PyCFunction)PySSL_SSLread, 1, + PySSL_SSLread_doc}, + {"server", (PyNoArgsFunction)PySSL_server, METH_NOARGS}, + {"issuer", (PyNoArgsFunction)PySSL_issuer, METH_NOARGS}, + {NULL, NULL} + }; + + static PyObject *PySSL_getattr(PySSLObject *self, char *name) + { + return Py_FindMethod(PySSLMethods, (PyObject *)self, name); + } + + staticforward PyTypeObject PySSL_Type = { + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "SSL", /*tp_name*/ + sizeof(PySSLObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)PySSL_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc)PySSL_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + }; #endif /* USE_SSL */ From jhylton@users.sourceforge.net Thu Oct 11 18:28:00 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 11 Oct 2001 10:28:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.177,1.178 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv2515 Modified Files: socketmodule.c Log Message: Use PySocket_Err() instead of PyErr_SetFromErrno(). The former does the right thing on Windows, the latter does not. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.177 retrieving revision 1.178 diff -C2 -d -r1.177 -r1.178 *** socketmodule.c 2001/10/11 17:23:34 1.177 --- socketmodule.c 2001/10/11 17:27:58 1.178 *************** *** 851,855 **** ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0'; if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) { ! PyErr_SetFromErrno(PySocket_Error); return 0; } --- 851,855 ---- ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0'; if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) { ! PySocket_Err(); return 0; } *************** *** 2531,2536 **** Py_DECREF(v); Py_DECREF(n); ! PyErr_SetFromErrno(PyExc_IOError); ! return NULL; } else { /* XXX Protected by global interpreter lock */ --- 2531,2535 ---- Py_DECREF(v); Py_DECREF(n); ! return PySocket_Err(); } else { /* XXX Protected by global interpreter lock */ From jhylton@users.sourceforge.net Thu Oct 11 18:47:24 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 11 Oct 2001 10:47:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib httplib.py,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv10232 Modified Files: httplib.py Log Message: Fix for SF buf #458835 Try to be systematic about dealing with socket and ssl exceptions in FakeSocket.makefile(). The previous version of the code caught all ssl errors and treated them as EOF, even though most of the errors don't mean EOF. An SSL error can mean on of three things: 1. The SSL/TLS connection was closed. 2. The operation should be retried. 3. An error occurred. Also, if a socket error occurred and the error was EINTR, retry the call. Otherwise, it was a legitimate error and the caller should receive the exception. Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** httplib.py 2001/10/07 08:53:32 1.40 --- httplib.py 2001/10/11 17:47:22 1.41 *************** *** 67,72 **** """ ! import socket import mimetools try: --- 67,73 ---- """ ! import errno import mimetools + import socket try: *************** *** 605,610 **** try: buf = self.__ssl.read() ! except socket.sslerror, msg: ! break if buf == '': break --- 606,621 ---- try: buf = self.__ssl.read() ! except socket.sslerror, err: ! if (err[0] == socket.SSL_ERROR_WANT_READ ! or err[0] == socket.SSL_ERROR_WANT_WRITE ! or 0): ! continue ! if err[0] == socket.SSL_ERROR_ZERO_RETURN: ! break ! raise ! except socket.error, err: ! if err[0] = errno.EINTR: ! continue ! raise if buf == '': break From tim_one@users.sourceforge.net Thu Oct 11 19:15:53 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 11 Oct 2001 11:15:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib httplib.py,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv19862 Modified Files: httplib.py Log Message: Somebody checked in a version of httplib that doesn't even compile -- SyntaxError. Fix it. Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** httplib.py 2001/10/11 17:47:22 1.41 --- httplib.py 2001/10/11 18:15:51 1.42 *************** *** 615,619 **** raise except socket.error, err: ! if err[0] = errno.EINTR: continue raise --- 615,619 ---- raise except socket.error, err: ! if err[0] == errno.EINTR: continue raise From tim_one@users.sourceforge.net Thu Oct 11 19:31:33 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 11 Oct 2001 11:31:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include objimpl.h,2.42,2.43 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv23954/python/Include Modified Files: objimpl.h Log Message: SF bug [#467145] Python 2.2a4 build problem on HPUX 11.0. The platform requires 8-byte alignment for doubles, but the GC header was 12 bytes and that threw off the natural alignment of the double members of a subtype of complex. The fix puts the GC header into a union with a double as the other member, to force no-looser-than double alignment of GC headers. On boxes that require 8-byte alignment for doubles, this may add pad bytes to the GC header accordingly; ditto for platforms that *prefer* 8-byte alignment for doubles. On platforms that don't care, it shouldn't change the memory layout (because the size of the old GC header is certainly greater than the size of a double on all platforms, so unioning with a double shouldn't change size or alignment on such boxes). Index: objimpl.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/objimpl.h,v retrieving revision 2.42 retrieving revision 2.43 diff -C2 -d -r2.42 -r2.43 *** objimpl.h 2001/10/07 03:54:51 2.42 --- objimpl.h 2001/10/11 18:31:31 2.43 *************** *** 267,274 **** /* GC information is stored BEFORE the object structure */ ! typedef struct _gc_head { ! struct _gc_head *gc_next; /* not NULL if object is tracked */ ! struct _gc_head *gc_prev; ! int gc_refs; } PyGC_Head; --- 267,277 ---- /* GC information is stored BEFORE the object structure */ ! typedef union _gc_head { ! struct { ! union _gc_head *gc_next; /* not NULL if object is tracked */ ! union _gc_head *gc_prev; ! int gc_refs; ! } gc; ! double dummy; /* force worst-case alignment */ } PyGC_Head; *************** *** 279,288 **** #define _PyObject_GC_TRACK(o) do { \ PyGC_Head *g = (PyGC_Head *)(o)-1; \ ! if (g->gc_next != NULL) \ Py_FatalError("GC object already in linked list"); \ ! g->gc_next = &_PyGC_generation0; \ ! g->gc_prev = _PyGC_generation0.gc_prev; \ ! g->gc_prev->gc_next = g; \ ! _PyGC_generation0.gc_prev = g; \ } while (0); --- 282,291 ---- #define _PyObject_GC_TRACK(o) do { \ PyGC_Head *g = (PyGC_Head *)(o)-1; \ ! if (g->gc.gc_next != NULL) \ Py_FatalError("GC object already in linked list"); \ ! g->gc.gc_next = &_PyGC_generation0; \ ! g->gc.gc_prev = _PyGC_generation0.gc.gc_prev; \ ! g->gc.gc_prev->gc.gc_next = g; \ ! _PyGC_generation0.gc.gc_prev = g; \ } while (0); *************** *** 290,296 **** #define _PyObject_GC_UNTRACK(o) do { \ PyGC_Head *g = (PyGC_Head *)(o)-1; \ ! g->gc_prev->gc_next = g->gc_next; \ ! g->gc_next->gc_prev = g->gc_prev; \ ! g->gc_next = NULL; \ } while (0); --- 293,299 ---- #define _PyObject_GC_UNTRACK(o) do { \ PyGC_Head *g = (PyGC_Head *)(o)-1; \ ! g->gc.gc_prev->gc.gc_next = g->gc.gc_next; \ ! g->gc.gc_next->gc.gc_prev = g->gc.gc_prev; \ ! g->gc.gc_next = NULL; \ } while (0); From tim_one@users.sourceforge.net Thu Oct 11 19:31:33 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 11 Oct 2001 11:31:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules gcmodule.c,2.23,2.24 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv23954/python/Modules Modified Files: gcmodule.c Log Message: SF bug [#467145] Python 2.2a4 build problem on HPUX 11.0. The platform requires 8-byte alignment for doubles, but the GC header was 12 bytes and that threw off the natural alignment of the double members of a subtype of complex. The fix puts the GC header into a union with a double as the other member, to force no-looser-than double alignment of GC headers. On boxes that require 8-byte alignment for doubles, this may add pad bytes to the GC header accordingly; ditto for platforms that *prefer* 8-byte alignment for doubles. On platforms that don't care, it shouldn't change the memory layout (because the size of the old GC header is certainly greater than the size of a double on all platforms, so unioning with a double shouldn't change size or alignment on such boxes). Index: gcmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/gcmodule.c,v retrieving revision 2.23 retrieving revision 2.24 diff -C2 -d -r2.23 -r2.24 *** gcmodule.c 2001/10/07 03:54:51 2.23 --- gcmodule.c 2001/10/11 18:31:31 2.24 *************** *** 78,83 **** gc_list_init(PyGC_Head *list) { ! list->gc_prev = list; ! list->gc_next = list; } --- 78,83 ---- gc_list_init(PyGC_Head *list) { ! list->gc.gc_prev = list; ! list->gc.gc_next = list; } *************** *** 85,92 **** gc_list_append(PyGC_Head *node, PyGC_Head *list) { ! node->gc_next = list; ! node->gc_prev = list->gc_prev; ! node->gc_prev->gc_next = node; ! list->gc_prev = node; } --- 85,92 ---- gc_list_append(PyGC_Head *node, PyGC_Head *list) { ! node->gc.gc_next = list; ! node->gc.gc_prev = list->gc.gc_prev; ! node->gc.gc_prev->gc.gc_next = node; ! list->gc.gc_prev = node; } *************** *** 94,100 **** gc_list_remove(PyGC_Head *node) { ! node->gc_prev->gc_next = node->gc_next; ! node->gc_next->gc_prev = node->gc_prev; ! node->gc_next = NULL; /* object is not currently tracked */ } --- 94,100 ---- gc_list_remove(PyGC_Head *node) { ! node->gc.gc_prev->gc.gc_next = node->gc.gc_next; ! node->gc.gc_next->gc.gc_prev = node->gc.gc_prev; ! node->gc.gc_next = NULL; /* object is not currently tracked */ } *************** *** 102,114 **** gc_list_move(PyGC_Head *from, PyGC_Head *to) { ! if (from->gc_next == from) { /* empty from list */ gc_list_init(to); } else { ! to->gc_next = from->gc_next; ! to->gc_next->gc_prev = to; ! to->gc_prev = from->gc_prev; ! to->gc_prev->gc_next = to; } gc_list_init(from); --- 102,114 ---- gc_list_move(PyGC_Head *from, PyGC_Head *to) { ! if (from->gc.gc_next == from) { /* empty from list */ gc_list_init(to); } else { ! to->gc.gc_next = from->gc.gc_next; ! to->gc.gc_next->gc.gc_prev = to; ! to->gc.gc_prev = from->gc.gc_prev; ! to->gc.gc_prev->gc.gc_next = to; } gc_list_init(from); *************** *** 120,129 **** { PyGC_Head *tail; ! if (from->gc_next != from) { ! tail = to->gc_prev; ! tail->gc_next = from->gc_next; ! tail->gc_next->gc_prev = tail; ! to->gc_prev = from->gc_prev; ! to->gc_prev->gc_next = to; } gc_list_init(from); --- 120,129 ---- { PyGC_Head *tail; ! if (from->gc.gc_next != from) { ! tail = to->gc.gc_prev; ! tail->gc.gc_next = from->gc.gc_next; ! tail->gc.gc_next->gc.gc_prev = tail; ! to->gc.gc_prev = from->gc.gc_prev; ! to->gc.gc_prev->gc.gc_next = to; } gc_list_init(from); *************** *** 135,139 **** PyGC_Head *gc; long n = 0; ! for (gc = list->gc_next; gc != list; gc = gc->gc_next) { n++; } --- 135,139 ---- PyGC_Head *gc; long n = 0; ! for (gc = list->gc.gc_next; gc != list; gc = gc->gc.gc_next) { n++; } *************** *** 149,155 **** update_refs(PyGC_Head *containers) { ! PyGC_Head *gc = containers->gc_next; ! for (; gc != containers; gc=gc->gc_next) { ! gc->gc_refs = FROM_GC(gc)->ob_refcnt; } } --- 149,155 ---- update_refs(PyGC_Head *containers) { ! PyGC_Head *gc = containers->gc.gc_next; ! for (; gc != containers; gc=gc->gc.gc_next) { ! gc->gc.gc_refs = FROM_GC(gc)->ob_refcnt; } } *************** *** 160,165 **** if (op && PyObject_IS_GC(op)) { PyGC_Head *gc = AS_GC(op); ! if (gc->gc_next != NULL) ! AS_GC(op)->gc_refs--; } return 0; --- 160,165 ---- if (op && PyObject_IS_GC(op)) { PyGC_Head *gc = AS_GC(op); ! if (gc->gc.gc_next != NULL) ! AS_GC(op)->gc.gc_refs--; } return 0; *************** *** 171,176 **** { traverseproc traverse; ! PyGC_Head *gc = containers->gc_next; ! for (; gc != containers; gc=gc->gc_next) { traverse = FROM_GC(gc)->ob_type->tp_traverse; (void) traverse(FROM_GC(gc), --- 171,176 ---- { traverseproc traverse; ! PyGC_Head *gc = containers->gc.gc_next; ! for (; gc != containers; gc=gc->gc.gc_next) { traverse = FROM_GC(gc)->ob_type->tp_traverse; (void) traverse(FROM_GC(gc), *************** *** 185,195 **** { PyGC_Head *next; ! PyGC_Head *gc = containers->gc_next; while (gc != containers) { ! next = gc->gc_next; ! if (gc->gc_refs > 0) { gc_list_remove(gc); gc_list_append(gc, roots); ! gc->gc_refs = GC_MOVED; } gc = next; --- 185,195 ---- { PyGC_Head *next; ! PyGC_Head *gc = containers->gc.gc_next; while (gc != containers) { ! next = gc->gc.gc_next; ! if (gc->gc.gc_refs > 0) { gc_list_remove(gc); gc_list_append(gc, roots); ! gc->gc.gc_refs = GC_MOVED; } gc = next; *************** *** 202,209 **** if (PyObject_IS_GC(op)) { PyGC_Head *gc = AS_GC(op); ! if (gc->gc_next != NULL && gc->gc_refs != GC_MOVED) { gc_list_remove(gc); gc_list_append(gc, tolist); ! gc->gc_refs = GC_MOVED; } } --- 202,209 ---- if (PyObject_IS_GC(op)) { PyGC_Head *gc = AS_GC(op); ! if (gc->gc.gc_next != NULL && gc->gc.gc_refs != GC_MOVED) { gc_list_remove(gc); gc_list_append(gc, tolist); ! gc->gc.gc_refs = GC_MOVED; } } *************** *** 216,221 **** { traverseproc traverse; ! PyGC_Head *gc = reachable->gc_next; ! for (; gc != reachable; gc=gc->gc_next) { /* careful, reachable list is growing here */ PyObject *op = FROM_GC(gc); --- 216,221 ---- { traverseproc traverse; ! PyGC_Head *gc = reachable->gc.gc_next; ! for (; gc != reachable; gc=gc->gc.gc_next) { /* careful, reachable list is growing here */ PyObject *op = FROM_GC(gc); *************** *** 232,236 **** { PyGC_Head *next; ! PyGC_Head *gc = unreachable->gc_next; static PyObject *delstr = NULL; if (delstr == NULL) { --- 232,236 ---- { PyGC_Head *next; ! PyGC_Head *gc = unreachable->gc.gc_next; static PyObject *delstr = NULL; if (delstr == NULL) { *************** *** 241,245 **** for (; gc != unreachable; gc=next) { PyObject *op = FROM_GC(gc); ! next = gc->gc_next; if (PyInstance_Check(op) && PyObject_HasAttr(op, delstr)) { gc_list_remove(gc); --- 241,245 ---- for (; gc != unreachable; gc=next) { PyObject *op = FROM_GC(gc); ! next = gc->gc.gc_next; if (PyInstance_Check(op) && PyObject_HasAttr(op, delstr)) { gc_list_remove(gc); *************** *** 254,259 **** { traverseproc traverse; ! PyGC_Head *gc = finalizers->gc_next; ! for (; gc != finalizers; gc=gc->gc_next) { /* careful, finalizers list is growing here */ traverse = FROM_GC(gc)->ob_type->tp_traverse; --- 254,259 ---- { traverseproc traverse; ! PyGC_Head *gc = finalizers->gc.gc_next; ! for (; gc != finalizers; gc=gc->gc.gc_next) { /* careful, finalizers list is growing here */ traverse = FROM_GC(gc)->ob_type->tp_traverse; *************** *** 298,303 **** garbage = PyList_New(0); } ! for (gc = finalizers->gc_next; gc != finalizers; ! gc = finalizers->gc_next) { PyObject *op = FROM_GC(gc); if ((debug & DEBUG_SAVEALL) || PyInstance_Check(op)) { --- 298,303 ---- garbage = PyList_New(0); } ! for (gc = finalizers->gc.gc_next; gc != finalizers; ! gc = finalizers->gc.gc_next) { PyObject *op = FROM_GC(gc); if ((debug & DEBUG_SAVEALL) || PyInstance_Check(op)) { *************** *** 322,327 **** inquiry clear; ! while (unreachable->gc_next != unreachable) { ! PyGC_Head *gc = unreachable->gc_next; PyObject *op = FROM_GC(gc); if (debug & DEBUG_SAVEALL) { --- 322,327 ---- inquiry clear; ! while (unreachable->gc.gc_next != unreachable) { ! PyGC_Head *gc = unreachable->gc.gc_next; PyObject *op = FROM_GC(gc); if (debug & DEBUG_SAVEALL) { *************** *** 335,339 **** } } ! if (unreachable->gc_next == gc) { /* object is still alive, move it, it may die later */ gc_list_remove(gc); --- 335,339 ---- } } ! if (unreachable->gc.gc_next == gc) { /* object is still alive, move it, it may die later */ gc_list_remove(gc); *************** *** 397,402 **** /* Collect statistics on collectable objects found and print * debugging information. */ ! for (gc = unreachable.gc_next; gc != &unreachable; ! gc = gc->gc_next) { m++; if (debug & DEBUG_COLLECTABLE) { --- 397,402 ---- /* Collect statistics on collectable objects found and print * debugging information. */ ! for (gc = unreachable.gc.gc_next; gc != &unreachable; ! gc = gc->gc.gc_next) { m++; if (debug & DEBUG_COLLECTABLE) { *************** *** 411,416 **** /* Collect statistics on uncollectable objects found and print * debugging information. */ ! for (gc = finalizers.gc_next; gc != &finalizers; ! gc = gc->gc_next) { n++; if (debug & DEBUG_UNCOLLECTABLE) { --- 411,416 ---- /* Collect statistics on uncollectable objects found and print * debugging information. */ ! for (gc = finalizers.gc.gc_next; gc != &finalizers; ! gc = gc->gc.gc_next) { n++; if (debug & DEBUG_UNCOLLECTABLE) { *************** *** 457,461 **** gc_list_merge(&_PyGC_generation0, &generation2); gc_list_merge(&generation1, &generation2); ! if (generation2.gc_next != &generation2) { n = collect(&generation2, &generation2); } --- 457,461 ---- gc_list_merge(&_PyGC_generation0, &generation2); gc_list_merge(&generation1, &generation2); ! if (generation2.gc.gc_next != &generation2) { n = collect(&generation2, &generation2); } *************** *** 466,470 **** collections1++; gc_list_merge(&_PyGC_generation0, &generation1); ! if (generation1.gc_next != &generation1) { n = collect(&generation1, &generation2); } --- 466,470 ---- collections1++; gc_list_merge(&_PyGC_generation0, &generation1); ! if (generation1.gc.gc_next != &generation1) { n = collect(&generation1, &generation2); } *************** *** 474,478 **** generation = 0; collections0++; ! if (_PyGC_generation0.gc_next != &_PyGC_generation0) { n = collect(&_PyGC_generation0, &generation1); } --- 474,478 ---- generation = 0; collections0++; ! if (_PyGC_generation0.gc.gc_next != &_PyGC_generation0) { n = collect(&_PyGC_generation0, &generation1); } *************** *** 647,651 **** PyObject *obj; traverseproc traverse; ! for (gc = list->gc_next; gc != list; gc = gc->gc_next) { obj = FROM_GC(gc); traverse = obj->ob_type->tp_traverse; --- 647,651 ---- PyObject *obj; traverseproc traverse; ! for (gc = list->gc.gc_next; gc != list; gc = gc->gc.gc_next) { obj = FROM_GC(gc); traverse = obj->ob_type->tp_traverse; *************** *** 689,693 **** { PyGC_Head *gc; ! for (gc = gc_list->gc_next; gc != gc_list; gc = gc->gc_next) { PyObject *op = FROM_GC(gc); if (op != py_list) { --- 689,693 ---- { PyGC_Head *gc; ! for (gc = gc_list->gc.gc_next; gc != gc_list; gc = gc->gc.gc_next) { PyObject *op = FROM_GC(gc); if (op != py_list) { *************** *** 808,812 **** if (g == NULL) return (PyObject *)PyErr_NoMemory(); ! g->gc_next = NULL; allocated++; if (allocated > threshold0 && --- 808,812 ---- if (g == NULL) return (PyObject *)PyErr_NoMemory(); ! g->gc.gc_next = NULL; allocated++; if (allocated > threshold0 && *************** *** 867,871 **** #ifdef WITH_CYCLE_GC PyGC_Head *g = AS_GC(op); ! if (g->gc_next != NULL) gc_list_remove(g); if (allocated > 0) { --- 867,871 ---- #ifdef WITH_CYCLE_GC PyGC_Head *g = AS_GC(op); ! if (g->gc.gc_next != NULL) gc_list_remove(g); if (allocated > 0) { From gvanrossum@users.sourceforge.net Thu Oct 11 19:33:55 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 11 Oct 2001 11:33:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.98,2.99 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv25854/Objects Modified Files: typeobject.c Log Message: Another step in the right direction: when a new class's attribute corresponding to a dispatch slot (e.g. __getitem__ or __add__) is set, calculate the proper dispatch slot and propagate the change to all subclasses. Because of multiple inheritance, there's no easy way to avoid always recursing down the tree of subclasses. Who cares? (There's more to do, but this works. There's also a test for this now.) Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.98 retrieving revision 2.99 diff -C2 -d -r2.98 -r2.99 *** typeobject.c 2001/10/09 20:17:57 2.98 --- typeobject.c 2001/10/11 18:33:53 2.99 *************** *** 677,681 **** staticforward void object_dealloc(PyObject *); staticforward int object_init(PyObject *, PyObject *, PyObject *); ! staticforward int update_slot(PyTypeObject *, PyObject *, PyObject *); staticforward void fixup_slot_dispatchers(PyTypeObject *); --- 677,681 ---- staticforward void object_dealloc(PyObject *); staticforward int object_init(PyObject *, PyObject *, PyObject *); ! staticforward int update_slot(PyTypeObject *, PyObject *); staticforward void fixup_slot_dispatchers(PyTypeObject *); *************** *** 1108,1112 **** if (PyObject_GenericSetAttr((PyObject *)type, name, value) < 0) return -1; ! return update_slot(type, name, value); } PyErr_SetString(PyExc_TypeError, "can't set static type attributes"); --- 1108,1112 ---- if (PyObject_GenericSetAttr((PyObject *)type, name, value) < 0) return -1; ! return update_slot(type, name); } PyErr_SetString(PyExc_TypeError, "can't set static type attributes"); *************** *** 3680,3683 **** --- 3680,3684 ---- void *function; wrapperfunc wrapper; + PyObject *name_strobj; } slotdef; *************** *** 3798,3804 **** TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc), - TPSLOT("__str__", tp_print, NULL, NULL), TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc), - TPSLOT("__repr__", tp_print, NULL, NULL), TPSLOT("__cmp__", tp_compare, _PyObject_SlotCompare, wrap_cmpfunc), TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc), --- 3799,3803 ---- *************** *** 3828,3860 **** }; - static int - update_slot(PyTypeObject *type, PyObject *name, PyObject *value) - { - char *s; - int n; - slotdef *p; - void **ptr; - - assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE); - if (value == NULL) - return 0; /* Can't unset a slot */ - s = PyString_AsString(name); - n = PyString_Size(name); - if (s == NULL || n < 0) { - /* Shouldn't happen, but can't be bothered */ - PyErr_Clear(); - return 0; - } - if (!(s[0] == '_' && s[1] == '_' && s[n-1] == '_' && s[n-2] == '_')) - return 0; - for (p = slotdefs; p->name; p++) { - if (!strcmp(p->name, s)) { - ptr = (void **) ((char *)type + p->offset); - *ptr = p->function; - } - } - return 0; - } - static void ** slotptr(PyTypeObject *type, int offset) --- 3827,3830 ---- *************** *** 3882,3885 **** --- 3852,3968 ---- ptr += offset; return (void **)ptr; + } + + staticforward int recurse_down_subclasses(PyTypeObject *type, int offset); + + static int + update_one_slot(PyTypeObject *type, int offset) + { + slotdef *p; + PyObject *descr; + PyWrapperDescrObject *d; + void *generic = NULL, *specific = NULL; + int use_generic = 0; + void **ptr; + + for (p = slotdefs; p->name; p++) { + if (p->offset != offset) + continue; + descr = _PyType_Lookup(type, p->name_strobj); + if (descr == NULL) + continue; + ptr = slotptr(type, p->offset); + if (ptr == NULL) + continue; + generic = p->function; + if (descr->ob_type == &PyWrapperDescr_Type) { + d = (PyWrapperDescrObject *)descr; + if (d->d_base->wrapper == p->wrapper && + PyType_IsSubtype(type, d->d_type)) { + if (specific == NULL || + specific == d->d_wrapped) + specific = d->d_wrapped; + else + use_generic = 1; + } + } + else + use_generic = 1; + if (specific && !use_generic) + *ptr = specific; + else + *ptr = generic; + } + if (recurse_down_subclasses(type, offset) < 0) + return -1; + return 0; + } + + static int + recurse_down_subclasses(PyTypeObject *type, int offset) + { + PyTypeObject *subclass; + PyObject *ref, *subclasses; + int i, n; + + subclasses = type->tp_subclasses; + if (subclasses == NULL) + return 0; + assert(PyList_Check(subclasses)); + n = PyList_GET_SIZE(subclasses); + for (i = 0; i < n; i++) { + ref = PyList_GET_ITEM(subclasses, i); + assert(PyWeakref_CheckRef(ref)); + subclass = (PyTypeObject *)PyWeakref_GET_OBJECT(ref); + if (subclass == NULL) + continue; + assert(PyType_Check(subclass)); + if (update_one_slot(subclass, offset) < 0) + return -1; + } + return 0; + } + + static void + init_name_strobj(void) + { + slotdef *p; + static int initialized = 0; + + if (initialized) + return; + for (p = slotdefs; p->name; p++) { + p->name_strobj = PyString_InternFromString(p->name); + if (!p->name_strobj) + Py_FatalError("XXX ouch"); + } + initialized = 1; + } + + static void + collect_offsets(PyObject *name, int offsets[]) + { + slotdef *p; + + init_name_strobj(); + for (p = slotdefs; p->name; p++) { + if (name == p->name_strobj) + *offsets++ = p->offset; + } + *offsets = 0; + } + + static int + update_slot(PyTypeObject *type, PyObject *name) + { + int offsets[10]; + int *ip; + + collect_offsets(name, offsets); + for (ip = offsets; *ip; ip++) { + if (update_one_slot(type, *ip) < 0) + return -1; + } + return 0; } From gvanrossum@users.sourceforge.net Thu Oct 11 19:33:56 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 11 Oct 2001 11:33:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.86,1.87 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv25854/Lib/test Modified Files: test_descr.py Log Message: Another step in the right direction: when a new class's attribute corresponding to a dispatch slot (e.g. __getitem__ or __add__) is set, calculate the proper dispatch slot and propagate the change to all subclasses. Because of multiple inheritance, there's no easy way to avoid always recursing down the tree of subclasses. Who cares? (There's more to do, but this works. There's also a test for this now.) Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.86 retrieving revision 1.87 diff -C2 -d -r1.86 -r1.87 *** test_descr.py 2001/10/09 20:36:44 1.86 --- test_descr.py 2001/10/11 18:33:53 1.87 *************** *** 8,11 **** --- 8,15 ---- raise TestFailed, "%r == %r" % (a, b) + def veris(a, b): + if a is not b: + raise TestFailed, "%r is %r" % (a, b) + def testunop(a, res, expr="len(a)", meth="__len__"): if verbose: print "checking", expr *************** *** 624,631 **** # Automatically add __super to the class # This trick only works for dynamic classes - # so we force __dynamic__ = 1 def __new__(metaclass, name, bases, dict): ! # XXX Should check that name isn't already a base class name ! dict["__dynamic__"] = 1 cls = super(autosuper, metaclass).__new__(metaclass, name, bases, dict) --- 628,633 ---- # Automatically add __super to the class # This trick only works for dynamic classes def __new__(metaclass, name, bases, dict): ! assert dict.get("__dynamic__", 1) cls = super(autosuper, metaclass).__new__(metaclass, name, bases, dict) *************** *** 950,954 **** # Test handling of int*seq and seq*int class I(int): ! __dynamic__ = 1 vereq("a"*I(2), "aa") vereq(I(2)*"a", "aa") --- 952,956 ---- # Test handling of int*seq and seq*int class I(int): ! __dynamic__ = 1 # XXX why? vereq("a"*I(2), "aa") vereq(I(2)*"a", "aa") *************** *** 959,963 **** # Test handling of long*seq and seq*long class L(long): ! __dynamic__ = 1 vereq("a"*L(2L), "aa") vereq(L(2L)*"a", "aa") --- 961,965 ---- # Test handling of long*seq and seq*long class L(long): ! __dynamic__ = 1 # XXX why? vereq("a"*L(2L), "aa") vereq(L(2L)*"a", "aa") *************** *** 968,972 **** # Test comparison of classes with dynamic metaclasses class dynamicmetaclass(type): ! __dynamic__ = 1 class someclass: __metaclass__ = dynamicmetaclass --- 970,974 ---- # Test comparison of classes with dynamic metaclasses class dynamicmetaclass(type): ! __dynamic__ = 1 # XXX ??? class someclass: __metaclass__ = dynamicmetaclass *************** *** 1254,1258 **** # Test the default behavior for dynamic classes class D(object): ! __dynamic__ = 1 def __getitem__(self, i): if 0 <= i < 10: return i --- 1256,1260 ---- # Test the default behavior for dynamic classes class D(object): ! __dynamic__ = 1 # XXX why? def __getitem__(self, i): if 0 <= i < 10: return i *************** *** 1564,1568 **** class madcomplex(complex): ! __dynamic__ = 0 def __repr__(self): return "%.17gj%+.17g" % (self.imag, self.real) --- 1566,1570 ---- class madcomplex(complex): ! __dynamic__ = 0 # XXX Shouldn't be necessary def __repr__(self): return "%.17gj%+.17g" % (self.imag, self.real) *************** *** 1570,1591 **** vereq(repr(a), "4j-3") base = complex(-3, 4) ! verify(base.__class__ is complex) vereq(a, base) vereq(complex(a), base) ! verify(complex(a).__class__ is complex) a = madcomplex(a) # just trying another form of the constructor vereq(repr(a), "4j-3") vereq(a, base) vereq(complex(a), base) ! verify(complex(a).__class__ is complex) vereq(hash(a), hash(base)) ! verify((+a).__class__ is complex) ! verify((a + 0).__class__ is complex) vereq(a + 0, base) ! verify((a - 0).__class__ is complex) vereq(a - 0, base) ! verify((a * 1).__class__ is complex) vereq(a * 1, base) ! verify((a / 1).__class__ is complex) vereq(a / 1, base) --- 1572,1593 ---- vereq(repr(a), "4j-3") base = complex(-3, 4) ! veris(base.__class__, complex) vereq(a, base) vereq(complex(a), base) ! veris(complex(a).__class__, complex) a = madcomplex(a) # just trying another form of the constructor vereq(repr(a), "4j-3") vereq(a, base) vereq(complex(a), base) ! veris(complex(a).__class__, complex) vereq(hash(a), hash(base)) ! veris((+a).__class__, complex) ! veris((a + 0).__class__, complex) vereq(a + 0, base) ! veris((a - 0).__class__, complex) vereq(a - 0, base) ! veris((a * 1).__class__, complex) vereq(a * 1, base) ! veris((a / 1).__class__, complex) vereq(a / 1, base) *************** *** 2238,2241 **** --- 2240,2303 ---- return self.lower() == other.lower() + def subclasspropagation(): + if verbose: print "Testing propagation of slot functions to subclasses..." + class A(object): + pass + class B(A): + pass + class C(A): + pass + class D(B, C): + pass + d = D() + vereq(hash(d), id(d)) + A.__hash__ = lambda self: 42 + vereq(hash(d), 42) + C.__hash__ = lambda self: 314 + vereq(hash(d), 314) + B.__hash__ = lambda self: 144 + vereq(hash(d), 144) + D.__hash__ = lambda self: 100 + vereq(hash(d), 100) + del D.__hash__ + vereq(hash(d), 144) + del B.__hash__ + vereq(hash(d), 314) + del C.__hash__ + vereq(hash(d), 42) + del A.__hash__ + vereq(hash(d), id(d)) + d.foo = 42 + d.bar = 42 + vereq(d.foo, 42) + vereq(d.bar, 42) + def __getattribute__(self, name): + if name == "foo": + return 24 + return object.__getattribute__(self, name) + A.__getattribute__ = __getattribute__ + vereq(d.foo, 24) + vereq(d.bar, 42) + def __getattr__(self, name): + if name in ("spam", "foo", "bar"): + return "hello" + raise AttributeError, name + B.__getattr__ = __getattr__ + vereq(d.spam, "hello") + vereq(d.foo, 24) + vereq(d.bar, 42) + del A.__getattribute__ + vereq(d.foo, 42) + del d.foo + vereq(d.foo, "hello") + vereq(d.bar, 42) + del B.__getattr__ + try: + d.foo + except AttributeError: + pass + else: + raise TestFailed, "d.foo should be undefined now" + def test_main(): *************** *** 2285,2288 **** --- 2347,2351 ---- copies() binopoverride() + subclasspropagation() if verbose: print "All OK" From loewis@users.sourceforge.net Thu Oct 11 20:23:30 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 11 Oct 2001 12:23:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/rpc README,1.5,1.6 mountclient.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Demo/rpc In directory usw-pr-cvs1:/tmp/cvs-serv13285 Modified Files: README mountclient.py Log Message: Patch #469517: Info about rpcgen compilers. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/rpc/README,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** README 1996/08/19 22:24:21 1.5 --- README 2001/10/11 19:23:28 1.6 *************** *** 24,25 **** --- 24,31 ---- For hostname, use e.g. wuarchive.wustl.edu or gatekeeper.dec.com (two hosts that are known to export NFS filesystems with little restrictions). + + There are now two different RPC compilers: + + 1) Wim Lewis rpcgen.py found on http://www.omnigroup.com/~wiml/soft/stale-index.html#python. + + 2) Peter Åstrands rpcgen.py, which is part of "pynfs" (http://www.cendio.se/~peter/pynfs/). Index: mountclient.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/rpc/mountclient.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** mountclient.py 1993/12/17 14:32:26 1.7 --- mountclient.py 2001/10/11 19:23:28 1.8 *************** *** 2,10 **** # This module demonstrates how to write your own RPC client in Python. ! # Since there is no RPC compiler for Python (yet), you must first ! # create classes derived from Packer and Unpacker to handle the data ! # types for the server you want to interface to. You then write the ! # client class. If you want to support both the TCP and the UDP ! # version of a protocol, use multiple inheritance as shown below. --- 2,11 ---- # This module demonstrates how to write your own RPC client in Python. ! # When this example was written, there was no RPC compiler for ! # Python. Without such a compiler, you must first create classes ! # derived from Packer and Unpacker to handle the data types for the ! # server you want to interface to. You then write the client class. ! # If you want to support both the TCP and the UDP version of a ! # protocol, use multiple inheritance as shown below. From tim_one@users.sourceforge.net Fri Oct 12 03:38:27 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 11 Oct 2001 19:38:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.99,2.100 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9055/python/Objects Modified Files: typeobject.c Log Message: SF bug [#470040] ParseTuple t# vs subclasses. inherit_slots(): tp_as_buffer was getting inherited as if it were a method pointer, rather than a pointer to a vector of method pointers. As a result, inheriting from a type that implemented buffer methods was ineffective, leaving all the tp_as_buffer slots NULL in the subclass. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.99 retrieving revision 2.100 diff -C2 -d -r2.99 -r2.100 *** typeobject.c 2001/10/11 18:33:53 2.99 --- typeobject.c 2001/10/12 02:38:24 2.100 *************** *** 1658,1661 **** --- 1658,1662 ---- #define COPYSEQ(SLOT) COPYSLOT(tp_as_sequence->SLOT) #define COPYMAP(SLOT) COPYSLOT(tp_as_mapping->SLOT) + #define COPYBUF(SLOT) COPYSLOT(tp_as_buffer->SLOT) /* This won't inherit indirect slots (from tp_as_number etc.) *************** *** 1733,1736 **** --- 1734,1747 ---- } + if (type->tp_as_buffer != NULL && base->tp_as_buffer != NULL) { + basebase = base->tp_base; + if (basebase->tp_as_buffer == NULL) + basebase = NULL; + COPYBUF(bf_getreadbuffer); + COPYBUF(bf_getwritebuffer); + COPYBUF(bf_getsegcount); + COPYBUF(bf_getcharbuffer); + } + basebase = base->tp_base; *************** *** 1750,1754 **** COPYSLOT(tp_call); COPYSLOT(tp_str); - COPYSLOT(tp_as_buffer); if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE) { if (type->tp_compare == NULL && --- 1761,1764 ---- From tim_one@users.sourceforge.net Fri Oct 12 03:38:27 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 11 Oct 2001 19:38:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.87,1.88 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv9055/python/Lib/test Modified Files: test_descr.py Log Message: SF bug [#470040] ParseTuple t# vs subclasses. inherit_slots(): tp_as_buffer was getting inherited as if it were a method pointer, rather than a pointer to a vector of method pointers. As a result, inheriting from a type that implemented buffer methods was ineffective, leaving all the tp_as_buffer slots NULL in the subclass. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.87 retrieving revision 1.88 diff -C2 -d -r1.87 -r1.88 *** test_descr.py 2001/10/11 18:33:53 1.87 --- test_descr.py 2001/10/12 02:38:24 1.88 *************** *** 2299,2304 **** else: raise TestFailed, "d.foo should be undefined now" - def test_main(): class_docstrings() --- 2299,2334 ---- else: raise TestFailed, "d.foo should be undefined now" + def buffer_inherit(): + import binascii + # SF bug [#470040] ParseTuple t# vs subclasses. + if verbose: + print "Testing that buffer interface is inherited ..." + + class MyStr(str): + pass + base = 'abc' + m = MyStr(base) + # b2a_hex uses the buffer interface to get its argument's value, via + # PyArg_ParseTuple 't#' code. + vereq(binascii.b2a_hex(m), binascii.b2a_hex(base)) + + # It's not clear that unicode will continue to support the character + # buffer interface, and this test will fail if that's taken away. + class MyUni(unicode): + pass + base = u'abc' + m = MyUni(base) + vereq(binascii.b2a_hex(m), binascii.b2a_hex(base)) + + class MyInt(int): + pass + m = MyInt(42) + try: + binascii.b2a_hex(m) + raise TestFailed('subclass of int should not have a buffer interface') + except TypeError: + pass + def test_main(): class_docstrings() *************** *** 2348,2351 **** --- 2378,2382 ---- binopoverride() subclasspropagation() + buffer_inherit() if verbose: print "All OK" From jhylton@users.sourceforge.net Fri Oct 12 05:11:09 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 11 Oct 2001 21:11:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules cPickle.c,2.64,2.65 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv2442 Modified Files: cPickle.c Log Message: Progress on SF bug #466175 and general cleanup. Add a fast_container member to Picklerobject. If fast is true, then fast_container counts the depth of nested container calls. If the depth exceeds FAST_LIMIT (2000), the fast flag is ignored and the normal checks occur. This approach is much like the approach for prevent stack overflow for comparison and reprs of recursive objects (e.g. [[...]]). - Fast container used for save_list(), save_dict(), and save_inst(). XXX Not clear which other save_xxx() functions should use it. Make Picklerobject into new-style types, using PyObject_GenericGetAttr() and PyObject_GenericSetAttr(). - Use PyMemberDef for binary and fast members - Use PyGetSetDef for persistent_id, inst_persistent_id, memo, and PicklingError. XXX Not all of these seem like they need to use getset, but it's not clear why the old getattr() and setattr() had such odd semantics. One change is that the getvalue() attribute will exist on all Picklers, not just list-based picklers; I think this is a more rationale interface. There is a long laundry list of other changes: - Remove unused #defines for PyList_SET_ITEM() etc. - Make some of the indentation consistent - Replace uses of cPickle_PyMapping_HasKey() where the first argument is self->memo with calls to PyDict_GetItem(), because self->memo must be a dictionary. - Don't bother to check if cPickle_PyMapping_HasKey() returns < 0, because it can only return 0 or 1. - Replace uses of PyObject_CallObject() with PyObject_Call(), when we can guarantee that the argument tuple is really a tuple. Performance impacts of these changes: - 5% speedup for normal pickling - No change to fast-mode pickling. XXX Really need tests for all the features in cPickle that aren't in pickle. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.64 retrieving revision 2.65 diff -C2 -d -r2.64 -r2.65 *** cPickle.c 2001/08/28 22:08:34 2.64 --- cPickle.c 2001/10/12 04:11:06 2.65 *************** *** 55,58 **** --- 55,59 ---- #include "Python.h" #include "cStringIO.h" + #include "structmember.h" #ifndef Py_eval_input *************** *** 145,164 **** *copy_reg_str, *dispatch_table_str, *safe_constructors_str; - #ifndef PyList_SET_ITEM - #define PyList_SET_ITEM(op, i, v) (((PyListObject *)(op))->ob_item[i] = (v)) - #endif - #ifndef PyList_GET_SIZE - #define PyList_GET_SIZE(op) (((PyListObject *)(op))->ob_size) - #endif - #ifndef PyTuple_SET_ITEM - #define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = (v)) - #endif - #ifndef PyTuple_GET_SIZE - #define PyTuple_GET_SIZE(op) (((PyTupleObject *)(op))->ob_size) - #endif - #ifndef PyString_GET_SIZE - #define PyString_GET_SIZE(op) (((PyStringObject *)(op))->ob_size) - #endif - /************************************************************************* Internal Data type for pickle data. */ --- 146,149 ---- *************** *** 319,338 **** typedef struct Picklerobject { ! PyObject_HEAD ! FILE *fp; ! PyObject *write; ! PyObject *file; ! PyObject *memo; ! PyObject *arg; ! PyObject *pers_func; ! PyObject *inst_pers_func; ! int bin; ! int fast; /* Fast mode doesn't save in memo, don't use if circ ref */ ! int (*write_func)(struct Picklerobject *, char *, int); ! char *write_buf; ! int buf_size; ! PyObject *dispatch_table; } Picklerobject; staticforward PyTypeObject Picklertype; --- 304,326 ---- typedef struct Picklerobject { ! PyObject_HEAD ! FILE *fp; ! PyObject *write; ! PyObject *file; ! PyObject *memo; ! PyObject *arg; ! PyObject *pers_func; ! PyObject *inst_pers_func; ! int bin; ! int fast; /* Fast mode doesn't save in memo, don't use if circ ref */ ! int (*write_func)(struct Picklerobject *, char *, int); ! char *write_buf; ! int buf_size; ! PyObject *dispatch_table; ! int fast_container; /* count nested container dumps */ } Picklerobject; + #define FAST_LIMIT 2000 + staticforward PyTypeObject Picklertype; *************** *** 483,487 **** ARG_TUP(self, py_str); if (self->arg) { ! junk = PyObject_CallObject(self->write, self->arg); FREE_ARG_TUP(self); } --- 471,475 ---- ARG_TUP(self, py_str); if (self->arg) { ! junk = PyObject_Call(self->write, self->arg, NULL); FREE_ARG_TUP(self); } *************** *** 613,617 **** ARG_TUP(self, bytes); if (self->arg) { ! str = PyObject_CallObject(self->read, self->arg); FREE_ARG_TUP(self); } --- 601,605 ---- ARG_TUP(self, bytes); if (self->arg) { ! str = PyObject_Call(self->read, self->arg, NULL); FREE_ARG_TUP(self); } *************** *** 714,718 **** static int put(Picklerobject *self, PyObject *ob) { ! if (ob->ob_refcnt < 2 || self->fast) return 0; --- 702,706 ---- static int put(Picklerobject *self, PyObject *ob) { ! if (ob->ob_refcnt < 2 || self->fast) return 0; *************** *** 729,733 **** PyObject *py_ob_id = 0, *memo_len = 0, *t = 0; ! if (self->fast) return 0; if ((p = PyDict_Size(self->memo)) < 0) --- 717,722 ---- PyObject *py_ob_id = 0, *memo_len = 0, *t = 0; ! if (self->fast) ! return 0; if ((p = PyDict_Size(self->memo)) < 0) *************** *** 1297,1301 **** save_tuple(Picklerobject *self, PyObject *args) { PyObject *element = 0, *py_tuple_id = 0; ! int len, i, has_key, res = -1; static char tuple = TUPLE; --- 1286,1290 ---- save_tuple(Picklerobject *self, PyObject *args) { PyObject *element = 0, *py_tuple_id = 0; ! int len, i, res = -1; static char tuple = TUPLE; *************** *** 1319,1326 **** if (len) { ! if ((has_key = cPickle_PyMapping_HasKey(self->memo, py_tuple_id)) < 0) ! goto finally; ! ! if (has_key) { if (self->bin) { static char pop_mark = POP_MARK; --- 1308,1312 ---- if (len) { ! if (PyDict_GetItem(self->memo, py_tuple_id)) { if (self->bin) { static char pop_mark = POP_MARK; *************** *** 1372,1380 **** save_list(Picklerobject *self, PyObject *args) { PyObject *element = 0; ! int s_len, len, i, using_appends, res = -1; char s[3]; static char append = APPEND, appends = APPENDS; if (self->bin) { s[0] = EMPTY_LIST; --- 1358,1371 ---- save_list(Picklerobject *self, PyObject *args) { PyObject *element = 0; ! int s_len, len, i, using_appends, res = -1, unfast = 0; char s[3]; static char append = APPEND, appends = APPENDS; + if (self->fast && self->fast_container++ > FAST_LIMIT) { + self->fast = 0; + unfast = 1; + } + if (self->bin) { s[0] = EMPTY_LIST; *************** *** 1427,1430 **** --- 1418,1426 ---- finally: + if (self->fast || unfast) { + self->fast_container--; + if (unfast && self->fast_container < FAST_LIMIT) + self->fast = 1; + } return res; *************** *** 1435,1443 **** save_dict(Picklerobject *self, PyObject *args) { PyObject *key = 0, *value = 0; ! int i, len, res = -1, using_setitems; char s[3]; static char setitem = SETITEM, setitems = SETITEMS; if (self->bin) { s[0] = EMPTY_DICT; --- 1431,1444 ---- save_dict(Picklerobject *self, PyObject *args) { PyObject *key = 0, *value = 0; ! int i, len, res = -1, using_setitems, unfast = 0; char s[3]; static char setitem = SETITEM, setitems = SETITEMS; + if (self->fast && self->fast_container++ > FAST_LIMIT) { + self->fast = 0; + unfast = 1; + } + if (self->bin) { s[0] = EMPTY_DICT; *************** *** 1491,1494 **** --- 1492,1501 ---- finally: + if (self->fast || unfast) { + self->fast_container--; + if (unfast && self->fast_container < FAST_LIMIT) + self->fast = 1; + } + return res; *************** *** 1501,1508 **** *getinitargs_func = 0, *getstate_func = 0, *class_args = 0; char *module_str, *name_str; ! int module_size, name_size, res = -1; static char inst = INST, obj = OBJ, build = BUILD; if ((*self->write_func)(self, &MARKv, 1) < 0) goto finally; --- 1508,1520 ---- *getinitargs_func = 0, *getstate_func = 0, *class_args = 0; char *module_str, *name_str; ! int module_size, name_size, res = -1, unfast = 0; static char inst = INST, obj = OBJ, build = BUILD; + if (self->fast && self->fast_container++ > FAST_LIMIT) { + self->fast = 0; + unfast = 1; + } + if ((*self->write_func)(self, &MARKv, 1) < 0) goto finally; *************** *** 1521,1525 **** UNLESS (class_args = ! PyObject_CallObject(getinitargs_func, empty_tuple)) goto finally; --- 1533,1537 ---- UNLESS (class_args = ! PyObject_Call(getinitargs_func, empty_tuple, NULL)) goto finally; *************** *** 1580,1584 **** if ((getstate_func = PyObject_GetAttr(args, __getstate___str))) { ! UNLESS (state = PyObject_CallObject(getstate_func, empty_tuple)) goto finally; } --- 1592,1596 ---- if ((getstate_func = PyObject_GetAttr(args, __getstate___str))) { ! UNLESS (state = PyObject_Call(getstate_func, empty_tuple, NULL)) goto finally; } *************** *** 1611,1614 **** --- 1623,1632 ---- finally: + if (self->fast || unfast) { + self->fast_container--; + if (unfast && self->fast_container < FAST_LIMIT) + self->fast = 1; + } + Py_XDECREF(module); Py_XDECREF(class); *************** *** 1710,1714 **** ARG_TUP(self, args); if (self->arg) { ! pid = PyObject_CallObject(f, self->arg); FREE_ARG_TUP(self); } --- 1728,1732 ---- ARG_TUP(self, args); if (self->arg) { ! pid = PyObject_Call(f, self->arg, NULL); FREE_ARG_TUP(self); } *************** *** 1861,1873 **** if (args->ob_refcnt > 1) { - int has_key; - UNLESS (py_ob_id = PyLong_FromVoidPtr(args)) goto finally; - - if ((has_key = cPickle_PyMapping_HasKey(self->memo, py_ob_id)) < 0) - goto finally; ! if (has_key) { if (get(self, py_ob_id) < 0) goto finally; --- 1879,1886 ---- if (args->ob_refcnt > 1) { UNLESS (py_ob_id = PyLong_FromVoidPtr(args)) goto finally; ! if (PyDict_GetItem(self->memo, py_ob_id)) { if (get(self, py_ob_id) < 0) goto finally; *************** *** 1961,1965 **** ARG_TUP(self, args); if (self->arg) { ! t = PyObject_CallObject(__reduce__, self->arg); FREE_ARG_TUP(self); } --- 1974,1978 ---- ARG_TUP(self, args); if (self->arg) { ! t = PyObject_Call(__reduce__, self->arg, NULL); FREE_ARG_TUP(self); } *************** *** 1970,1974 **** if ((__reduce__ = PyObject_GetAttr(args, __reduce___str))) { ! UNLESS (t = PyObject_CallObject(__reduce__, empty_tuple)) goto finally; } --- 1983,1987 ---- if ((__reduce__ = PyObject_GetAttr(args, __reduce___str))) { ! UNLESS (t = PyObject_Call(__reduce__, empty_tuple, NULL)) goto finally; } *************** *** 2045,2052 **** static PyObject * Pickle_clear_memo(Picklerobject *self, PyObject *args) { ! if (args && ! PyArg_ParseTuple(args,":clear_memo")) return NULL; ! if (self->memo) PyDict_Clear(self->memo); ! Py_INCREF(Py_None); ! return Py_None; } --- 2058,2067 ---- static PyObject * Pickle_clear_memo(Picklerobject *self, PyObject *args) { ! if (!PyArg_ParseTuple(args,":clear_memo")) ! return NULL; ! if (self->memo) ! PyDict_Clear(self->memo); ! Py_INCREF(Py_None); ! return Py_None; } *************** *** 2059,2070 **** Pdata *data; ! if (args && ! PyArg_ParseTuple(args,"|i:getvalue",&clear)) return NULL; /* Check to make sure we are based on a list */ if (! Pdata_Check(self->file)) { PyErr_SetString(PicklingError, ! "Attempt to getvalue a non-list-based pickler"); return NULL; ! } /* flush write buffer */ --- 2074,2087 ---- Pdata *data; ! /* Can be called by Python code or C code */ ! if (args && !PyArg_ParseTuple(args, "|i:getvalue", &clear)) ! return NULL; /* Check to make sure we are based on a list */ if (! Pdata_Check(self->file)) { PyErr_SetString(PicklingError, ! "Attempt to getvalue() a non-list-based pickler"); return NULL; ! } /* flush write buffer */ *************** *** 2199,2202 **** --- 2216,2220 ---- if (get) return Pickle_getvalue(self, NULL); + /* XXX Why does dump() return self? */ Py_INCREF(self); return (PyObject*)self; *************** *** 2233,2236 **** --- 2251,2255 ---- self->bin = bin; self->fast = 0; + self->fast_container = 0; self->buf_size = 0; self->dispatch_table = NULL; *************** *** 2304,2317 **** static PyObject * get_Pickler(PyObject *self, PyObject *args) { ! PyObject *file=NULL; ! int bin; ! bin=1; ! if (! PyArg_ParseTuple(args, "|i:Pickler", &bin)) { PyErr_Clear(); ! bin=0; ! if (! PyArg_ParseTuple(args, "O|i:Pickler", &file, &bin)) ! return NULL; ! } return (PyObject *)newPicklerobject(file, bin); } --- 2323,2335 ---- static PyObject * get_Pickler(PyObject *self, PyObject *args) { ! PyObject *file = NULL; ! int bin = 1; ! if (!PyArg_ParseTuple(args, "|i:Pickler", &bin)) { PyErr_Clear(); ! bin = 0; ! if (!PyArg_ParseTuple(args, "O|i:Pickler", &file, &bin)) ! return NULL; ! } return (PyObject *)newPicklerobject(file, bin); } *************** *** 2335,2442 **** } - static PyObject * ! Pickler_getattr(Picklerobject *self, char *name) { ! ! switch (*name) { ! case 'p': ! if (strcmp(name, "persistent_id") == 0) { ! if (!self->pers_func) { ! PyErr_SetString(PyExc_AttributeError, name); ! return NULL; ! } ! ! Py_INCREF(self->pers_func); ! return self->pers_func; ! } ! break; ! case 'm': ! if (strcmp(name, "memo") == 0) { ! if (!self->memo) { ! PyErr_SetString(PyExc_AttributeError, name); ! return NULL; ! } ! ! Py_INCREF(self->memo); ! return self->memo; ! } ! break; ! case 'P': ! if (strcmp(name, "PicklingError") == 0) { ! Py_INCREF(PicklingError); ! return PicklingError; ! } ! break; ! case 'b': ! if (strcmp(name, "binary")==0) ! return PyInt_FromLong(self->bin); ! break; ! case 'f': ! if (strcmp(name, "fast")==0) ! return PyInt_FromLong(self->fast); ! break; ! case 'g': ! if (strcmp(name, "getvalue")==0 && ! Pdata_Check(self->file)) { ! PyErr_SetString(PyExc_AttributeError, name); ! return NULL; ! } ! break; ! } ! return Py_FindMethod(Pickler_methods, (PyObject *)self, name); } - ! int ! Pickler_setattr(Picklerobject *self, char *name, PyObject *value) { ! ! if (! value) { PyErr_SetString(PyExc_TypeError, ! "attribute deletion is not supported"); return -1; - } - - if (strcmp(name, "persistent_id") == 0) { - Py_XDECREF(self->pers_func); - self->pers_func = value; - Py_INCREF(value); - return 0; } ! if (strcmp(name, "inst_persistent_id") == 0) { ! Py_XDECREF(self->inst_pers_func); ! self->inst_pers_func = value; ! Py_INCREF(value); ! return 0; } ! if (strcmp(name, "memo") == 0) { ! if (! PyDict_Check(value)) { ! PyErr_SetString(PyExc_TypeError, "memo must be a dictionary"); ! return -1; ! } ! Py_XDECREF(self->memo); ! self->memo = value; ! Py_INCREF(value); ! return 0; ! } ! if (strcmp(name, "binary")==0) { ! self->bin=PyObject_IsTrue(value); ! return 0; } ! ! if (strcmp(name, "fast")==0) { ! self->fast=PyObject_IsTrue(value); ! return 0; } ! PyErr_SetString(PyExc_AttributeError, name); ! return -1; } static char Picklertype__doc__[] = ! "Objects that know how to pickle objects\n" ! ; static PyTypeObject Picklertype = { --- 2353,2445 ---- } static PyObject * ! Pickler_get_pers_func(Picklerobject *p) ! { ! if (p->pers_func == NULL) ! PyErr_SetString(PyExc_AttributeError, "persistent_id"); ! else ! Py_INCREF(p->pers_func); ! return p->pers_func; } ! static int ! Pickler_set_pers_func(Picklerobject *p, PyObject *v) ! { ! if (v == NULL) { PyErr_SetString(PyExc_TypeError, ! "attribute deletion is not supported"); return -1; } + Py_XDECREF(p->pers_func); + Py_INCREF(v); + p->pers_func = v; + return 0; + } ! static int ! Pickler_set_inst_pers_func(Picklerobject *p, PyObject *v) ! { ! if (v == NULL) { ! PyErr_SetString(PyExc_TypeError, ! "attribute deletion is not supported"); ! return -1; } + Py_XDECREF(p->inst_pers_func); + Py_INCREF(v); + p->inst_pers_func = v; + return 0; + } ! static PyObject * ! Pickler_get_memo(Picklerobject *p) ! { ! if (p->memo == NULL) ! PyErr_SetString(PyExc_AttributeError, "memo"); ! else ! Py_INCREF(p->memo); ! return p->memo; ! } ! static int ! Pickler_set_memo(Picklerobject *p, PyObject *v) ! { ! if (v == NULL) { ! PyErr_SetString(PyExc_TypeError, ! "attribute deletion is not supported"); ! return -1; } ! if (!PyDict_Check(v)) { ! PyErr_SetString(PyExc_TypeError, "memo must be a dictionary"); ! return -1; } + Py_XDECREF(p->memo); + Py_INCREF(v); + p->memo = v; + return 0; + } ! static PyObject * ! Pickler_get_error(Picklerobject *p) ! { ! /* why is this an attribute on the Pickler? */ ! Py_INCREF(PicklingError); ! return PicklingError; } + static PyMemberDef Pickler_members[] = { + {"binary", T_INT, offsetof(Picklerobject, bin)}, + {"fast", T_INT, offsetof(Picklerobject, fast)}, + }; + + static PyGetSetDef Pickler_getsets[] = { + {"persistent_id", (getter)Pickler_get_pers_func, + (setter)Pickler_set_pers_func}, + {"inst_persistent_id", NULL, (setter)Pickler_set_inst_pers_func}, + {"memo", (getter)Pickler_get_memo, (setter)Pickler_set_memo}, + {"PicklingError", (getter)Pickler_get_error, NULL} + }; static char Picklertype__doc__[] = ! "Objects that know how to pickle objects\n"; static PyTypeObject Picklertype = { *************** *** 2444,2466 **** 0, /*ob_size*/ "Pickler", /*tp_name*/ ! sizeof(Picklerobject), /*tp_basicsize*/ ! 0, /*tp_itemsize*/ ! /* methods */ ! (destructor)Pickler_dealloc, /*tp_dealloc*/ ! (printfunc)0, /*tp_print*/ ! (getattrfunc)Pickler_getattr, /*tp_getattr*/ ! (setattrfunc)Pickler_setattr, /*tp_setattr*/ ! (cmpfunc)0, /*tp_compare*/ ! (reprfunc)0, /*tp_repr*/ ! 0, /*tp_as_number*/ ! 0, /*tp_as_sequence*/ ! 0, /*tp_as_mapping*/ ! (hashfunc)0, /*tp_hash*/ ! (ternaryfunc)0, /*tp_call*/ ! (reprfunc)0, /*tp_str*/ ! ! /* Space for future expansion */ ! 0L,0L,0L,0L, ! Picklertype__doc__ /* Documentation string */ }; --- 2447,2478 ---- 0, /*ob_size*/ "Pickler", /*tp_name*/ ! sizeof(Picklerobject), /*tp_basicsize*/ ! 0, ! (destructor)Pickler_dealloc, /* tp_dealloc */ ! 0, /* tp_print */ ! 0, /* tp_getattr */ ! 0, /* tp_setattr */ ! 0, /* tp_compare */ ! 0, /* tp_repr */ ! 0, /* tp_as_number */ ! 0, /* tp_as_sequence */ ! 0, /* tp_as_mapping */ ! 0, /* tp_hash */ ! 0, /* tp_call */ ! 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ ! PyObject_GenericSetAttr, /* tp_setattro */ ! 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ ! Picklertype__doc__, /* tp_doc */ ! 0, /* tp_traverse */ ! 0, /* tp_clear */ ! 0, /* tp_richcompare */ ! 0, /* tp_weaklistoffset */ ! 0, /* tp_iter */ ! 0, /* tp_iternext */ ! Pickler_methods, /* tp_methods */ ! Pickler_members, /* tp_members */ ! Pickler_getsets, /* tp_getset */ }; *************** *** 2995,3002 **** } ! ! if ((has_key = cPickle_PyMapping_HasKey(safe_constructors, cls)) < 0) ! goto err; ! if (!has_key) if (!(safe = PyObject_GetAttr(cls, __safe_for_unpickling___str)) || --- 3007,3012 ---- } ! /* Is safe_constructors always a dict? */ ! has_key = cPickle_PyMapping_HasKey(safe_constructors, cls); if (!has_key) if (!(safe = PyObject_GetAttr(cls, __safe_for_unpickling___str)) || *************** *** 3137,3141 **** ARG_TUP(self, pid); if (self->arg) { ! pid = PyObject_CallObject(self->pers_func, self->arg); FREE_ARG_TUP(self); } --- 3147,3151 ---- ARG_TUP(self, pid); if (self->arg) { ! pid = PyObject_Call(self->pers_func, self->arg, NULL); FREE_ARG_TUP(self); } *************** *** 3172,3176 **** ARG_TUP(self, pid); if (self->arg) { ! pid = PyObject_CallObject(self->pers_func, self->arg); FREE_ARG_TUP(self); } --- 3182,3186 ---- ARG_TUP(self, pid); if (self->arg) { ! pid = PyObject_Call(self->pers_func, self->arg, NULL); FREE_ARG_TUP(self); } *************** *** 3425,3429 **** ARG_TUP(self, value); if (self->arg) { ! junk = PyObject_CallObject(append_method, self->arg); FREE_ARG_TUP(self); } --- 3435,3439 ---- ARG_TUP(self, value); if (self->arg) { ! junk = PyObject_Call(append_method, self->arg, NULL); FREE_ARG_TUP(self); } *************** *** 3506,3510 **** ARG_TUP(self, value); if (self->arg) { ! junk = PyObject_CallObject(__setstate__, self->arg); FREE_ARG_TUP(self); } --- 3516,3520 ---- ARG_TUP(self, value); if (self->arg) { ! junk = PyObject_Call(__setstate__, self->arg, NULL); FREE_ARG_TUP(self); } *************** *** 4323,4329 **** if (strcmp(name, "memo") == 0) { ! if (! PyDict_Check(value)) { ! PyErr_SetString(PyExc_TypeError, "memo must be a dictionary"); ! return -1; } Py_XDECREF(self->memo); --- 4333,4339 ---- if (strcmp(name, "memo") == 0) { ! if (!PyDict_Check(value)) { ! PyErr_SetString(PyExc_TypeError, "memo must be a dictionary"); ! return -1; } Py_XDECREF(self->memo); *************** *** 4500,4504 **** PyObject *copy_reg, *t, *r; ! #define INIT_STR(S) UNLESS(S ## _str=PyString_FromString(#S)) return -1; INIT_STR(__class__); --- 4510,4514 ---- PyObject *copy_reg, *t, *r; ! #define INIT_STR(S) UNLESS(S ## _str=PyString_InternFromString(#S)) return -1; INIT_STR(__class__); *************** *** 4530,4534 **** UNLESS (safe_constructors = PyObject_GetAttr(copy_reg, ! safe_constructors_str)) return -1; --- 4540,4544 ---- UNLESS (safe_constructors = PyObject_GetAttr(copy_reg, ! safe_constructors_str)) return -1; From gvanrossum@users.sourceforge.net Fri Oct 12 15:13:23 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 12 Oct 2001 07:13:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.100,2.101 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12908 Modified Files: typeobject.c Log Message: Now that COPYBUF is a new local macro, add #undef COPYBUF. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.100 retrieving revision 2.101 diff -C2 -d -r2.100 -r2.101 *** typeobject.c 2001/10/12 02:38:24 2.100 --- typeobject.c 2001/10/12 14:13:21 2.101 *************** *** 1647,1650 **** --- 1647,1651 ---- #undef COPYSEQ #undef COPYMAP + #undef COPYBUF #define SLOTDEFINED(SLOT) \ From gvanrossum@users.sourceforge.net Fri Oct 12 16:34:31 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 12 Oct 2001 08:34:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/lib-tk FixTk.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory usw-pr-cvs1:/tmp/cvs-serv10506 Modified Files: FixTk.py Log Message: Suggestion from SF patch #470433 to avoid clobbering TCL_LIBRARY et al. if already set. Also adds TIX_LIBRARY (just in case). (Note that this is entirely Windows specific.) Index: FixTk.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/FixTk.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** FixTk.py 2000/10/25 17:42:13 1.4 --- FixTk.py 2001/10/12 15:34:29 1.5 *************** *** 1,6 **** import sys, os, _tkinter ver = str(_tkinter.TCL_VERSION) ! for t in "tcl", "tk": ! v = os.path.join(sys.prefix, "tcl", t+ver) ! if os.path.exists(os.path.join(v, "tclIndex")): ! os.environ[t.upper() + "_LIBRARY"] = v --- 1,11 ---- import sys, os, _tkinter + ver = str(_tkinter.TCL_VERSION) ! for t in "tcl", "tk", "tix": ! key = t.upper() + "_LIBRARY" ! try: ! v = os.environ[key] ! except KeyError: ! v = os.path.join(sys.prefix, "tcl", t+ver) ! if os.path.exists(os.path.join(v, "tclIndex")): ! os.environ[key] = v From fredrik@pythonware.com Fri Oct 12 16:54:10 2001 From: fredrik@pythonware.com (Fredrik Lundh) Date: Fri, 12 Oct 2001 17:54:10 +0200 Subject: [Python-checkins] CVS: python/dist/src/Lib/lib-tk FixTk.py,1.4,1.5 References: Message-ID: <001b01c15336$223802c0$0900a8c0@spiff> > Suggestion from SF patch #470433 to avoid clobbering TCL_LIBRARY et > al. if already set. Also adds TIX_LIBRARY (just in case). > (Note that this is entirely Windows specific.) in my experience, this will fuck things up as often than it'll solve things. it could be a good idea to put a note somewhere mentioning that the standard FixTk doesn't necessarily work well for any- one who plan to distribute Python with Tkinter (whether as a python kit or with an application). in that case, you're better off providing your own version of FixTk. From guido@python.org Fri Oct 12 17:06:45 2001 From: guido@python.org (Guido van Rossum) Date: Fri, 12 Oct 2001 12:06:45 -0400 Subject: [Python-checkins] CVS: python/dist/src/Lib/lib-tk FixTk.py,1.4,1.5 In-Reply-To: Your message of "Fri, 12 Oct 2001 17:54:10 +0200." <001b01c15336$223802c0$0900a8c0@spiff> References: <001b01c15336$223802c0$0900a8c0@spiff> Message-ID: <200110121606.MAA05846@cj20424-a.reston1.va.home.com> > > Suggestion from SF patch #470433 to avoid clobbering TCL_LIBRARY et > > al. if already set. Also adds TIX_LIBRARY (just in case). > > (Note that this is entirely Windows specific.) > > in my experience, this will fuck things up as often than it'll > solve things. > > it could be a good idea to put a note somewhere mentioning > that the standard FixTk doesn't necessarily work well for any- > one who plan to distribute Python with Tkinter (whether as a > python kit or with an application). in that case, you're better > off providing your own version of FixTk. Oops, I didn't realize that. Can you suggest specific words or just check them in? --Guido van Rossum (home page: http://www.python.org/~guido/) From gvanrossum@users.sourceforge.net Fri Oct 12 18:43:45 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 12 Oct 2001 10:43:45 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv24653 Modified Files: PLAN.txt Log Message: The dynamic performance hack is (mostly) done. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PLAN.txt,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** PLAN.txt 2001/10/10 14:28:58 1.14 --- PLAN.txt 2001/10/12 17:43:43 1.15 *************** *** 5,18 **** ----------- - More performance work -- one particular test, test_descr.inherits(), - is still about 50% slower with dynamic classes. :-( The approach of - choice would be: - - Add a list of weak refs to derived classes to each dynamic - class, and trap setattr+delattr on the base class so that they - update the tp_XXX slot in each derived class when the base class - __XXX__ gets set or deleted. More work, but more gain (zero waste - in slot_tp_XXX when __XXX__ is not overridden). - Add __del__ handlers? --- 5,8 ---- *************** *** 35,38 **** --- 25,39 ---- Done (mostly) ------------- + + More performance work -- one particular test, test_descr.inherits(), + is still about 50% slower with dynamic classes. :-( The approach of + choice would be: + + Add a list of weak refs to derived classes to each dynamic + class, and trap setattr+delattr on the base class so that they + update the tp_XXX slot in each derived class when the base class + __XXX__ gets set or deleted. More work, but more gain (zero waste + in slot_tp_XXX when __XXX__ is not overridden). + *** That's done now, with great success. *** Make __dynamic__ the default. *** done (but more performance work From gvanrossum@users.sourceforge.net Fri Oct 12 19:59:29 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 12 Oct 2001 11:59:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.178,1.179 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv11916 Modified Files: socketmodule.c Log Message: PySocket_getaddrinfo(): fix two refcount bugs, both having to do with a misunderstanding of the refcont behavior of the 'O' format code in PyArg_ParseTuple() and Py_BuildValue(), respectively. - pobj is only a borrowed reference, so should *not* be DECREF'ed at the end. This was the cause of SF bug #470635. - The Py_BuildValue() call would leak the object produced by makesockaddr(). (I found this by eyeballing the code.) Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.178 retrieving revision 1.179 diff -C2 -d -r1.178 -r1.179 *** socketmodule.c 2001/10/11 17:27:58 1.178 --- socketmodule.c 2001/10/12 18:59:27 1.179 *************** *** 2378,2385 **** goto err; for (res = res0; res; res = res->ai_next) { single = Py_BuildValue("iiisO", res->ai_family, res->ai_socktype, res->ai_protocol, res->ai_canonname ? res->ai_canonname : "", ! makesockaddr(-1, res->ai_addr, res->ai_addrlen)); if (single == NULL) goto err; --- 2378,2390 ---- goto err; for (res = res0; res; res = res->ai_next) { + PyObject *addr = + makesockaddr(-1, res->ai_addr, res->ai_addrlen); + if (addr == NULL) + goto err; single = Py_BuildValue("iiisO", res->ai_family, res->ai_socktype, res->ai_protocol, res->ai_canonname ? res->ai_canonname : "", ! addr); ! Py_DECREF(addr); if (single == NULL) goto err; *************** *** 2389,2398 **** Py_XDECREF(single); } - Py_XDECREF(pobj); return all; err: Py_XDECREF(single); Py_XDECREF(all); - Py_XDECREF(pobj); return (PyObject *)NULL; } --- 2394,2401 ---- From fdrake@users.sourceforge.net Fri Oct 12 20:01:45 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 12 Oct 2001 12:01:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api abstract.tex,NONE,1.1 concrete.tex,NONE,1.1 exceptions.tex,NONE,1.1 init.tex,NONE,1.1 intro.tex,NONE,1.1 memory.tex,NONE,1.1 newtypes.tex,NONE,1.1 refcounting.tex,NONE,1.1 utilities.tex,NONE,1.1 veryhigh.tex,NONE,1.1 api.tex,1.153,1.154 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv12475 Modified Files: api.tex Added Files: abstract.tex concrete.tex exceptions.tex init.tex intro.tex memory.tex newtypes.tex refcounting.tex utilities.tex veryhigh.tex Log Message: Break the Python/C API manual into smaller files by chapter. This manual has grown beyond what font-lock will work with using the default (X)Emacs settings. Indentation of the description has been made consistent, and a number of smaller markup adjustments have been made as well. --- NEW FILE: abstract.tex --- \chapter{Abstract Objects Layer \label{abstract}} The functions in this chapter interact with Python objects regardless of their type, or with wide classes of object types (e.g. all numerical types, or all sequence types). When used on object types for which they do not apply, they will raise a Python exception. \section{Object Protocol \label{object}} \begin{cfuncdesc}{int}{PyObject_Print}{PyObject *o, FILE *fp, int flags} Print an object \var{o}, on file \var{fp}. Returns \code{-1} on error. The flags argument is used to enable certain printing options. The only option currently supported is \constant{Py_PRINT_RAW}; if given, the \function{str()} of the object is written instead of the \function{repr()}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_HasAttrString}{PyObject *o, char *attr_name} Returns \code{1} if \var{o} has the attribute \var{attr_name}, and \code{0} otherwise. This is equivalent to the Python expression \samp{hasattr(\var{o}, \var{attr_name})}. This function always succeeds. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyObject_GetAttrString}{PyObject *o, char *attr_name} Retrieve an attribute named \var{attr_name} from object \var{o}. Returns the attribute value on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o}.\var{attr_name}}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_HasAttr}{PyObject *o, PyObject *attr_name} Returns \code{1} if \var{o} has the attribute \var{attr_name}, and \code{0} otherwise. This is equivalent to the Python expression \samp{hasattr(\var{o}, \var{attr_name})}. This function always succeeds. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyObject_GetAttr}{PyObject *o, PyObject *attr_name} Retrieve an attribute named \var{attr_name} from object \var{o}. Returns the attribute value on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o}.\var{attr_name}}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_SetAttrString}{PyObject *o, char *attr_name, PyObject *v} Set the value of the attribute named \var{attr_name}, for object \var{o}, to the value \var{v}. Returns \code{-1} on failure. This is the equivalent of the Python statement \samp{\var{o}.\var{attr_name} = \var{v}}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_SetAttr}{PyObject *o, PyObject *attr_name, PyObject *v} Set the value of the attribute named \var{attr_name}, for object \var{o}, to the value \var{v}. Returns \code{-1} on failure. This is the equivalent of the Python statement \samp{\var{o}.\var{attr_name} = \var{v}}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_DelAttrString}{PyObject *o, char *attr_name} Delete attribute named \var{attr_name}, for object \var{o}. Returns \code{-1} on failure. This is the equivalent of the Python statement: \samp{del \var{o}.\var{attr_name}}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_DelAttr}{PyObject *o, PyObject *attr_name} Delete attribute named \var{attr_name}, for object \var{o}. Returns \code{-1} on failure. This is the equivalent of the Python statement \samp{del \var{o}.\var{attr_name}}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_Cmp}{PyObject *o1, PyObject *o2, int *result} Compare the values of \var{o1} and \var{o2} using a routine provided by \var{o1}, if one exists, otherwise with a routine provided by \var{o2}. The result of the comparison is returned in \var{result}. Returns \code{-1} on failure. This is the equivalent of the Python statement\bifuncindex{cmp} \samp{\var{result} = cmp(\var{o1}, \var{o2})}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_Compare}{PyObject *o1, PyObject *o2} Compare the values of \var{o1} and \var{o2} using a routine provided by \var{o1}, if one exists, otherwise with a routine provided by \var{o2}. Returns the result of the comparison on success. On error, the value returned is undefined; use \cfunction{PyErr_Occurred()} to detect an error. This is equivalent to the Python expression\bifuncindex{cmp} \samp{cmp(\var{o1}, \var{o2})}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyObject_Repr}{PyObject *o} Compute a string representation of object \var{o}. Returns the string representation on success, \NULL{} on failure. This is the equivalent of the Python expression \samp{repr(\var{o})}. Called by the \function{repr()}\bifuncindex{repr} built-in function and by reverse quotes. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyObject_Str}{PyObject *o} Compute a string representation of object \var{o}. Returns the string representation on success, \NULL{} on failure. This is the equivalent of the Python expression \samp{str(\var{o})}. Called by the \function{str()}\bifuncindex{str} built-in function and by the \keyword{print} statement. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyObject_Unicode}{PyObject *o} Compute a Unicode string representation of object \var{o}. Returns the Unicode string representation on success, \NULL{} on failure. This is the equivalent of the Python expression \samp{unistr(\var{o})}. Called by the \function{unistr()}\bifuncindex{unistr} built-in function. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_IsInstance}{PyObject *inst, PyObject *cls} Return \code{1} if \var{inst} is an instance of the class \var{cls} or a subclass of \var{cls}. If \var{cls} is a type object rather than a class object, \cfunction{PyObject_IsInstance()} returns \code{1} if \var{inst} is of type \var{cls}. If \var{inst} is not a class instance and \var{cls} is neither a type object or class object, \var{inst} must have a \member{__class__} attribute --- the class relationship of the value of that attribute with \var{cls} will be used to determine the result of this function. \versionadded{2.1} \end{cfuncdesc} Subclass determination is done in a fairly straightforward way, but includes a wrinkle that implementors of extensions to the class system may want to be aware of. If \class{A} and \class{B} are class objects, \class{B} is a subclass of \class{A} if it inherits from \class{A} either directly or indirectly. If either is not a class object, a more general mechanism is used to determine the class relationship of the two objects. When testing if \var{B} is a subclass of \var{A}, if \var{A} is \var{B}, \cfunction{PyObject_IsSubclass()} returns true. If \var{A} and \var{B} are different objects, \var{B}'s \member{__bases__} attribute is searched in a depth-first fashion for \var{A} --- the presence of the \member{__bases__} attribute is considered sufficient for this determination. \begin{cfuncdesc}{int}{PyObject_IsSubclass}{PyObject *derived, PyObject *cls} Returns \code{1} if the class \var{derived} is identical to or derived from the class \var{cls}, otherwise returns \code{0}. In case of an error, returns \code{-1}. If either \var{derived} or \var{cls} is not an actual class object, this function uses the generic algorithm described above. \versionadded{2.1} \end{cfuncdesc} \begin{cfuncdesc}{int}{PyCallable_Check}{PyObject *o} Determine if the object \var{o} is callable. Return \code{1} if the object is callable and \code{0} otherwise. This function always succeeds. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyObject_CallObject}{PyObject *callable_object, PyObject *args} Call a callable Python object \var{callable_object}, with arguments given by the tuple \var{args}. If no arguments are needed, then \var{args} may be \NULL. Returns the result of the call on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{apply(\var{callable_object}, \var{args})} or \samp{\var{callable_object}(*\var{args})}. \bifuncindex{apply} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyObject_CallFunction}{PyObject *callable_object, char *format, ...} Call a callable Python object \var{callable_object}, with a variable number of C arguments. The C arguments are described using a \cfunction{Py_BuildValue()} style format string. The format may be \NULL, indicating that no arguments are provided. Returns the result of the call on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{apply(\var{callable_object}\var{args})} or \samp{\var{callable_object}(*\var{args})}. \bifuncindex{apply} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyObject_CallMethod}{PyObject *o, char *method, char *format, ...} Call the method named \var{m} of object \var{o} with a variable number of C arguments. The C arguments are described by a \cfunction{Py_BuildValue()} format string. The format may be \NULL, indicating that no arguments are provided. Returns the result of the call on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o}.\var{method}(\var{args})}. Note that special method names, such as \method{__add__()}, \method{__getitem__()}, and so on are not supported. The specific abstract-object routines for these must be used. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_Hash}{PyObject *o} Compute and return the hash value of an object \var{o}. On failure, return \code{-1}. This is the equivalent of the Python expression \samp{hash(\var{o})}.\bifuncindex{hash} \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_IsTrue}{PyObject *o} Returns \code{1} if the object \var{o} is considered to be true, and \code{0} otherwise. This is equivalent to the Python expression \samp{not not \var{o}}. This function always succeeds. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyObject_Type}{PyObject *o} When \var{o} is non-\NULL, returns a type object corresponding to the object type of object \var{o}. On failure, raises \exception{SystemError} and returns \NULL. This is equivalent to the Python expression \code{type(\var{o})}. \bifuncindex{type} \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_TypeCheck}{PyObject *o, PyTypeObject *type} Return true if the object \var{o} is of type \var{type} or a subtype of \var{type}. Both parameters must be non-\NULL. \versionadded{2.2} \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_Length}{PyObject *o} Return the length of object \var{o}. If the object \var{o} provides both sequence and mapping protocols, the sequence length is returned. On error, \code{-1} is returned. This is the equivalent to the Python expression \samp{len(\var{o})}.\bifuncindex{len} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyObject_GetItem}{PyObject *o, PyObject *key} Return element of \var{o} corresponding to the object \var{key} or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o}[\var{key}]}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_SetItem}{PyObject *o, PyObject *key, PyObject *v} Map the object \var{key} to the value \var{v}. Returns \code{-1} on failure. This is the equivalent of the Python statement \samp{\var{o}[\var{key}] = \var{v}}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_DelItem}{PyObject *o, PyObject *key} Delete the mapping for \var{key} from \var{o}. Returns \code{-1} on failure. This is the equivalent of the Python statement \samp{del \var{o}[\var{key}]}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_AsFileDescriptor}{PyObject *o} Derives a file-descriptor from a Python object. If the object is an integer or long integer, its value is returned. If not, the object's \method{fileno()} method is called if it exists; the method must return an integer or long integer, which is returned as the file descriptor value. Returns \code{-1} on failure. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyObject_Dir}{PyObject *o} This is equivalent to the Python expression \samp{dir(\var{o})}, returning a (possibly empty) list of strings appropriate for the object argument, or \NULL{} if there was an error. If the argument is \NULL, this is like the Python \samp{dir()}, returning the names of the current locals; in this case, if no execution frame is active then \NULL{} is returned but \cfunction{PyErr_Occurred()} will return false. \end{cfuncdesc} \section{Number Protocol \label{number}} \begin{cfuncdesc}{int}{PyNumber_Check}{PyObject *o} Returns \code{1} if the object \var{o} provides numeric protocols, and false otherwise. This function always succeeds. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Add}{PyObject *o1, PyObject *o2} Returns the result of adding \var{o1} and \var{o2}, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o1} + \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Subtract}{PyObject *o1, PyObject *o2} Returns the result of subtracting \var{o2} from \var{o1}, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o1} - \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Multiply}{PyObject *o1, PyObject *o2} Returns the result of multiplying \var{o1} and \var{o2}, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o1} * \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Divide}{PyObject *o1, PyObject *o2} Returns the result of dividing \var{o1} by \var{o2}, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o1} / \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_FloorDivide}{PyObject *o1, PyObject *o2} Return the floor of \var{o1} divided by \var{o2}, or \NULL{} on failure. This is equivalent to the ``classic'' division of integers. \versionadded{2.2} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_TrueDivide}{PyObject *o1, PyObject *o2} Return a reasonable approximation for the mathematical value of \var{o1} divided by \var{o2}, or \NULL{} on failure. The return value is ``approximate'' because binary floating point numbers are approximate; it is not possible to represent all real numbers in base two. This function can return a floating point value when passed two integers. \versionadded{2.2} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Remainder}{PyObject *o1, PyObject *o2} Returns the remainder of dividing \var{o1} by \var{o2}, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o1} \%\ \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Divmod}{PyObject *o1, PyObject *o2} See the built-in function \function{divmod()}\bifuncindex{divmod}. Returns \NULL{} on failure. This is the equivalent of the Python expression \samp{divmod(\var{o1}, \var{o2})}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Power}{PyObject *o1, PyObject *o2, PyObject *o3} See the built-in function \function{pow()}\bifuncindex{pow}. Returns \NULL{} on failure. This is the equivalent of the Python expression \samp{pow(\var{o1}, \var{o2}, \var{o3})}, where \var{o3} is optional. If \var{o3} is to be ignored, pass \cdata{Py_None} in its place (passing \NULL{} for \var{o3} would cause an illegal memory access). \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Negative}{PyObject *o} Returns the negation of \var{o} on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{-\var{o}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Positive}{PyObject *o} Returns \var{o} on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{+\var{o}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Absolute}{PyObject *o} Returns the absolute value of \var{o}, or \NULL{} on failure. This is the equivalent of the Python expression \samp{abs(\var{o})}. \bifuncindex{abs} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Invert}{PyObject *o} Returns the bitwise negation of \var{o} on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\~\var{o}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Lshift}{PyObject *o1, PyObject *o2} Returns the result of left shifting \var{o1} by \var{o2} on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o1} <\code{<} \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Rshift}{PyObject *o1, PyObject *o2} Returns the result of right shifting \var{o1} by \var{o2} on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o1} >\code{>} \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_And}{PyObject *o1, PyObject *o2} Returns the ``bitwise and'' of \var{o2} and \var{o2} on success and \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o1} \&\ \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Xor}{PyObject *o1, PyObject *o2} Returns the ``bitwise exclusive or'' of \var{o1} by \var{o2} on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o1} \textasciicircum{} \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Or}{PyObject *o1, PyObject *o2} Returns the ``bitwise or'' of \var{o1} and \var{o2} on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o1} | \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceAdd}{PyObject *o1, PyObject *o2} Returns the result of adding \var{o1} and \var{o2}, or \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python statement \samp{\var{o1} += \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceSubtract}{PyObject *o1, PyObject *o2} Returns the result of subtracting \var{o2} from \var{o1}, or \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python statement \samp{\var{o1} -= \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceMultiply}{PyObject *o1, PyObject *o2} Returns the result of multiplying \var{o1} and \var{o2}, or \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python statement \samp{\var{o1} *= \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceDivide}{PyObject *o1, PyObject *o2} Returns the result of dividing \var{o1} by \var{o2}, or \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python statement \samp{\var{o1} /= \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceFloorDivide}{PyObject *o1, PyObject *o2} Returns the mathematical of dividing \var{o1} by \var{o2}, or \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python statement \samp{\var{o1} //= \var{o2}}. \versionadded{2.2} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceTrueDivide}{PyObject *o1, PyObject *o2} Return a reasonable approximation for the mathematical value of \var{o1} divided by \var{o2}, or \NULL{} on failure. The return value is ``approximate'' because binary floating point numbers are approximate; it is not possible to represent all real numbers in base two. This function can return a floating point value when passed two integers. The operation is done \emph{in-place} when \var{o1} supports it. \versionadded{2.2} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceRemainder}{PyObject *o1, PyObject *o2} Returns the remainder of dividing \var{o1} by \var{o2}, or \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python statement \samp{\var{o1} \%= \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_InPlacePower}{PyObject *o1, PyObject *o2, PyObject *o3} See the built-in function \function{pow()}.\bifuncindex{pow} Returns \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python statement \samp{\var{o1} **= \var{o2}} when o3 is \cdata{Py_None}, or an in-place variant of \samp{pow(\var{o1}, \var{o2}, \var{o3})} otherwise. If \var{o3} is to be ignored, pass \cdata{Py_None} in its place (passing \NULL{} for \var{o3} would cause an illegal memory access). \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceLshift}{PyObject *o1, PyObject *o2} Returns the result of left shifting \var{o1} by \var{o2} on success, or \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python statement \samp{\var{o1} <\code{<=} \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceRshift}{PyObject *o1, PyObject *o2} Returns the result of right shifting \var{o1} by \var{o2} on success, or \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python statement \samp{\var{o1} >\code{>=} \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceAnd}{PyObject *o1, PyObject *o2} Returns the ``bitwise and'' of \var{o1} and \var{o2} on success and \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python statement \samp{\var{o1} \&= \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceXor}{PyObject *o1, PyObject *o2} Returns the ``bitwise exclusive or'' of \var{o1} by \var{o2} on success, or \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python statement \samp{\var{o1} \textasciicircum= \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_InPlaceOr}{PyObject *o1, PyObject *o2} Returns the ``bitwise or'' of \var{o1} and \var{o2} on success, or \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python statement \samp{\var{o1} |= \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyNumber_Coerce}{PyObject **p1, PyObject **p2} This function takes the addresses of two variables of type \ctype{PyObject*}. If the objects pointed to by \code{*\var{p1}} and \code{*\var{p2}} have the same type, increment their reference count and return \code{0} (success). If the objects can be converted to a common numeric type, replace \code{*p1} and \code{*p2} by their converted value (with 'new' reference counts), and return \code{0}. If no conversion is possible, or if some other error occurs, return \code{-1} (failure) and don't increment the reference counts. The call \code{PyNumber_Coerce(\&o1, \&o2)} is equivalent to the Python statement \samp{\var{o1}, \var{o2} = coerce(\var{o1}, \var{o2})}. \bifuncindex{coerce} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Int}{PyObject *o} Returns the \var{o} converted to an integer object on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{int(\var{o})}.\bifuncindex{int} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Long}{PyObject *o} Returns the \var{o} converted to a long integer object on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{long(\var{o})}.\bifuncindex{long} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyNumber_Float}{PyObject *o} Returns the \var{o} converted to a float object on success, or \NULL{} on failure. This is the equivalent of the Python expression \samp{float(\var{o})}.\bifuncindex{float} \end{cfuncdesc} \section{Sequence Protocol \label{sequence}} \begin{cfuncdesc}{int}{PySequence_Check}{PyObject *o} Return \code{1} if the object provides sequence protocol, and \code{0} otherwise. This function always succeeds. \end{cfuncdesc} \begin{cfuncdesc}{int}{PySequence_Size}{PyObject *o} Returns the number of objects in sequence \var{o} on success, and \code{-1} on failure. For objects that do not provide sequence protocol, this is equivalent to the Python expression \samp{len(\var{o})}.\bifuncindex{len} \end{cfuncdesc} \begin{cfuncdesc}{int}{PySequence_Length}{PyObject *o} Alternate name for \cfunction{PySequence_Size()}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySequence_Concat}{PyObject *o1, PyObject *o2} Return the concatenation of \var{o1} and \var{o2} on success, and \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o1} + \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySequence_Repeat}{PyObject *o, int count} Return the result of repeating sequence object \var{o} \var{count} times, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o} * \var{count}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySequence_InPlaceConcat}{PyObject *o1, PyObject *o2} Return the concatenation of \var{o1} and \var{o2} on success, and \NULL{} on failure. The operation is done \emph{in-place} when \var{o1} supports it. This is the equivalent of the Python expression \samp{\var{o1} += \var{o2}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySequence_InPlaceRepeat}{PyObject *o, int count} Return the result of repeating sequence object \var{o} \var{count} times, or \NULL{} on failure. The operation is done \emph{in-place} when \var{o} supports it. This is the equivalent of the Python expression \samp{\var{o} *= \var{count}}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySequence_GetItem}{PyObject *o, int i} Return the \var{i}th element of \var{o}, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o}[\var{i}]}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySequence_GetSlice}{PyObject *o, int i1, int i2} Return the slice of sequence object \var{o} between \var{i1} and \var{i2}, or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o}[\var{i1}:\var{i2}]}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PySequence_SetItem}{PyObject *o, int i, PyObject *v} Assign object \var{v} to the \var{i}th element of \var{o}. Returns \code{-1} on failure. This is the equivalent of the Python statement \samp{\var{o}[\var{i}] = \var{v}}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PySequence_DelItem}{PyObject *o, int i} Delete the \var{i}th element of object \var{o}. Returns \code{-1} on failure. This is the equivalent of the Python statement \samp{del \var{o}[\var{i}]}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PySequence_SetSlice}{PyObject *o, int i1, int i2, PyObject *v} Assign the sequence object \var{v} to the slice in sequence object \var{o} from \var{i1} to \var{i2}. This is the equivalent of the Python statement \samp{\var{o}[\var{i1}:\var{i2}] = \var{v}}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PySequence_DelSlice}{PyObject *o, int i1, int i2} Delete the slice in sequence object \var{o} from \var{i1} to \var{i2}. Returns \code{-1} on failure. This is the equivalent of the Python statement \samp{del \var{o}[\var{i1}:\var{i2}]}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySequence_Tuple}{PyObject *o} Returns the \var{o} as a tuple on success, and \NULL{} on failure. This is equivalent to the Python expression \samp{tuple(\var{o})}. \bifuncindex{tuple} \end{cfuncdesc} \begin{cfuncdesc}{int}{PySequence_Count}{PyObject *o, PyObject *value} Return the number of occurrences of \var{value} in \var{o}, that is, return the number of keys for which \code{\var{o}[\var{key}] == \var{value}}. On failure, return \code{-1}. This is equivalent to the Python expression \samp{\var{o}.count(\var{value})}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PySequence_Contains}{PyObject *o, PyObject *value} Determine if \var{o} contains \var{value}. If an item in \var{o} is equal to \var{value}, return \code{1}, otherwise return \code{0}. On error, return \code{-1}. This is equivalent to the Python expression \samp{\var{value} in \var{o}}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PySequence_Index}{PyObject *o, PyObject *value} Return the first index \var{i} for which \code{\var{o}[\var{i}] == \var{value}}. On error, return \code{-1}. This is equivalent to the Python expression \samp{\var{o}.index(\var{value})}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySequence_List}{PyObject *o} Return a list object with the same contents as the arbitrary sequence \var{o}. The returned list is guaranteed to be new. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySequence_Tuple}{PyObject *o} Return a tuple object with the same contents as the arbitrary sequence \var{o}. If \var{o} is a tuple, a new reference will be returned, otherwise a tuple will be constructed with the appropriate contents. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySequence_Fast}{PyObject *o, const char *m} Returns the sequence \var{o} as a tuple, unless it is already a tuple or list, in which case \var{o} is returned. Use \cfunction{PySequence_Fast_GET_ITEM()} to access the members of the result. Returns \NULL{} on failure. If the object is not a sequence, raises \exception{TypeError} with \var{m} as the message text. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PySequence_Fast_GET_ITEM}{PyObject *o, int i} Return the \var{i}th element of \var{o}, assuming that \var{o} was returned by \cfunction{PySequence_Fast()}, and that \var{i} is within bounds. The caller is expected to get the length of the sequence by calling \cfunction{PySequence_Size()} on \var{o}, since lists and tuples are guaranteed to always return their true length. \end{cfuncdesc} \section{Mapping Protocol \label{mapping}} \begin{cfuncdesc}{int}{PyMapping_Check}{PyObject *o} Return \code{1} if the object provides mapping protocol, and \code{0} otherwise. This function always succeeds. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyMapping_Length}{PyObject *o} Returns the number of keys in object \var{o} on success, and \code{-1} on failure. For objects that do not provide mapping protocol, this is equivalent to the Python expression \samp{len(\var{o})}.\bifuncindex{len} \end{cfuncdesc} \begin{cfuncdesc}{int}{PyMapping_DelItemString}{PyObject *o, char *key} Remove the mapping for object \var{key} from the object \var{o}. Return \code{-1} on failure. This is equivalent to the Python statement \samp{del \var{o}[\var{key}]}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyMapping_DelItem}{PyObject *o, PyObject *key} Remove the mapping for object \var{key} from the object \var{o}. Return \code{-1} on failure. This is equivalent to the Python statement \samp{del \var{o}[\var{key}]}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyMapping_HasKeyString}{PyObject *o, char *key} On success, return \code{1} if the mapping object has the key \var{key} and \code{0} otherwise. This is equivalent to the Python expression \samp{\var{o}.has_key(\var{key})}. This function always succeeds. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyMapping_HasKey}{PyObject *o, PyObject *key} Return \code{1} if the mapping object has the key \var{key} and \code{0} otherwise. This is equivalent to the Python expression \samp{\var{o}.has_key(\var{key})}. This function always succeeds. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyMapping_Keys}{PyObject *o} On success, return a list of the keys in object \var{o}. On failure, return \NULL. This is equivalent to the Python expression \samp{\var{o}.keys()}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyMapping_Values}{PyObject *o} On success, return a list of the values in object \var{o}. On failure, return \NULL. This is equivalent to the Python expression \samp{\var{o}.values()}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyMapping_Items}{PyObject *o} On success, return a list of the items in object \var{o}, where each item is a tuple containing a key-value pair. On failure, return \NULL. This is equivalent to the Python expression \samp{\var{o}.items()}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyMapping_GetItemString}{PyObject *o, char *key} Return element of \var{o} corresponding to the object \var{key} or \NULL{} on failure. This is the equivalent of the Python expression \samp{\var{o}[\var{key}]}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyMapping_SetItemString}{PyObject *o, char *key, PyObject *v} Map the object \var{key} to the value \var{v} in object \var{o}. Returns \code{-1} on failure. This is the equivalent of the Python statement \samp{\var{o}[\var{key}] = \var{v}}. \end{cfuncdesc} \section{Iterator Protocol \label{iterator}} \versionadded{2.2} There are only a couple of functions specifically for working with iterators. \begin{cfuncdesc}{int}{PyIter_Check}{PyObject *o} Return true if the object \var{o} supports the iterator protocol. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyIter_Next}{PyObject *o} Return the next value from the iteration \var{o}. If the object is an iterator, this retrieves the next value from the iteration, and returns \NULL{} with no exception set if there are no remaining items. If the object is not an iterator, \exception{TypeError} is raised, or if there is an error in retrieving the item, returns \NULL{} and passes along the exception. \end{cfuncdesc} To write a loop which iterates over an iterator, the C code should look something like this: \begin{verbatim} PyObject *iterator = ...; PyObject *item; while (item = PyIter_Next(iter)) { /* do something with item */ } if (PyErr_Occurred()) { /* propogate error */ } else { /* continue doing useful work */ } \end{verbatim} --- NEW FILE: concrete.tex --- \chapter{Concrete Objects Layer \label{concrete}} The functions in this chapter are specific to certain Python object types. Passing them an object of the wrong type is not a good idea; if you receive an object from a Python program and you are not sure that it has the right type, you must perform a type check first; for example, to check that an object is a dictionary, use \cfunction{PyDict_Check()}. The chapter is structured like the ``family tree'' of Python object types. \warning{While the functions described in this chapter carefully check the type of the objects which are passed in, many of them do not check for \NULL{} being passed instead of a valid object. Allowing \NULL{} to be passed in can cause memory access violations and immediate termination of the interpreter.} \section{Fundamental Objects \label{fundamental}} [...2303 lines suppressed...] unless it is \NULL. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyCObject_FromVoidPtrAndDesc}{void* cobj, void* desc, void (*destr)(void *, void *)} Creates a \ctype{PyCObject} from the \ctype{void *}\var{cobj}. The \var{destr} function will be called when the object is reclaimed. The \var{desc} argument can be used to pass extra callback data for the destructor function. \end{cfuncdesc} \begin{cfuncdesc}{void*}{PyCObject_AsVoidPtr}{PyObject* self} Returns the object \ctype{void *} that the \ctype{PyCObject} \var{self} was created with. \end{cfuncdesc} \begin{cfuncdesc}{void*}{PyCObject_GetDesc}{PyObject* self} Returns the description \ctype{void *} that the \ctype{PyCObject} \var{self} was created with. \end{cfuncdesc} --- NEW FILE: exceptions.tex --- \chapter{Exception Handling \label{exceptionHandling}} The functions described in this chapter will let you handle and raise Python exceptions. It is important to understand some of the basics of Python exception handling. It works somewhat like the \UNIX{} \cdata{errno} variable: there is a global indicator (per thread) of the last error that occurred. Most functions don't clear this on success, but will set it to indicate the cause of the error on failure. Most functions also return an error indicator, usually \NULL{} if they are supposed to return a pointer, or \code{-1} if they return an integer (exception: the \cfunction{PyArg_Parse*()} functions return \code{1} for success and \code{0} for failure). When a function must fail because some function it called failed, it generally doesn't set the error indicator; the function it called already set it. The error indicator consists of three Python objects corresponding to \withsubitem{(in module sys)}{ \ttindex{exc_type}\ttindex{exc_value}\ttindex{exc_traceback}} the Python variables \code{sys.exc_type}, \code{sys.exc_value} and \code{sys.exc_traceback}. API functions exist to interact with the error indicator in various ways. There is a separate error indicator for each thread. % XXX Order of these should be more thoughtful. % Either alphabetical or some kind of structure. \begin{cfuncdesc}{void}{PyErr_Print}{} Print a standard traceback to \code{sys.stderr} and clear the error indicator. Call this function only when the error indicator is set. (Otherwise it will cause a fatal error!) \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyErr_Occurred}{} Test whether the error indicator is set. If set, return the exception \emph{type} (the first argument to the last call to one of the \cfunction{PyErr_Set*()} functions or to \cfunction{PyErr_Restore()}). If not set, return \NULL. You do not own a reference to the return value, so you do not need to \cfunction{Py_DECREF()} it. \note{Do not compare the return value to a specific exception; use \cfunction{PyErr_ExceptionMatches()} instead, shown below. (The comparison could easily fail since the exception may be an instance instead of a class, in the case of a class exception, or it may the a subclass of the expected exception.)} \end{cfuncdesc} \begin{cfuncdesc}{int}{PyErr_ExceptionMatches}{PyObject *exc} Equivalent to \samp{PyErr_GivenExceptionMatches(PyErr_Occurred(), \var{exc})}. This should only be called when an exception is actually set; a memory access violation will occur if no exception has been raised. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyErr_GivenExceptionMatches}{PyObject *given, PyObject *exc} Return true if the \var{given} exception matches the exception in \var{exc}. If \var{exc} is a class object, this also returns true when \var{given} is an instance of a subclass. If \var{exc} is a tuple, all exceptions in the tuple (and recursively in subtuples) are searched for a match. If \var{given} is \NULL, a memory access violation will occur. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyErr_NormalizeException}{PyObject**exc, PyObject**val, PyObject**tb} Under certain circumstances, the values returned by \cfunction{PyErr_Fetch()} below can be ``unnormalized'', meaning that \code{*\var{exc}} is a class object but \code{*\var{val}} is not an instance of the same class. This function can be used to instantiate the class in that case. If the values are already normalized, nothing happens. The delayed normalization is implemented to improve performance. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyErr_Clear}{} Clear the error indicator. If the error indicator is not set, there is no effect. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyErr_Fetch}{PyObject **ptype, PyObject **pvalue, PyObject **ptraceback} Retrieve the error indicator into three variables whose addresses are passed. If the error indicator is not set, set all three variables to \NULL. If it is set, it will be cleared and you own a reference to each object retrieved. The value and traceback object may be \NULL{} even when the type object is not. \note{This function is normally only used by code that needs to handle exceptions or by code that needs to save and restore the error indicator temporarily.} \end{cfuncdesc} \begin{cfuncdesc}{void}{PyErr_Restore}{PyObject *type, PyObject *value, PyObject *traceback} Set the error indicator from the three objects. If the error indicator is already set, it is cleared first. If the objects are \NULL, the error indicator is cleared. Do not pass a \NULL{} type and non-\NULL{} value or traceback. The exception type should be a string or class; if it is a class, the value should be an instance of that class. Do not pass an invalid exception type or value. (Violating these rules will cause subtle problems later.) This call takes away a reference to each object: you must own a reference to each object before the call and after the call you no longer own these references. (If you don't understand this, don't use this function. I warned you.) \note{This function is normally only used by code that needs to save and restore the error indicator temporarily.} \end{cfuncdesc} \begin{cfuncdesc}{void}{PyErr_SetString}{PyObject *type, char *message} This is the most common way to set the error indicator. The first argument specifies the exception type; it is normally one of the standard exceptions, e.g. \cdata{PyExc_RuntimeError}. You need not increment its reference count. The second argument is an error message; it is converted to a string object. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyErr_SetObject}{PyObject *type, PyObject *value} This function is similar to \cfunction{PyErr_SetString()} but lets you specify an arbitrary Python object for the ``value'' of the exception. You need not increment its reference count. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyErr_Format}{PyObject *exception, const char *format, \moreargs} This function sets the error indicator. \var{exception} should be a Python exception (string or class, not an instance). \var{format} should be a string, containing format codes, similar to \cfunction{printf()}. The \code{width.precision} before a format code is parsed, but the width part is ignored. \begin{tableii}{c|l}{character}{Character}{Meaning} \lineii{c}{Character, as an \ctype{int} parameter} \lineii{d}{Number in decimal, as an \ctype{int} parameter} \lineii{x}{Number in hexadecimal, as an \ctype{int} parameter} \lineii{x}{A string, as a \ctype{char *} parameter} \end{tableii} An unrecognized format character causes all the rest of the format string to be copied as-is to the result string, and any extra arguments discarded. A new reference is returned, which is owned by the caller. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyErr_SetNone}{PyObject *type} This is a shorthand for \samp{PyErr_SetObject(\var{type}, Py_None)}. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyErr_BadArgument}{} This is a shorthand for \samp{PyErr_SetString(PyExc_TypeError, \var{message})}, where \var{message} indicates that a built-in operation was invoked with an illegal argument. It is mostly for internal use. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyErr_NoMemory}{} This is a shorthand for \samp{PyErr_SetNone(PyExc_MemoryError)}; it returns \NULL{} so an object allocation function can write \samp{return PyErr_NoMemory();} when it runs out of memory. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyErr_SetFromErrno}{PyObject *type} This is a convenience function to raise an exception when a C library function has returned an error and set the C variable \cdata{errno}. It constructs a tuple object whose first item is the integer \cdata{errno} value and whose second item is the corresponding error message (gotten from \cfunction{strerror()}\ttindex{strerror()}), and then calls \samp{PyErr_SetObject(\var{type}, \var{object})}. On \UNIX, when the \cdata{errno} value is \constant{EINTR}, indicating an interrupted system call, this calls \cfunction{PyErr_CheckSignals()}, and if that set the error indicator, leaves it set to that. The function always returns \NULL, so a wrapper function around a system call can write \samp{return PyErr_SetFromErrno();} when the system call returns an error. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyErr_SetFromErrnoWithFilename}{PyObject *type, char *filename} Similar to \cfunction{PyErr_SetFromErrno()}, with the additional behavior that if \var{filename} is not \NULL, it is passed to the constructor of \var{type} as a third parameter. In the case of exceptions such as \exception{IOError} and \exception{OSError}, this is used to define the \member{filename} attribute of the exception instance. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyErr_BadInternalCall}{} This is a shorthand for \samp{PyErr_SetString(PyExc_TypeError, \var{message})}, where \var{message} indicates that an internal operation (e.g. a Python/C API function) was invoked with an illegal argument. It is mostly for internal use. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyErr_Warn}{PyObject *category, char *message} Issue a warning message. The \var{category} argument is a warning category (see below) or \NULL; the \var{message} argument is a message string. This function normally prints a warning message to \var{sys.stderr}; however, it is also possible that the user has specified that warnings are to be turned into errors, and in that case this will raise an exception. It is also possible that the function raises an exception because of a problem with the warning machinery (the implementation imports the \module{warnings} module to do the heavy lifting). The return value is \code{0} if no exception is raised, or \code{-1} if an exception is raised. (It is not possible to determine whether a warning message is actually printed, nor what the reason is for the exception; this is intentional.) If an exception is raised, the caller should do its normal exception handling (for example, \cfunction{Py_DECREF()} owned references and return an error value). Warning categories must be subclasses of \cdata{Warning}; the default warning category is \cdata{RuntimeWarning}. The standard Python warning categories are available as global variables whose names are \samp{PyExc_} followed by the Python exception name. These have the type \ctype{PyObject*}; they are all class objects. Their names are \cdata{PyExc_Warning}, \cdata{PyExc_UserWarning}, \cdata{PyExc_DeprecationWarning}, \cdata{PyExc_SyntaxWarning}, and \cdata{PyExc_RuntimeWarning}. \cdata{PyExc_Warning} is a subclass of \cdata{PyExc_Exception}; the other warning categories are subclasses of \cdata{PyExc_Warning}. 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} \begin{cfuncdesc}{int}{PyErr_WarnExplicit}{PyObject *category, char *message, char *filename, int lineno, char *module, PyObject *registry} Issue a warning message with explicit control over all warning attributes. This is a straightforward wrapper around the Python function \function{warnings.warn_explicit()}, see there for more information. The \var{module} and \var{registry} arguments may be set to \NULL{} to get the default effect described there. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyErr_CheckSignals}{} This function interacts with Python's signal handling. It checks whether a signal has been sent to the processes and if so, invokes the corresponding signal handler. If the \module{signal}\refbimodindex{signal} module is supported, this can invoke a signal handler written in Python. In all cases, the default effect for \constant{SIGINT}\ttindex{SIGINT} is to raise the \withsubitem{(built-in exception)}{\ttindex{KeyboardInterrupt}} \exception{KeyboardInterrupt} exception. If an exception is raised the error indicator is set and the function returns \code{1}; otherwise the function returns \code{0}. The error indicator may or may not be cleared if it was previously set. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyErr_SetInterrupt}{} This function is obsolete. It simulates the effect of a \constant{SIGINT}\ttindex{SIGINT} signal arriving --- the next time \cfunction{PyErr_CheckSignals()} is called, \withsubitem{(built-in exception)}{\ttindex{KeyboardInterrupt}} \exception{KeyboardInterrupt} will be raised. It may be called without holding the interpreter lock. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyErr_NewException}{char *name, PyObject *base, PyObject *dict} This utility function creates and returns a new exception object. The \var{name} argument must be the name of the new exception, a C string of the form \code{module.class}. The \var{base} and \var{dict} arguments are normally \NULL. This creates a class object derived from the root for all exceptions, the built-in name \exception{Exception} (accessible in C as \cdata{PyExc_Exception}). The \member{__module__} attribute of the new class is set to the first part (up to the last dot) of the \var{name} argument, and the class name is set to the last part (after the last dot). The \var{base} argument can be used to specify an alternate base class. The \var{dict} argument can be used to specify a dictionary of class variables and methods. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyErr_WriteUnraisable}{PyObject *obj} This utility function prints a warning message to \code{sys.stderr} when an exception has been set but it is impossible for the interpreter to actually raise the exception. It is used, for example, when an exception occurs in an \method{__del__()} method. The function is called with a single argument \var{obj} that identifies where the context in which the unraisable exception occurred. The repr of \var{obj} will be printed in the warning message. \end{cfuncdesc} \section{Standard Exceptions \label{standardExceptions}} All standard Python exceptions are available as global variables whose names are \samp{PyExc_} followed by the Python exception name. These have the type \ctype{PyObject*}; they are all class objects. For completeness, here are all the variables: \begin{tableiii}{l|l|c}{cdata}{C Name}{Python Name}{Notes} \lineiii{PyExc_Exception}{\exception{Exception}}{(1)} \lineiii{PyExc_StandardError}{\exception{StandardError}}{(1)} \lineiii{PyExc_ArithmeticError}{\exception{ArithmeticError}}{(1)} \lineiii{PyExc_LookupError}{\exception{LookupError}}{(1)} \lineiii{PyExc_AssertionError}{\exception{AssertionError}}{} \lineiii{PyExc_AttributeError}{\exception{AttributeError}}{} \lineiii{PyExc_EOFError}{\exception{EOFError}}{} \lineiii{PyExc_EnvironmentError}{\exception{EnvironmentError}}{(1)} \lineiii{PyExc_FloatingPointError}{\exception{FloatingPointError}}{} \lineiii{PyExc_IOError}{\exception{IOError}}{} \lineiii{PyExc_ImportError}{\exception{ImportError}}{} \lineiii{PyExc_IndexError}{\exception{IndexError}}{} \lineiii{PyExc_KeyError}{\exception{KeyError}}{} \lineiii{PyExc_KeyboardInterrupt}{\exception{KeyboardInterrupt}}{} \lineiii{PyExc_MemoryError}{\exception{MemoryError}}{} \lineiii{PyExc_NameError}{\exception{NameError}}{} \lineiii{PyExc_NotImplementedError}{\exception{NotImplementedError}}{} \lineiii{PyExc_OSError}{\exception{OSError}}{} \lineiii{PyExc_OverflowError}{\exception{OverflowError}}{} \lineiii{PyExc_ReferenceError}{\exception{ReferenceError}}{(2)} \lineiii{PyExc_RuntimeError}{\exception{RuntimeError}}{} \lineiii{PyExc_SyntaxError}{\exception{SyntaxError}}{} \lineiii{PyExc_SystemError}{\exception{SystemError}}{} \lineiii{PyExc_SystemExit}{\exception{SystemExit}}{} \lineiii{PyExc_TypeError}{\exception{TypeError}}{} \lineiii{PyExc_ValueError}{\exception{ValueError}}{} \lineiii{PyExc_WindowsError}{\exception{WindowsError}}{(3)} \lineiii{PyExc_ZeroDivisionError}{\exception{ZeroDivisionError}}{} \end{tableiii} \noindent Notes: \begin{description} \item[(1)] This is a base class for other standard exceptions. \item[(2)] This is the same as \exception{weakref.ReferenceError}. \item[(3)] Only defined on Windows; protect code that uses this by testing that the preprocessor macro \code{MS_WINDOWS} is defined. \end{description} \section{Deprecation of String Exceptions} All exceptions built into Python or provided in the standard library are derived from \exception{Exception}. \withsubitem{(built-in exception)}{\ttindex{Exception}} String exceptions are still supported in the interpreter to allow existing code to run unmodified, but this will also change in a future release. --- NEW FILE: init.tex --- \chapter{Initialization, Finalization, and Threads \label{initialization}} \begin{cfuncdesc}{void}{Py_Initialize}{} Initialize the Python interpreter. In an application embedding Python, this should be called before using any other Python/C API functions; with the exception of \cfunction{Py_SetProgramName()}\ttindex{Py_SetProgramName()}, \cfunction{PyEval_InitThreads()}\ttindex{PyEval_InitThreads()}, \cfunction{PyEval_ReleaseLock()}\ttindex{PyEval_ReleaseLock()}, and \cfunction{PyEval_AcquireLock()}\ttindex{PyEval_AcquireLock()}. This initializes the table of loaded modules (\code{sys.modules}), and\withsubitem{(in module sys)}{\ttindex{modules}\ttindex{path}} creates the fundamental modules \module{__builtin__}\refbimodindex{__builtin__}, \module{__main__}\refbimodindex{__main__} and \module{sys}\refbimodindex{sys}. It also initializes the module search\indexiii{module}{search}{path} path (\code{sys.path}). It does not set \code{sys.argv}; use \cfunction{PySys_SetArgv()}\ttindex{PySys_SetArgv()} for that. This is a no-op when called for a second time (without calling \cfunction{Py_Finalize()}\ttindex{Py_Finalize()} first). There is no return value; it is a fatal error if the initialization fails. \end{cfuncdesc} \begin{cfuncdesc}{int}{Py_IsInitialized}{} Return true (nonzero) when the Python interpreter has been initialized, false (zero) if not. After \cfunction{Py_Finalize()} is called, this returns false until \cfunction{Py_Initialize()} is called again. \end{cfuncdesc} \begin{cfuncdesc}{void}{Py_Finalize}{} Undo all initializations made by \cfunction{Py_Initialize()} and subsequent use of Python/C API functions, and destroy all sub-interpreters (see \cfunction{Py_NewInterpreter()} below) that were created and not yet destroyed since the last call to \cfunction{Py_Initialize()}. Ideally, this frees all memory allocated by the Python interpreter. This is a no-op when called for a second time (without calling \cfunction{Py_Initialize()} again first). There is no return value; errors during finalization are ignored. This function is provided for a number of reasons. An embedding application might want to restart Python without having to restart the application itself. An application that has loaded the Python interpreter from a dynamically loadable library (or DLL) might want to free all memory allocated by Python before unloading the DLL. During a hunt for memory leaks in an application a developer might want to free all memory allocated by Python before exiting from the application. \strong{Bugs and caveats:} The destruction of modules and objects in modules is done in random order; this may cause destructors (\method{__del__()} methods) to fail when they depend on other objects (even functions) or modules. Dynamically loaded extension modules loaded by Python are not unloaded. Small amounts of memory allocated by the Python interpreter may not be freed (if you find a leak, please report it). Memory tied up in circular references between objects is not freed. Some memory allocated by extension modules may not be freed. Some extension may not work properly if their initialization routine is called more than once; this can happen if an applcation calls \cfunction{Py_Initialize()} and \cfunction{Py_Finalize()} more than once. \end{cfuncdesc} \begin{cfuncdesc}{PyThreadState*}{Py_NewInterpreter}{} Create a new sub-interpreter. This is an (almost) totally separate environment for the execution of Python code. In particular, the new interpreter has separate, independent versions of all imported modules, including the fundamental modules \module{__builtin__}\refbimodindex{__builtin__}, \module{__main__}\refbimodindex{__main__} and \module{sys}\refbimodindex{sys}. The table of loaded modules (\code{sys.modules}) and the module search path (\code{sys.path}) are also separate. The new environment has no \code{sys.argv} variable. It has new standard I/O stream file objects \code{sys.stdin}, \code{sys.stdout} and \code{sys.stderr} (however these refer to the same underlying \ctype{FILE} structures in the C library). \withsubitem{(in module sys)}{ \ttindex{stdout}\ttindex{stderr}\ttindex{stdin}} The return value points to the first thread state created in the new sub-interpreter. This thread state is made the current thread state. Note that no actual thread is created; see the discussion of thread states below. If creation of the new interpreter is unsuccessful, \NULL{} is returned; no exception is set since the exception state is stored in the current thread state and there may not be a current thread state. (Like all other Python/C API functions, the global interpreter lock must be held before calling this function and is still held when it returns; however, unlike most other Python/C API functions, there needn't be a current thread state on entry.) Extension modules are shared between (sub-)interpreters as follows: the first time a particular extension is imported, it is initialized normally, and a (shallow) copy of its module's dictionary is squirreled away. When the same extension is imported by another (sub-)interpreter, a new module is initialized and filled with the contents of this copy; the extension's \code{init} function is not called. Note that this is different from what happens when an extension is imported after the interpreter has been completely re-initialized by calling \cfunction{Py_Finalize()}\ttindex{Py_Finalize()} and \cfunction{Py_Initialize()}\ttindex{Py_Initialize()}; in that case, the extension's \code{init\var{module}} function \emph{is} called again. \strong{Bugs and caveats:} Because sub-interpreters (and the main interpreter) are part of the same process, the insulation between them isn't perfect --- for example, using low-level file operations like \withsubitem{(in module os)}{\ttindex{close()}} \function{os.close()} they can (accidentally or maliciously) affect each other's open files. Because of the way extensions are shared between (sub-)interpreters, some extensions may not work properly; this is especially likely when the extension makes use of (static) global variables, or when the extension manipulates its module's dictionary after its initialization. It is possible to insert objects created in one sub-interpreter into a namespace of another sub-interpreter; this should be done with great care to avoid sharing user-defined functions, methods, instances or classes between sub-interpreters, since import operations executed by such objects may affect the wrong (sub-)interpreter's dictionary of loaded modules. (XXX This is a hard-to-fix bug that will be addressed in a future release.) \end{cfuncdesc} \begin{cfuncdesc}{void}{Py_EndInterpreter}{PyThreadState *tstate} Destroy the (sub-)interpreter represented by the given thread state. The given thread state must be the current thread state. See the discussion of thread states below. When the call returns, the current thread state is \NULL. All thread states associated with this interpreted are destroyed. (The global interpreter lock must be held before calling this function and is still held when it returns.) \cfunction{Py_Finalize()}\ttindex{Py_Finalize()} will destroy all sub-interpreters that haven't been explicitly destroyed at that point. \end{cfuncdesc} \begin{cfuncdesc}{void}{Py_SetProgramName}{char *name} This function should be called before \cfunction{Py_Initialize()}\ttindex{Py_Initialize()} is called for the first time, if it is called at all. It tells the interpreter the value of the \code{argv[0]} argument to the \cfunction{main()}\ttindex{main()} function of the program. This is used by \cfunction{Py_GetPath()}\ttindex{Py_GetPath()} and some other functions below to find the Python run-time libraries relative to the interpreter executable. The default value is \code{'python'}. The argument should point to a zero-terminated character string in static storage whose contents will not change for the duration of the program's execution. No code in the Python interpreter will change the contents of this storage. \end{cfuncdesc} \begin{cfuncdesc}{char*}{Py_GetProgramName}{} Return the program name set with \cfunction{Py_SetProgramName()}\ttindex{Py_SetProgramName()}, or the default. The returned string points into static storage; the caller should not modify its value. \end{cfuncdesc} \begin{cfuncdesc}{char*}{Py_GetPrefix}{} Return the \emph{prefix} for installed platform-independent files. This is derived through a number of complicated rules from the program name set with \cfunction{Py_SetProgramName()} and some environment variables; for example, if the program name is \code{'/usr/local/bin/python'}, the prefix is \code{'/usr/local'}. The returned string points into static storage; the caller should not modify its value. This corresponds to the \makevar{prefix} variable in the top-level \file{Makefile} and the \longprogramopt{prefix} argument to the \program{configure} script at build time. The value is available to Python code as \code{sys.prefix}. It is only useful on \UNIX. See also the next function. \end{cfuncdesc} \begin{cfuncdesc}{char*}{Py_GetExecPrefix}{} Return the \emph{exec-prefix} for installed platform-\emph{de}pendent files. This is derived through a number of complicated rules from the program name set with \cfunction{Py_SetProgramName()} and some environment variables; for example, if the program name is \code{'/usr/local/bin/python'}, the exec-prefix is \code{'/usr/local'}. The returned string points into static storage; the caller should not modify its value. This corresponds to the \makevar{exec_prefix} variable in the top-level \file{Makefile} and the \longprogramopt{exec-prefix} argument to the \program{configure} script at build time. The value is available to Python code as \code{sys.exec_prefix}. It is only useful on \UNIX. Background: The exec-prefix differs from the prefix when platform dependent files (such as executables and shared libraries) are installed in a different directory tree. In a typical installation, platform dependent files may be installed in the \file{/usr/local/plat} subtree while platform independent may be installed in \file{/usr/local}. Generally speaking, a platform is a combination of hardware and software families, e.g. Sparc machines running the Solaris 2.x operating system are considered the same platform, but Intel machines running Solaris 2.x are another platform, and Intel machines running Linux are yet another platform. Different major revisions of the same operating system generally also form different platforms. Non-\UNIX{} operating systems are a different story; the installation strategies on those systems are so different that the prefix and exec-prefix are meaningless, and set to the empty string. Note that compiled Python bytecode files are platform independent (but not independent from the Python version by which they were compiled!). System administrators will know how to configure the \program{mount} or \program{automount} programs to share \file{/usr/local} between platforms while having \file{/usr/local/plat} be a different filesystem for each platform. \end{cfuncdesc} \begin{cfuncdesc}{char*}{Py_GetProgramFullPath}{} Return the full program name of the Python executable; this is computed as a side-effect of deriving the default module search path from the program name (set by \cfunction{Py_SetProgramName()}\ttindex{Py_SetProgramName()} above). The returned string points into static storage; the caller should not modify its value. The value is available to Python code as \code{sys.executable}. \withsubitem{(in module sys)}{\ttindex{executable}} \end{cfuncdesc} \begin{cfuncdesc}{char*}{Py_GetPath}{} \indexiii{module}{search}{path} Return the default module search path; this is computed from the program name (set by \cfunction{Py_SetProgramName()} above) and some environment variables. The returned string consists of a series of directory names separated by a platform dependent delimiter character. The delimiter character is \character{:} on \UNIX, \character{;} on DOS/Windows, and \character{\e n} (the \ASCII{} newline character) on Macintosh. The returned string points into static storage; the caller should not modify its value. The value is available to Python code as the list \code{sys.path}\withsubitem{(in module sys)}{\ttindex{path}}, which may be modified to change the future search path for loaded modules. % XXX should give the exact rules \end{cfuncdesc} \begin{cfuncdesc}{const char*}{Py_GetVersion}{} Return the version of this Python interpreter. This is a string that looks something like \begin{verbatim} "1.5 (#67, Dec 31 1997, 22:34:28) [GCC 2.7.2.2]" \end{verbatim} The first word (up to the first space character) is the current Python version; the first three characters are the major and minor version separated by a period. The returned string points into static storage; the caller should not modify its value. The value is available to Python code as the list \code{sys.version}. \withsubitem{(in module sys)}{\ttindex{version}} \end{cfuncdesc} \begin{cfuncdesc}{const char*}{Py_GetPlatform}{} Return the platform identifier for the current platform. On \UNIX, this is formed from the ``official'' name of the operating system, converted to lower case, followed by the major revision number; e.g., for Solaris 2.x, which is also known as SunOS 5.x, the value is \code{'sunos5'}. On Macintosh, it is \code{'mac'}. On Windows, it is \code{'win'}. The returned string points into static storage; the caller should not modify its value. The value is available to Python code as \code{sys.platform}. \withsubitem{(in module sys)}{\ttindex{platform}} \end{cfuncdesc} \begin{cfuncdesc}{const char*}{Py_GetCopyright}{} Return the official copyright string for the current Python version, for example \code{'Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam'} The returned string points into static storage; the caller should not modify its value. The value is available to Python code as the list \code{sys.copyright}. \withsubitem{(in module sys)}{\ttindex{copyright}} \end{cfuncdesc} \begin{cfuncdesc}{const char*}{Py_GetCompiler}{} Return an indication of the compiler used to build the current Python version, in square brackets, for example: \begin{verbatim} "[GCC 2.7.2.2]" \end{verbatim} The returned string points into static storage; the caller should not modify its value. The value is available to Python code as part of the variable \code{sys.version}. \withsubitem{(in module sys)}{\ttindex{version}} \end{cfuncdesc} \begin{cfuncdesc}{const char*}{Py_GetBuildInfo}{} Return information about the sequence number and build date and time of the current Python interpreter instance, for example \begin{verbatim} "#67, Aug 1 1997, 22:34:28" \end{verbatim} The returned string points into static storage; the caller should not modify its value. The value is available to Python code as part of the variable \code{sys.version}. \withsubitem{(in module sys)}{\ttindex{version}} \end{cfuncdesc} \begin{cfuncdesc}{int}{PySys_SetArgv}{int argc, char **argv} Set \code{sys.argv} based on \var{argc} and \var{argv}. These parameters are similar to those passed to the program's \cfunction{main()}\ttindex{main()} function with the difference that the first entry should refer to the script file to be executed rather than the executable hosting the Python interpreter. If there isn't a script that will be run, the first entry in \var{argv} can be an empty string. If this function fails to initialize \code{sys.argv}, a fatal condition is signalled using \cfunction{Py_FatalError()}\ttindex{Py_FatalError()}. \withsubitem{(in module sys)}{\ttindex{argv}} % XXX impl. doesn't seem consistent in allowing 0/NULL for the params; % check w/ Guido. \end{cfuncdesc} % XXX Other PySys thingies (doesn't really belong in this chapter) \section{Thread State and the Global Interpreter Lock \label{threads}} \index{global interpreter lock} \index{interpreter lock} \index{lock, interpreter} The Python interpreter is not fully thread safe. In order to support multi-threaded Python programs, there's a global lock that must be held by the current thread before it can safely access Python objects. Without the lock, even the simplest operations could cause problems in a multi-threaded program: for example, when two threads simultaneously increment the reference count of the same object, the reference count could end up being incremented only once instead of twice. Therefore, the rule exists that only the thread that has acquired the global interpreter lock may operate on Python objects or call Python/C API functions. In order to support multi-threaded Python programs, the interpreter regularly releases and reacquires the lock --- by default, every ten bytecode instructions (this can be changed with \withsubitem{(in module sys)}{\ttindex{setcheckinterval()}} \function{sys.setcheckinterval()}). The lock is also released and reacquired around potentially blocking I/O operations like reading or writing a file, so that other threads can run while the thread that requests the I/O is waiting for the I/O operation to complete. The Python interpreter needs to keep some bookkeeping information separate per thread --- for this it uses a data structure called \ctype{PyThreadState}\ttindex{PyThreadState}. This is new in Python 1.5; in earlier versions, such state was stored in global variables, and switching threads could cause problems. In particular, exception handling is now thread safe, when the application uses \withsubitem{(in module sys)}{\ttindex{exc_info()}} \function{sys.exc_info()} to access the exception last raised in the current thread. There's one global variable left, however: the pointer to the current \ctype{PyThreadState}\ttindex{PyThreadState} structure. While most thread packages have a way to store ``per-thread global data,'' Python's internal platform independent thread abstraction doesn't support this yet. Therefore, the current thread state must be manipulated explicitly. This is easy enough in most cases. Most code manipulating the global interpreter lock has the following simple structure: \begin{verbatim} Save the thread state in a local variable. Release the interpreter lock. ...Do some blocking I/O operation... Reacquire the interpreter lock. Restore the thread state from the local variable. \end{verbatim} This is so common that a pair of macros exists to simplify it: \begin{verbatim} Py_BEGIN_ALLOW_THREADS ...Do some blocking I/O operation... Py_END_ALLOW_THREADS \end{verbatim} The \code{Py_BEGIN_ALLOW_THREADS}\ttindex{Py_BEGIN_ALLOW_THREADS} macro opens a new block and declares a hidden local variable; the \code{Py_END_ALLOW_THREADS}\ttindex{Py_END_ALLOW_THREADS} macro closes the block. Another advantage of using these two macros is that when Python is compiled without thread support, they are defined empty, thus saving the thread state and lock manipulations. When thread support is enabled, the block above expands to the following code: \begin{verbatim} PyThreadState *_save; _save = PyEval_SaveThread(); ...Do some blocking I/O operation... PyEval_RestoreThread(_save); \end{verbatim} Using even lower level primitives, we can get roughly the same effect as follows: \begin{verbatim} PyThreadState *_save; _save = PyThreadState_Swap(NULL); PyEval_ReleaseLock(); ...Do some blocking I/O operation... PyEval_AcquireLock(); PyThreadState_Swap(_save); \end{verbatim} There are some subtle differences; in particular, \cfunction{PyEval_RestoreThread()}\ttindex{PyEval_RestoreThread()} saves and restores the value of the global variable \cdata{errno}\ttindex{errno}, since the lock manipulation does not guarantee that \cdata{errno} is left alone. Also, when thread support is disabled, \cfunction{PyEval_SaveThread()}\ttindex{PyEval_SaveThread()} and \cfunction{PyEval_RestoreThread()} don't manipulate the lock; in this case, \cfunction{PyEval_ReleaseLock()}\ttindex{PyEval_ReleaseLock()} and \cfunction{PyEval_AcquireLock()}\ttindex{PyEval_AcquireLock()} are not available. This is done so that dynamically loaded extensions compiled with thread support enabled can be loaded by an interpreter that was compiled with disabled thread support. The global interpreter lock is used to protect the pointer to the current thread state. When releasing the lock and saving the thread state, the current thread state pointer must be retrieved before the lock is released (since another thread could immediately acquire the lock and store its own thread state in the global variable). Conversely, when acquiring the lock and restoring the thread state, the lock must be acquired before storing the thread state pointer. Why am I going on with so much detail about this? Because when threads are created from C, they don't have the global interpreter lock, nor is there a thread state data structure for them. Such threads must bootstrap themselves into existence, by first creating a thread state data structure, then acquiring the lock, and finally storing their thread state pointer, before they can start using the Python/C API. When they are done, they should reset the thread state pointer, release the lock, and finally free their thread state data structure. When creating a thread data structure, you need to provide an interpreter state data structure. The interpreter state data structure hold global data that is shared by all threads in an interpreter, for example the module administration (\code{sys.modules}). Depending on your needs, you can either create a new interpreter state data structure, or share the interpreter state data structure used by the Python main thread (to access the latter, you must obtain the thread state and access its \member{interp} member; this must be done by a thread that is created by Python or by the main thread after Python is initialized). \begin{ctypedesc}{PyInterpreterState} This data structure represents the state shared by a number of cooperating threads. Threads belonging to the same interpreter share their module administration and a few other internal items. There are no public members in this structure. Threads belonging to different interpreters initially share nothing, except process state like available memory, open file descriptors and such. The global interpreter lock is also shared by all threads, regardless of to which interpreter they belong. \end{ctypedesc} \begin{ctypedesc}{PyThreadState} This data structure represents the state of a single thread. The only public data member is \ctype{PyInterpreterState *}\member{interp}, which points to this thread's interpreter state. \end{ctypedesc} \begin{cfuncdesc}{void}{PyEval_InitThreads}{} Initialize and acquire the global interpreter lock. It should be called in the main thread before creating a second thread or engaging in any other thread operations such as \cfunction{PyEval_ReleaseLock()}\ttindex{PyEval_ReleaseLock()} or \code{PyEval_ReleaseThread(\var{tstate})}\ttindex{PyEval_ReleaseThread()}. It is not needed before calling \cfunction{PyEval_SaveThread()}\ttindex{PyEval_SaveThread()} or \cfunction{PyEval_RestoreThread()}\ttindex{PyEval_RestoreThread()}. This is a no-op when called for a second time. It is safe to call this function before calling \cfunction{Py_Initialize()}\ttindex{Py_Initialize()}. When only the main thread exists, no lock operations are needed. This is a common situation (most Python programs do not use threads), and the lock operations slow the interpreter down a bit. Therefore, the lock is not created initially. This situation is equivalent to having acquired the lock: when there is only a single thread, all object accesses are safe. Therefore, when this function initializes the lock, it also acquires it. Before the Python \module{thread}\refbimodindex{thread} module creates a new thread, knowing that either it has the lock or the lock hasn't been created yet, it calls \cfunction{PyEval_InitThreads()}. When this call returns, it is guaranteed that the lock has been created and that it has acquired it. It is \strong{not} safe to call this function when it is unknown which thread (if any) currently has the global interpreter lock. This function is not available when thread support is disabled at compile time. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyEval_AcquireLock}{} Acquire the global interpreter lock. The lock must have been created earlier. If this thread already has the lock, a deadlock ensues. This function is not available when thread support is disabled at compile time. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyEval_ReleaseLock}{} Release the global interpreter lock. The lock must have been created earlier. This function is not available when thread support is disabled at compile time. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyEval_AcquireThread}{PyThreadState *tstate} Acquire the global interpreter lock and then set the current thread state to \var{tstate}, which should not be \NULL. The lock must have been created earlier. If this thread already has the lock, deadlock ensues. This function is not available when thread support is disabled at compile time. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyEval_ReleaseThread}{PyThreadState *tstate} Reset the current thread state to \NULL{} and release the global interpreter lock. The lock must have been created earlier and must be held by the current thread. The \var{tstate} argument, which must not be \NULL, is only used to check that it represents the current thread state --- if it isn't, a fatal error is reported. This function is not available when thread support is disabled at compile time. \end{cfuncdesc} \begin{cfuncdesc}{PyThreadState*}{PyEval_SaveThread}{} Release the interpreter lock (if it has been created and thread support is enabled) and reset the thread state to \NULL, returning the previous thread state (which is not \NULL). If the lock has been created, the current thread must have acquired it. (This function is available even when thread support is disabled at compile time.) \end{cfuncdesc} \begin{cfuncdesc}{void}{PyEval_RestoreThread}{PyThreadState *tstate} Acquire the interpreter lock (if it has been created and thread support is enabled) and set the thread state to \var{tstate}, which must not be \NULL. If the lock has been created, the current thread must not have acquired it, otherwise deadlock ensues. (This function is available even when thread support is disabled at compile time.) \end{cfuncdesc} The following macros are normally used without a trailing semicolon; look for example usage in the Python source distribution. \begin{csimplemacrodesc}{Py_BEGIN_ALLOW_THREADS} This macro expands to \samp{\{ PyThreadState *_save; _save = PyEval_SaveThread();}. Note that it contains an opening brace; it must be matched with a following \code{Py_END_ALLOW_THREADS} macro. See above for further discussion of this macro. It is a no-op when thread support is disabled at compile time. \end{csimplemacrodesc} \begin{csimplemacrodesc}{Py_END_ALLOW_THREADS} This macro expands to \samp{PyEval_RestoreThread(_save); \}}. Note that it contains a closing brace; it must be matched with an earlier \code{Py_BEGIN_ALLOW_THREADS} macro. See above for further discussion of this macro. It is a no-op when thread support is disabled at compile time. \end{csimplemacrodesc} \begin{csimplemacrodesc}{Py_BLOCK_THREADS} This macro expands to \samp{PyEval_RestoreThread(_save);}: it is equivalent to \code{Py_END_ALLOW_THREADS} without the closing brace. It is a no-op when thread support is disabled at compile time. \end{csimplemacrodesc} \begin{csimplemacrodesc}{Py_UNBLOCK_THREADS} This macro expands to \samp{_save = PyEval_SaveThread();}: it is equivalent to \code{Py_BEGIN_ALLOW_THREADS} without the opening brace and variable declaration. It is a no-op when thread support is disabled at compile time. \end{csimplemacrodesc} All of the following functions are only available when thread support is enabled at compile time, and must be called only when the interpreter lock has been created. \begin{cfuncdesc}{PyInterpreterState*}{PyInterpreterState_New}{} Create a new interpreter state object. The interpreter lock need not be held, but may be held if it is necessary to serialize calls to this function. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyInterpreterState_Clear}{PyInterpreterState *interp} Reset all information in an interpreter state object. The interpreter lock must be held. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyInterpreterState_Delete}{PyInterpreterState *interp} Destroy an interpreter state object. The interpreter lock need not be held. The interpreter state must have been reset with a previous call to \cfunction{PyInterpreterState_Clear()}. \end{cfuncdesc} \begin{cfuncdesc}{PyThreadState*}{PyThreadState_New}{PyInterpreterState *interp} Create a new thread state object belonging to the given interpreter object. The interpreter lock need not be held, but may be held if it is necessary to serialize calls to this function. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyThreadState_Clear}{PyThreadState *tstate} Reset all information in a thread state object. The interpreter lock must be held. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyThreadState_Delete}{PyThreadState *tstate} Destroy a thread state object. The interpreter lock need not be held. The thread state must have been reset with a previous call to \cfunction{PyThreadState_Clear()}. \end{cfuncdesc} \begin{cfuncdesc}{PyThreadState*}{PyThreadState_Get}{} Return the current thread state. The interpreter lock must be held. When the current thread state is \NULL, this issues a fatal error (so that the caller needn't check for \NULL). \end{cfuncdesc} \begin{cfuncdesc}{PyThreadState*}{PyThreadState_Swap}{PyThreadState *tstate} Swap the current thread state with the thread state given by the argument \var{tstate}, which may be \NULL. The interpreter lock must be held. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyThreadState_GetDict}{} Return a dictionary in which extensions can store thread-specific state information. Each extension should use a unique key to use to store state in the dictionary. If this function returns \NULL, an exception has been raised and the caller should allow it to propogate. \end{cfuncdesc} \section{Profiling and Tracing \label{profiling}} \sectionauthor{Fred L. Drake, Jr.}{fdrake@acm.org} The Python interpreter provides some low-level support for attaching profiling and execution tracing facilities. These are used for profiling, debugging, and coverage analysis tools. Starting with Python 2.2, the implementation of this facility was substantially revised, and an interface from C was added. This C interface allows the profiling or tracing code to avoid the overhead of calling through Python-level callable objects, making a direct C function call instead. The essential attributes of the facility have not changed; the interface allows trace functions to be installed per-thread, and the basic events reported to the trace function are the same as had been reported to the Python-level trace functions in previous versions. \begin{ctypedesc}[Py_tracefunc]{int (*Py_tracefunc)(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg)} The type of the trace function registered using \cfunction{PyEval_SetProfile()} and \cfunction{PyEval_SetTrace()}. The first parameter is the object passed to the registration function as \var{obj}, \var{frame} is the frame object to which the event pertains, \var{what} is one of the constants \constant{PyTrace_CALL}, \constant{PyTrace_EXCEPT}, \constant{PyTrace_LINE} or \constant{PyTrace_RETURN}, and \var{arg} depends on the value of \var{what}: \begin{tableii}{l|l}{constant}{Value of \var{what}}{Meaning of \var{arg}} \lineii{PyTrace_CALL}{Always \NULL.} \lineii{PyTrace_EXCEPT}{Exception information as returned by \function{sys.exc_info()}.} \lineii{PyTrace_LINE}{Always \NULL.} \lineii{PyTrace_RETURN}{Value being returned to the caller.} \end{tableii} \end{ctypedesc} \begin{cvardesc}{int}{PyTrace_CALL} The value of the \var{what} parameter to a \ctype{Py_tracefunc} function when a new call to a function or method is being reported, or a new entry into a generator. Note that the creation of the iterator for a generator function is not reported as there is no control transfer to the Python bytecode in the corresponding frame. \end{cvardesc} \begin{cvardesc}{int}{PyTrace_EXCEPT} The value of the \var{what} parameter to a \ctype{Py_tracefunc} function when an exception has been raised by Python code as the result of an operation. The operation may have explictly intended to raise the operation (as with a \keyword{raise} statement), or may have triggered an exception in the runtime as a result of the specific operation. \end{cvardesc} \begin{cvardesc}{int}{PyTrace_LINE} The value passed as the \var{what} parameter to a trace function (but not a profiling function) when a line-number event is being reported. \end{cvardesc} \begin{cvardesc}{int}{PyTrace_RETURN} The value for the \var{what} parameter to \ctype{Py_tracefunc} functions when a call is returning without propogating an exception. \end{cvardesc} \begin{cfuncdesc}{void}{PyEval_SetProfile}{Py_tracefunc func, PyObject *obj} Set the profiler function to \var{func}. The \var{obj} parameter is passed to the function as its first parameter, and may be any Python object, or \NULL. If the profile function needs to maintain state, using a different value for \var{obj} for each thread provides a convenient and thread-safe place to store it. The profile function is called for all monitored events except the line-number events. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyEval_SetTrace}{Py_tracefunc func, PyObject *obj} Set the the tracing function to \var{func}. This is similar to \cfunction{PyEval_SetProfile()}, except the tracing function does receive line-number events. \end{cfuncdesc} \section{Advanced Debugger Support \label{advanced-debugging}} \sectionauthor{Fred L. Drake, Jr.}{fdrake@acm.org} These functions are only intended to be used by advanced debugging tools. \begin{cfuncdesc}{PyInterpreterState*}{PyInterpreterState_Head}{} Return the interpreter state object at the head of the list of all such objects. \versionadded{2.2} \end{cfuncdesc} \begin{cfuncdesc}{PyInterpreterState*}{PyInterpreterState_Next}{PyInterpreterState *interp} Return the next interpreter state object after \var{interp} from the list of all such objects. \versionadded{2.2} \end{cfuncdesc} \begin{cfuncdesc}{PyThreadState *}{PyInterpreterState_ThreadHead}{PyInterpreterState *interp} Return the a pointer to the first \ctype{PyThreadState} object in the list of threads associated with the interpreter \var{interp}. \versionadded{2.2} \end{cfuncdesc} \begin{cfuncdesc}{PyThreadState*}{PyThreadState_Next}{PyThreadState *tstate} Return the next thread state object after \var{tstate} from the list of all such objects belonging to the same \ctype{PyInterpreterState} object. \versionadded{2.2} \end{cfuncdesc} --- NEW FILE: intro.tex --- \chapter{Introduction \label{intro}} The Application Programmer's Interface to Python gives C and \Cpp{} programmers access to the Python interpreter at a variety of levels. The API is equally usable from \Cpp{}, but for brevity it is generally referred to as the Python/C API. There are two fundamentally different reasons for using the Python/C API. The first reason is to write \emph{extension modules} for specific purposes; these are C modules that extend the Python interpreter. This is probably the most common use. The second reason is to use Python as a component in a larger application; this technique is generally referred to as \dfn{embedding} Python in an application. Writing an extension module is a relatively well-understood process, where a ``cookbook'' approach works well. There are several tools that automate the process to some extent. While people have embedded Python in other applications since its early existence, the process of embedding Python is less straightforward than writing an extension. Many API functions are useful independent of whether you're embedding or extending Python; moreover, most applications that embed Python will need to provide a custom extension as well, so it's probably a good idea to become familiar with writing an extension before attempting to embed Python in a real application. \section{Include Files \label{includes}} All function, type and macro definitions needed to use the Python/C API are included in your code by the following line: \begin{verbatim} #include "Python.h" \end{verbatim} This implies inclusion of the following standard headers: \code{}, \code{}, \code{}, \code{}, and \code{} (if available). Since Python may define some pre-processor definitions which affect the standard headers on some systems, you must include \file{Python.h} before any standard headers are included. All user visible names defined by Python.h (except those defined by the included standard headers) have one of the prefixes \samp{Py} or \samp{_Py}. Names beginning with \samp{_Py} are for internal use by the Python implementation and should not be used by extension writers. Structure member names do not have a reserved prefix. \strong{Important:} user code should never define names that begin with \samp{Py} or \samp{_Py}. This confuses the reader, and jeopardizes the portability of the user code to future Python versions, which may define additional names beginning with one of these prefixes. The header files are typically installed with Python. On \UNIX, these are located in the directories \file{\envvar{prefix}/include/python\var{version}/} and \file{\envvar{exec_prefix}/include/python\var{version}/}, where \envvar{prefix} and \envvar{exec_prefix} are defined by the corresponding parameters to Python's \program{configure} script and \var{version} is \code{sys.version[:3]}. On Windows, the headers are installed in \file{\envvar{prefix}/include}, where \envvar{prefix} is the installation directory specified to the installer. To include the headers, place both directories (if different) on your compiler's search path for includes. Do \emph{not} place the parent directories on the search path and then use \samp{\#include }; this will break on multi-platform builds since the platform independent headers under \envvar{prefix} include the platform specific headers from \envvar{exec_prefix}. \Cpp{} users should note that though the API is defined entirely using C, the header files do properly declare the entry points to be \code{extern "C"}, so there is no need to do anything special to use the API from \Cpp. \section{Objects, Types and Reference Counts \label{objects}} Most Python/C API functions have one or more arguments as well as a return value of type \ctype{PyObject*}. This type is a pointer to an opaque data type representing an arbitrary Python object. Since all Python object types are treated the same way by the Python language in most situations (e.g., assignments, scope rules, and argument passing), it is only fitting that they should be represented by a single C type. Almost all Python objects live on the heap: you never declare an automatic or static variable of type \ctype{PyObject}, only pointer variables of type \ctype{PyObject*} can be declared. The sole exception are the type objects\obindex{type}; since these must never be deallocated, they are typically static \ctype{PyTypeObject} objects. All Python objects (even Python integers) have a \dfn{type} and a \dfn{reference count}. An object's type determines what kind of object it is (e.g., an integer, a list, or a user-defined function; there are many more as explained in the \citetitle[../ref/ref.html]{Python Reference Manual}). For each of the well-known types there is a macro to check whether an object is of that type; for instance, \samp{PyList_Check(\var{a})} is true if (and only if) the object pointed to by \var{a} is a Python list. \subsection{Reference Counts \label{refcounts}} The reference count is important because today's computers have a finite (and often severely limited) memory size; it counts how many different places there are that have a reference to an object. Such a place could be another object, or a global (or static) C variable, or a local variable in some C function. When an object's reference count becomes zero, the object is deallocated. If it contains references to other objects, their reference count is decremented. Those other objects may be deallocated in turn, if this decrement makes their reference count become zero, and so on. (There's an obvious problem with objects that reference each other here; for now, the solution is ``don't do that.'') Reference counts are always manipulated explicitly. The normal way is to use the macro \cfunction{Py_INCREF()}\ttindex{Py_INCREF()} to increment an object's reference count by one, and \cfunction{Py_DECREF()}\ttindex{Py_DECREF()} to decrement it by one. The \cfunction{Py_DECREF()} macro is considerably more complex than the incref one, since it must check whether the reference count becomes zero and then cause the object's deallocator to be called. The deallocator is a function pointer contained in the object's type structure. The type-specific deallocator takes care of decrementing the reference counts for other objects contained in the object if this is a compound object type, such as a list, as well as performing any additional finalization that's needed. There's no chance that the reference count can overflow; at least as many bits are used to hold the reference count as there are distinct memory locations in virtual memory (assuming \code{sizeof(long) >= sizeof(char*)}). Thus, the reference count increment is a simple operation. It is not necessary to increment an object's reference count for every local variable that contains a pointer to an object. In theory, the object's reference count goes up by one when the variable is made to point to it and it goes down by one when the variable goes out of scope. However, these two cancel each other out, so at the end the reference count hasn't changed. The only real reason to use the reference count is to prevent the object from being deallocated as long as our variable is pointing to it. If we know that there is at least one other reference to the object that lives at least as long as our variable, there is no need to increment the reference count temporarily. An important situation where this arises is in objects that are passed as arguments to C functions in an extension module that are called from Python; the call mechanism guarantees to hold a reference to every argument for the duration of the call. However, a common pitfall is to extract an object from a list and hold on to it for a while without incrementing its reference count. Some other operation might conceivably remove the object from the list, decrementing its reference count and possible deallocating it. The real danger is that innocent-looking operations may invoke arbitrary Python code which could do this; there is a code path which allows control to flow back to the user from a \cfunction{Py_DECREF()}, so almost any operation is potentially dangerous. A safe approach is to always use the generic operations (functions whose name begins with \samp{PyObject_}, \samp{PyNumber_}, \samp{PySequence_} or \samp{PyMapping_}). These operations always increment the reference count of the object they return. This leaves the caller with the responsibility to call \cfunction{Py_DECREF()} when they are done with the result; this soon becomes second nature. \subsubsection{Reference Count Details \label{refcountDetails}} The reference count behavior of functions in the Python/C API is best explained in terms of \emph{ownership of references}. Note that we talk of owning references, never of owning objects; objects are always shared! When a function owns a reference, it has to dispose of it properly --- either by passing ownership on (usually to its caller) or by calling \cfunction{Py_DECREF()} or \cfunction{Py_XDECREF()}. When a function passes ownership of a reference on to its caller, the caller is said to receive a \emph{new} reference. When no ownership is transferred, the caller is said to \emph{borrow} the reference. Nothing needs to be done for a borrowed reference. Conversely, when a calling function passes it a reference to an object, there are two possibilities: the function \emph{steals} a reference to the object, or it does not. Few functions steal references; the two notable exceptions are \cfunction{PyList_SetItem()}\ttindex{PyList_SetItem()} and \cfunction{PyTuple_SetItem()}\ttindex{PyTuple_SetItem()}, which steal a reference to the item (but not to the tuple or list into which the item is put!). These functions were designed to steal a reference because of a common idiom for populating a tuple or list with newly created objects; for example, the code to create the tuple \code{(1, 2, "three")} could look like this (forgetting about error handling for the moment; a better way to code this is shown below): \begin{verbatim} PyObject *t; t = PyTuple_New(3); PyTuple_SetItem(t, 0, PyInt_FromLong(1L)); PyTuple_SetItem(t, 1, PyInt_FromLong(2L)); PyTuple_SetItem(t, 2, PyString_FromString("three")); \end{verbatim} Incidentally, \cfunction{PyTuple_SetItem()} is the \emph{only} way to set tuple items; \cfunction{PySequence_SetItem()} and \cfunction{PyObject_SetItem()} refuse to do this since tuples are an immutable data type. You should only use \cfunction{PyTuple_SetItem()} for tuples that you are creating yourself. Equivalent code for populating a list can be written using \cfunction{PyList_New()} and \cfunction{PyList_SetItem()}. Such code can also use \cfunction{PySequence_SetItem()}; this illustrates the difference between the two (the extra \cfunction{Py_DECREF()} calls): \begin{verbatim} PyObject *l, *x; l = PyList_New(3); x = PyInt_FromLong(1L); PySequence_SetItem(l, 0, x); Py_DECREF(x); x = PyInt_FromLong(2L); PySequence_SetItem(l, 1, x); Py_DECREF(x); x = PyString_FromString("three"); PySequence_SetItem(l, 2, x); Py_DECREF(x); \end{verbatim} You might find it strange that the ``recommended'' approach takes more code. However, in practice, you will rarely use these ways of creating and populating a tuple or list. There's a generic function, \cfunction{Py_BuildValue()}, that can create most common objects from C values, directed by a \dfn{format string}. For example, the above two blocks of code could be replaced by the following (which also takes care of the error checking): \begin{verbatim} PyObject *t, *l; t = Py_BuildValue("(iis)", 1, 2, "three"); l = Py_BuildValue("[iis]", 1, 2, "three"); \end{verbatim} It is much more common to use \cfunction{PyObject_SetItem()} and friends with items whose references you are only borrowing, like arguments that were passed in to the function you are writing. In that case, their behaviour regarding reference counts is much saner, since you don't have to increment a reference count so you can give a reference away (``have it be stolen''). For example, this function sets all items of a list (actually, any mutable sequence) to a given item: \begin{verbatim} int set_all(PyObject *target, PyObject *item) { int i, n; n = PyObject_Length(target); if (n < 0) return -1; for (i = 0; i < n; i++) { if (PyObject_SetItem(target, i, item) < 0) return -1; } return 0; } \end{verbatim} \ttindex{set_all()} The situation is slightly different for function return values. While passing a reference to most functions does not change your ownership responsibilities for that reference, many functions that return a referece to an object give you ownership of the reference. The reason is simple: in many cases, the returned object is created on the fly, and the reference you get is the only reference to the object. Therefore, the generic functions that return object references, like \cfunction{PyObject_GetItem()} and \cfunction{PySequence_GetItem()}, always return a new reference (the caller becomes the owner of the reference). It is important to realize that whether you own a reference returned by a function depends on which function you call only --- \emph{the plumage} (the type of the type of the object passed as an argument to the function) \emph{doesn't enter into it!} Thus, if you extract an item from a list using \cfunction{PyList_GetItem()}, you don't own the reference --- but if you obtain the same item from the same list using \cfunction{PySequence_GetItem()} (which happens to take exactly the same arguments), you do own a reference to the returned object. Here is an example of how you could write a function that computes the sum of the items in a list of integers; once using \cfunction{PyList_GetItem()}\ttindex{PyList_GetItem()}, and once using \cfunction{PySequence_GetItem()}\ttindex{PySequence_GetItem()}. \begin{verbatim} long sum_list(PyObject *list) { int i, n; long total = 0; PyObject *item; n = PyList_Size(list); if (n < 0) return -1; /* Not a list */ for (i = 0; i < n; i++) { item = PyList_GetItem(list, i); /* Can't fail */ if (!PyInt_Check(item)) continue; /* Skip non-integers */ total += PyInt_AsLong(item); } return total; } \end{verbatim} \ttindex{sum_list()} \begin{verbatim} long sum_sequence(PyObject *sequence) { int i, n; long total = 0; PyObject *item; n = PySequence_Length(sequence); if (n < 0) return -1; /* Has no length */ for (i = 0; i < n; i++) { item = PySequence_GetItem(sequence, i); if (item == NULL) return -1; /* Not a sequence, or other failure */ if (PyInt_Check(item)) total += PyInt_AsLong(item); Py_DECREF(item); /* Discard reference ownership */ } return total; } \end{verbatim} \ttindex{sum_sequence()} \subsection{Types \label{types}} There are few other data types that play a significant role in the Python/C API; most are simple C types such as \ctype{int}, \ctype{long}, \ctype{double} and \ctype{char*}. A few structure types are used to describe static tables used to list the functions exported by a module or the data attributes of a new object type, and another is used to describe the value of a complex number. These will be discussed together with the functions that use them. \section{Exceptions \label{exceptions}} The Python programmer only needs to deal with exceptions if specific error handling is required; unhandled exceptions are automatically propagated to the caller, then to the caller's caller, and so on, until they reach the top-level interpreter, where they are reported to the user accompanied by a stack traceback. For C programmers, however, error checking always has to be explicit. All functions in the Python/C API can raise exceptions, unless an explicit claim is made otherwise in a function's documentation. In general, when a function encounters an error, it sets an exception, discards any object references that it owns, and returns an error indicator --- usually \NULL{} or \code{-1}. A few functions return a Boolean true/false result, with false indicating an error. Very few functions return no explicit error indicator or have an ambiguous return value, and require explicit testing for errors with \cfunction{PyErr_Occurred()}\ttindex{PyErr_Occurred()}. Exception state is maintained in per-thread storage (this is equivalent to using global storage in an unthreaded application). A thread can be in one of two states: an exception has occurred, or not. The function \cfunction{PyErr_Occurred()} can be used to check for this: it returns a borrowed reference to the exception type object when an exception has occurred, and \NULL{} otherwise. There are a number of functions to set the exception state: \cfunction{PyErr_SetString()}\ttindex{PyErr_SetString()} is the most common (though not the most general) function to set the exception state, and \cfunction{PyErr_Clear()}\ttindex{PyErr_Clear()} clears the exception state. The full exception state consists of three objects (all of which can be \NULL): the exception type, the corresponding exception value, and the traceback. These have the same meanings as the Python \withsubitem{(in module sys)}{ \ttindex{exc_type}\ttindex{exc_value}\ttindex{exc_traceback}} objects \code{sys.exc_type}, \code{sys.exc_value}, and \code{sys.exc_traceback}; however, they are not the same: the Python objects represent the last exception being handled by a Python \keyword{try} \ldots\ \keyword{except} statement, while the C level exception state only exists while an exception is being passed on between C functions until it reaches the Python bytecode interpreter's main loop, which takes care of transferring it to \code{sys.exc_type} and friends. Note that starting with Python 1.5, the preferred, thread-safe way to access the exception state from Python code is to call the function \withsubitem{(in module sys)}{\ttindex{exc_info()}} \function{sys.exc_info()}, which returns the per-thread exception state for Python code. Also, the semantics of both ways to access the exception state have changed so that a function which catches an exception will save and restore its thread's exception state so as to preserve the exception state of its caller. This prevents common bugs in exception handling code caused by an innocent-looking function overwriting the exception being handled; it also reduces the often unwanted lifetime extension for objects that are referenced by the stack frames in the traceback. As a general principle, a function that calls another function to perform some task should check whether the called function raised an exception, and if so, pass the exception state on to its caller. It should discard any object references that it owns, and return an error indicator, but it should \emph{not} set another exception --- that would overwrite the exception that was just raised, and lose important information about the exact cause of the error. A simple example of detecting exceptions and passing them on is shown in the \cfunction{sum_sequence()}\ttindex{sum_sequence()} example above. It so happens that that example doesn't need to clean up any owned references when it detects an error. The following example function shows some error cleanup. First, to remind you why you like Python, we show the equivalent Python code: \begin{verbatim} def incr_item(dict, key): try: item = dict[key] except KeyError: item = 0 dict[key] = item + 1 \end{verbatim} \ttindex{incr_item()} Here is the corresponding C code, in all its glory: \begin{verbatim} int incr_item(PyObject *dict, PyObject *key) { /* Objects all initialized to NULL for Py_XDECREF */ PyObject *item = NULL, *const_one = NULL, *incremented_item = NULL; int rv = -1; /* Return value initialized to -1 (failure) */ item = PyObject_GetItem(dict, key); if (item == NULL) { /* Handle KeyError only: */ if (!PyErr_ExceptionMatches(PyExc_KeyError)) goto error; /* Clear the error and use zero: */ PyErr_Clear(); item = PyInt_FromLong(0L); if (item == NULL) goto error; } const_one = PyInt_FromLong(1L); if (const_one == NULL) goto error; incremented_item = PyNumber_Add(item, const_one); if (incremented_item == NULL) goto error; if (PyObject_SetItem(dict, key, incremented_item) < 0) goto error; rv = 0; /* Success */ /* Continue with cleanup code */ error: /* Cleanup code, shared by success and failure path */ /* Use Py_XDECREF() to ignore NULL references */ Py_XDECREF(item); Py_XDECREF(const_one); Py_XDECREF(incremented_item); return rv; /* -1 for error, 0 for success */ } \end{verbatim} \ttindex{incr_item()} This example represents an endorsed use of the \keyword{goto} statement in C! It illustrates the use of \cfunction{PyErr_ExceptionMatches()}\ttindex{PyErr_ExceptionMatches()} and \cfunction{PyErr_Clear()}\ttindex{PyErr_Clear()} to handle specific exceptions, and the use of \cfunction{Py_XDECREF()}\ttindex{Py_XDECREF()} to dispose of owned references that may be \NULL{} (note the \character{X} in the name; \cfunction{Py_DECREF()} would crash when confronted with a \NULL{} reference). It is important that the variables used to hold owned references are initialized to \NULL{} for this to work; likewise, the proposed return value is initialized to \code{-1} (failure) and only set to success after the final call made is successful. \section{Embedding Python \label{embedding}} The one important task that only embedders (as opposed to extension writers) of the Python interpreter have to worry about is the initialization, and possibly the finalization, of the Python interpreter. Most functionality of the interpreter can only be used after the interpreter has been initialized. The basic initialization function is \cfunction{Py_Initialize()}\ttindex{Py_Initialize()}. This initializes the table of loaded modules, and creates the fundamental modules \module{__builtin__}\refbimodindex{__builtin__}, \module{__main__}\refbimodindex{__main__}, \module{sys}\refbimodindex{sys}, and \module{exceptions}.\refbimodindex{exceptions} It also initializes the module search path (\code{sys.path}).% \indexiii{module}{search}{path} \withsubitem{(in module sys)}{\ttindex{path}} \cfunction{Py_Initialize()} does not set the ``script argument list'' (\code{sys.argv}). If this variable is needed by Python code that will be executed later, it must be set explicitly with a call to \code{PySys_SetArgv(\var{argc}, \var{argv})}\ttindex{PySys_SetArgv()} subsequent to the call to \cfunction{Py_Initialize()}. On most systems (in particular, on \UNIX{} and Windows, although the details are slightly different), \cfunction{Py_Initialize()} calculates the module search path based upon its best guess for the location of the standard Python interpreter executable, assuming that the Python library is found in a fixed location relative to the Python interpreter executable. In particular, it looks for a directory named \file{lib/python\shortversion} relative to the parent directory where the executable named \file{python} is found on the shell command search path (the environment variable \envvar{PATH}). For instance, if the Python executable is found in \file{/usr/local/bin/python}, it will assume that the libraries are in \file{/usr/local/lib/python\shortversion}. (In fact, this particular path is also the ``fallback'' location, used when no executable file named \file{python} is found along \envvar{PATH}.) The user can override this behavior by setting the environment variable \envvar{PYTHONHOME}, or insert additional directories in front of the standard path by setting \envvar{PYTHONPATH}. The embedding application can steer the search by calling \code{Py_SetProgramName(\var{file})}\ttindex{Py_SetProgramName()} \emph{before} calling \cfunction{Py_Initialize()}. Note that \envvar{PYTHONHOME} still overrides this and \envvar{PYTHONPATH} is still inserted in front of the standard path. An application that requires total control has to provide its own implementation of \cfunction{Py_GetPath()}\ttindex{Py_GetPath()}, \cfunction{Py_GetPrefix()}\ttindex{Py_GetPrefix()}, \cfunction{Py_GetExecPrefix()}\ttindex{Py_GetExecPrefix()}, and \cfunction{Py_GetProgramFullPath()}\ttindex{Py_GetProgramFullPath()} (all defined in \file{Modules/getpath.c}). Sometimes, it is desirable to ``uninitialize'' Python. For instance, the application may want to start over (make another call to \cfunction{Py_Initialize()}) or the application is simply done with its use of Python and wants to free all memory allocated by Python. This can be accomplished by calling \cfunction{Py_Finalize()}. The function \cfunction{Py_IsInitialized()}\ttindex{Py_IsInitialized()} returns true if Python is currently in the initialized state. More information about these functions is given in a later chapter. --- NEW FILE: memory.tex --- \chapter{Memory Management \label{memory}} \sectionauthor{Vladimir Marangozov}{Vladimir.Marangozov@inrialpes.fr} \section{Overview \label{memoryOverview}} Memory management in Python involves a private heap containing all Python objects and data structures. The management of this private heap is ensured internally by the \emph{Python memory manager}. The Python memory manager has different components which deal with various dynamic storage management aspects, like sharing, segmentation, preallocation or caching. At the lowest level, a raw memory allocator ensures that there is enough room in the private heap for storing all Python-related data by interacting with the memory manager of the operating system. On top of the raw memory allocator, several object-specific allocators operate on the same heap and implement distinct memory management policies adapted to the peculiarities of every object type. For example, integer objects are managed differently within the heap than strings, tuples or dictionaries because integers imply different storage requirements and speed/space tradeoffs. The Python memory manager thus delegates some of the work to the object-specific allocators, but ensures that the latter operate within the bounds of the private heap. It is important to understand that the management of the Python heap is performed by the interpreter itself and that the user has no control on it, even if she regularly manipulates object pointers to memory blocks inside that heap. The allocation of heap space for Python objects and other internal buffers is performed on demand by the Python memory manager through the Python/C API functions listed in this document. To avoid memory corruption, extension writers should never try to operate on Python objects with the functions exported by the C library: \cfunction{malloc()}\ttindex{malloc()}, \cfunction{calloc()}\ttindex{calloc()}, \cfunction{realloc()}\ttindex{realloc()} and \cfunction{free()}\ttindex{free()}. This will result in mixed calls between the C allocator and the Python memory manager with fatal consequences, because they implement different algorithms and operate on different heaps. However, one may safely allocate and release memory blocks with the C library allocator for individual purposes, as shown in the following example: \begin{verbatim} PyObject *res; char *buf = (char *) malloc(BUFSIZ); /* for I/O */ if (buf == NULL) return PyErr_NoMemory(); ...Do some I/O operation involving buf... res = PyString_FromString(buf); free(buf); /* malloc'ed */ return res; \end{verbatim} In this example, the memory request for the I/O buffer is handled by the C library allocator. The Python memory manager is involved only in the allocation of the string object returned as a result. In most situations, however, it is recommended to allocate memory from the Python heap specifically because the latter is under control of the Python memory manager. For example, this is required when the interpreter is extended with new object types written in C. Another reason for using the Python heap is the desire to \emph{inform} the Python memory manager about the memory needs of the extension module. Even when the requested memory is used exclusively for internal, highly-specific purposes, delegating all memory requests to the Python memory manager causes the interpreter to have a more accurate image of its memory footprint as a whole. Consequently, under certain circumstances, the Python memory manager may or may not trigger appropriate actions, like garbage collection, memory compaction or other preventive procedures. Note that by using the C library allocator as shown in the previous example, the allocated memory for the I/O buffer escapes completely the Python memory manager. \section{Memory Interface \label{memoryInterface}} The following function sets, modeled after the ANSI C standard, are available for allocating and releasing memory from the Python heap: \begin{cfuncdesc}{void*}{PyMem_Malloc}{size_t n} Allocates \var{n} bytes and returns a pointer of type \ctype{void*} to the allocated memory, or \NULL{} if the request fails. Requesting zero bytes returns a non-\NULL{} pointer. The memory will not have been initialized in any way. \end{cfuncdesc} \begin{cfuncdesc}{void*}{PyMem_Realloc}{void *p, size_t n} Resizes the memory block pointed to by \var{p} to \var{n} bytes. The contents will be unchanged to the minimum of the old and the new sizes. If \var{p} is \NULL, the call is equivalent to \cfunction{PyMem_Malloc(\var{n})}; if \var{n} is equal to zero, the memory block is resized but is not freed, and the returned pointer is non-\NULL. Unless \var{p} is \NULL, it must have been returned by a previous call to \cfunction{PyMem_Malloc()} or \cfunction{PyMem_Realloc()}. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyMem_Free}{void *p} Frees the memory block pointed to by \var{p}, which must have been returned by a previous call to \cfunction{PyMem_Malloc()} or \cfunction{PyMem_Realloc()}. Otherwise, or if \cfunction{PyMem_Free(p)} has been called before, undefined behaviour occurs. If \var{p} is \NULL, no operation is performed. \end{cfuncdesc} The following type-oriented macros are provided for convenience. Note that \var{TYPE} refers to any C type. \begin{cfuncdesc}{\var{TYPE}*}{PyMem_New}{TYPE, size_t n} Same as \cfunction{PyMem_Malloc()}, but allocates \code{(\var{n} * sizeof(\var{TYPE}))} bytes of memory. Returns a pointer cast to \ctype{\var{TYPE}*}. The memory will not have been initialized in any way. \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyMem_Resize}{void *p, TYPE, size_t n} Same as \cfunction{PyMem_Realloc()}, but the memory block is resized to \code{(\var{n} * sizeof(\var{TYPE}))} bytes. Returns a pointer cast to \ctype{\var{TYPE}*}. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyMem_Del}{void *p} Same as \cfunction{PyMem_Free()}. \end{cfuncdesc} In addition, the following macro sets are provided for calling the Python memory allocator directly, without involving the C API functions listed above. However, note that their use does not preserve binary compatibility accross Python versions and is therefore deprecated in extension modules. \cfunction{PyMem_MALLOC()}, \cfunction{PyMem_REALLOC()}, \cfunction{PyMem_FREE()}. \cfunction{PyMem_NEW()}, \cfunction{PyMem_RESIZE()}, \cfunction{PyMem_DEL()}. \section{Examples \label{memoryExamples}} Here is the example from section \ref{memoryOverview}, rewritten so that the I/O buffer is allocated from the Python heap by using the first function set: \begin{verbatim} PyObject *res; char *buf = (char *) PyMem_Malloc(BUFSIZ); /* for I/O */ if (buf == NULL) return PyErr_NoMemory(); /* ...Do some I/O operation involving buf... */ res = PyString_FromString(buf); PyMem_Free(buf); /* allocated with PyMem_Malloc */ return res; \end{verbatim} The same code using the type-oriented function set: \begin{verbatim} PyObject *res; char *buf = PyMem_New(char, BUFSIZ); /* for I/O */ if (buf == NULL) return PyErr_NoMemory(); /* ...Do some I/O operation involving buf... */ res = PyString_FromString(buf); PyMem_Del(buf); /* allocated with PyMem_New */ return res; \end{verbatim} Note that in the two examples above, the buffer is always manipulated via functions belonging to the same set. Indeed, it is required to use the same memory API family for a given memory block, so that the risk of mixing different allocators is reduced to a minimum. The following code sequence contains two errors, one of which is labeled as \emph{fatal} because it mixes two different allocators operating on different heaps. \begin{verbatim} char *buf1 = PyMem_New(char, BUFSIZ); char *buf2 = (char *) malloc(BUFSIZ); char *buf3 = (char *) PyMem_Malloc(BUFSIZ); ... PyMem_Del(buf3); /* Wrong -- should be PyMem_Free() */ free(buf2); /* Right -- allocated via malloc() */ free(buf1); /* Fatal -- should be PyMem_Del() */ \end{verbatim} In addition to the functions aimed at handling raw memory blocks from the Python heap, objects in Python are allocated and released with \cfunction{PyObject_New()}, \cfunction{PyObject_NewVar()} and \cfunction{PyObject_Del()}, or with their corresponding macros \cfunction{PyObject_NEW()}, \cfunction{PyObject_NEW_VAR()} and \cfunction{PyObject_DEL()}. These will be explained in the next chapter on defining and implementing new object types in C. --- NEW FILE: newtypes.tex --- \chapter{Defining New Object Types \label{newTypes}} \section{Allocating Objects on the Heap \label{allocating-objects}} \begin{cfuncdesc}{PyObject*}{_PyObject_New}{PyTypeObject *type} \end{cfuncdesc} \begin{cfuncdesc}{PyVarObject*}{_PyObject_NewVar}{PyTypeObject *type, int size} \end{cfuncdesc} \begin{cfuncdesc}{void}{_PyObject_Del}{PyObject *op} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyObject_Init}{PyObject *op, PyTypeObject *type} Initialize a newly-allocated object \var{op} with its type and initial reference. Returns the initialized object. If \var{type} indicates that the object participates in the cyclic garbage detector, it it added to the detector's set of observed objects. Other fields of the object are not affected. \end{cfuncdesc} \begin{cfuncdesc}{PyVarObject*}{PyObject_InitVar}{PyVarObject *op, PyTypeObject *type, int size} This does everything \cfunction{PyObject_Init()} does, and also initializes the length information for a variable-size object. \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_New}{TYPE, PyTypeObject *type} Allocate a new Python object using the C structure type \var{TYPE} and the Python type object \var{type}. Fields not defined by the Python object header are not initialized; the object's reference count will be one. The size of the memory allocation is determined from the \member{tp_basicsize} field of the type object. \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NewVar}{TYPE, PyTypeObject *type, int size} Allocate a new Python object using the C structure type \var{TYPE} and the Python type object \var{type}. Fields not defined by the Python object header are not initialized. The allocated memory allows for the \var{TYPE} structure plus \var{size} fields of the size given by the \member{tp_itemsize} field of \var{type}. This is useful for implementing objects like tuples, which are able to determine their size at construction time. Embedding the array of fields into the same allocation decreases the number of allocations, improving the memory management efficiency. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyObject_Del}{PyObject *op} Releases memory allocated to an object using \cfunction{PyObject_New()} or \cfunction{PyObject_NewVar()}. This is normally called from the \member{tp_dealloc} handler specified in the object's type. The fields of the object should not be accessed after this call as the memory is no longer a valid Python object. \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NEW}{TYPE, PyTypeObject *type} Macro version of \cfunction{PyObject_New()}, to gain performance at the expense of safety. This does not check \var{type} for a \NULL{} value. \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_NEW_VAR}{TYPE, PyTypeObject *type, int size} Macro version of \cfunction{PyObject_NewVar()}, to gain performance at the expense of safety. This does not check \var{type} for a \NULL{} value. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyObject_DEL}{PyObject *op} Macro version of \cfunction{PyObject_Del()}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{Py_InitModule}{char *name, PyMethodDef *methods} Create a new module object based on a name and table of functions, returning the new module object. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{Py_InitModule3}{char *name, PyMethodDef *methods, char *doc} Create a new module object based on a name and table of functions, returning the new module object. If \var{doc} is non-\NULL, it will be used to define the docstring for the module. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{Py_InitModule4}{char *name, PyMethodDef *methods, char *doc, PyObject *self, int apiver} Create a new module object based on a name and table of functions, returning the new module object. If \var{doc} is non-\NULL, it will be used to define the docstring for the module. If \var{self} is non-\NULL, it will passed to the functions of the module as their (otherwise \NULL) first parameter. (This was added as an experimental feature, and there are no known uses in the current version of Python.) For \var{apiver}, the only value which should be passed is defined by the constant \constant{PYTHON_API_VERSION}. \note{Most uses of this function should probably be using the \cfunction{Py_InitModule3()} instead; only use this if you are sure you need it.} \end{cfuncdesc} DL_IMPORT \begin{cvardesc}{PyObject}{_Py_NoneStruct} Object which is visible in Python as \code{None}. This should only be accessed using the \code{Py_None} macro, which evaluates to a pointer to this object. \end{cvardesc} \section{Common Object Structures \label{common-structs}} PyObject, PyVarObject PyObject_HEAD, PyObject_HEAD_INIT, PyObject_VAR_HEAD Typedefs: unaryfunc, binaryfunc, ternaryfunc, inquiry, coercion, intargfunc, intintargfunc, intobjargproc, intintobjargproc, objobjargproc, destructor, printfunc, getattrfunc, getattrofunc, setattrfunc, setattrofunc, cmpfunc, reprfunc, hashfunc \begin{ctypedesc}{PyCFunction} Type of the functions used to implement most Python callables in C. \end{ctypedesc} \begin{ctypedesc}{PyMethodDef} Structure used to describe a method of an extension type. This structure has four fields: \begin{tableiii}{l|l|l}{member}{Field}{C Type}{Meaning} \lineiii{ml_name}{char *}{name of the method} \lineiii{ml_meth}{PyCFunction}{pointer to the C implementation} \lineiii{ml_flags}{int}{flag bits indicating how the call should be constructed} \lineiii{ml_doc}{char *}{points to the contents of the docstring} \end{tableiii} \end{ctypedesc} The \member{ml_meth} is a C function pointer. The functions may be of different types, but they always return \ctype{PyObject*}. If the function is not of the \ctype{PyCFunction}, the compiler will require a cast in the method table. Even though \ctype{PyCFunction} defines the first parameter as \ctype{PyObject*}, it is common that the method implementation uses a the specific C type of the \var{self} object. The flags can have the following values. Only \constant{METH_VARARGS} and \constant{METH_KEYWORDS} can be combined; the others can't. \begin{datadesc}{METH_VARARGS} This is the typical calling convention, where the methods have the type \ctype{PyMethodDef}. The function expects two \ctype{PyObject*}. The first one is the \var{self} object for methods; for module functions, it has the value given to \cfunction{Py_InitModule4()} (or \NULL{} if \cfunction{Py_InitModule()} was used). The second parameter (often called \var{args}) is a tuple object representing all arguments. This parameter is typically processed using \cfunction{PyArg_ParseTuple()}. \end{datadesc} \begin{datadesc}{METH_KEYWORDS} Methods with these flags must be of type \ctype{PyCFunctionWithKeywords}. The function expects three parameters: \var{self}, \var{args}, and a dictionary of all the keyword arguments. The flag is typically combined with \constant{METH_VARARGS}, and the parameters are typically processed using \cfunction{PyArg_ParseTupleAndKeywords()}. \end{datadesc} \begin{datadesc}{METH_NOARGS} Methods without parameters don't need to check whether arguments are given if they are listed with the \constant{METH_NOARGS} flag. They need to be of type \ctype{PyNoArgsFunction}: they expect a single single \ctype{PyObject*} as a parameter. When used with object methods, this parameter is typically named \code{self} and will hold a reference to the object instance. \end{datadesc} \begin{datadesc}{METH_O} Methods with a single object argument can be listed with the \constant{METH_O} flag, instead of invoking \cfunction{PyArg_ParseTuple()} with a \code{"O"} argument. They have the type \ctype{PyCFunction}, with the \var{self} parameter, and a \ctype{PyObject*} parameter representing the single argument. \end{datadesc} \begin{datadesc}{METH_OLDARGS} This calling convention is deprecated. The method must be of type \ctype{PyCFunction}. The second argument is \NULL{} if no arguments are given, a single object if exactly one argument is given, and a tuple of objects if more than one argument is given. There is no way for a function using this convention to distinguish between a call with multiple arguments and a call with a tuple as the only argument. \end{datadesc} \begin{cfuncdesc}{PyObject*}{Py_FindMethod}{PyMethodDef table[], PyObject *ob, char *name} Return a bound method object for an extension type implemented in C. This function also handles the special attribute \member{__methods__}, returning a list of all the method names defined in \var{table}. \end{cfuncdesc} \section{Mapping Object Structures \label{mapping-structs}} \begin{ctypedesc}{PyMappingMethods} Structure used to hold pointers to the functions used to implement the mapping protocol for an extension type. \end{ctypedesc} \section{Number Object Structures \label{number-structs}} \begin{ctypedesc}{PyNumberMethods} Structure used to hold pointers to the functions an extension type uses to implement the number protocol. \end{ctypedesc} \section{Sequence Object Structures \label{sequence-structs}} \begin{ctypedesc}{PySequenceMethods} Structure used to hold pointers to the functions which an object uses to implement the sequence protocol. \end{ctypedesc} \section{Buffer Object Structures \label{buffer-structs}} \sectionauthor{Greg J. Stein}{greg@lyra.org} The buffer interface exports a model where an object can expose its internal data as a set of chunks of data, where each chunk is specified as a pointer/length pair. These chunks are called \dfn{segments} and are presumed to be non-contiguous in memory. If an object does not export the buffer interface, then its \member{tp_as_buffer} member in the \ctype{PyTypeObject} structure should be \NULL. Otherwise, the \member{tp_as_buffer} will point to a \ctype{PyBufferProcs} structure. \note{It is very important that your \ctype{PyTypeObject} structure uses \constant{Py_TPFLAGS_DEFAULT} for the value of the \member{tp_flags} member rather than \code{0}. This tells the Python runtime that your \ctype{PyBufferProcs} structure contains the \member{bf_getcharbuffer} slot. Older versions of Python did not have this member, so a new Python interpreter using an old extension needs to be able to test for its presence before using it.} \begin{ctypedesc}{PyBufferProcs} Structure used to hold the function pointers which define an implementation of the buffer protocol. The first slot is \member{bf_getreadbuffer}, of type \ctype{getreadbufferproc}. If this slot is \NULL, then the object does not support reading from the internal data. This is non-sensical, so implementors should fill this in, but callers should test that the slot contains a non-\NULL{} value. The next slot is \member{bf_getwritebuffer} having type \ctype{getwritebufferproc}. This slot may be \NULL{} if the object does not allow writing into its returned buffers. The third slot is \member{bf_getsegcount}, with type \ctype{getsegcountproc}. This slot must not be \NULL{} and is used to inform the caller how many segments the object contains. Simple objects such as \ctype{PyString_Type} and \ctype{PyBuffer_Type} objects contain a single segment. The last slot is \member{bf_getcharbuffer}, of type \ctype{getcharbufferproc}. This slot will only be present if the \constant{Py_TPFLAGS_HAVE_GETCHARBUFFER} flag is present in the \member{tp_flags} field of the object's \ctype{PyTypeObject}. Before using this slot, the caller should test whether it is present by using the \cfunction{PyType_HasFeature()}\ttindex{PyType_HasFeature()} function. If present, it may be \NULL, indicating that the object's contents cannot be used as \emph{8-bit characters}. The slot function may also raise an error if the object's contents cannot be interpreted as 8-bit characters. For example, if the object is an array which is configured to hold floating point values, an exception may be raised if a caller attempts to use \member{bf_getcharbuffer} to fetch a sequence of 8-bit characters. This notion of exporting the internal buffers as ``text'' is used to distinguish between objects that are binary in nature, and those which have character-based content. \note{The current policy seems to state that these characters may be multi-byte characters. This implies that a buffer size of \var{N} does not mean there are \var{N} characters present.} \end{ctypedesc} \begin{datadesc}{Py_TPFLAGS_HAVE_GETCHARBUFFER} Flag bit set in the type structure to indicate that the \member{bf_getcharbuffer} slot is known. This being set does not indicate that the object supports the buffer interface or that the \member{bf_getcharbuffer} slot is non-\NULL. \end{datadesc} \begin{ctypedesc}[getreadbufferproc]{int (*getreadbufferproc) (PyObject *self, int segment, void **ptrptr)} Return a pointer to a readable segment of the buffer. This function is allowed to raise an exception, in which case it must return \code{-1}. The \var{segment} which is passed must be zero or positive, and strictly less than the number of segments returned by the \member{bf_getsegcount} slot function. On success, it returns the length of the buffer memory, and sets \code{*\var{ptrptr}} to a pointer to that memory. \end{ctypedesc} \begin{ctypedesc}[getwritebufferproc]{int (*getwritebufferproc) (PyObject *self, int segment, void **ptrptr)} Return a pointer to a writable memory buffer in \code{*\var{ptrptr}}, and the length of that segment as the function return value. The memory buffer must correspond to buffer segment \var{segment}. Must return \code{-1} and set an exception on error. \exception{TypeError} should be raised if the object only supports read-only buffers, and \exception{SystemError} should be raised when \var{segment} specifies a segment that doesn't exist. % Why doesn't it raise ValueError for this one? % GJS: because you shouldn't be calling it with an invalid % segment. That indicates a blatant programming error in the C % code. \end{ctypedesc} \begin{ctypedesc}[getsegcountproc]{int (*getsegcountproc) (PyObject *self, int *lenp)} Return the number of memory segments which comprise the buffer. If \var{lenp} is not \NULL, the implementation must report the sum of the sizes (in bytes) of all segments in \code{*\var{lenp}}. The function cannot fail. \end{ctypedesc} \begin{ctypedesc}[getcharbufferproc]{int (*getcharbufferproc) (PyObject *self, int segment, const char **ptrptr)} \end{ctypedesc} \section{Supporting the Iterator Protocol \label{supporting-iteration}} \section{Supporting Cyclic Garbarge Collection \label{supporting-cycle-detection}} Python's support for detecting and collecting garbage which involves circular references requires support from object types which are ``containers'' for other objects which may also be containers. Types which do not store references to other objects, or which only store references to atomic types (such as numbers or strings), do not need to provide any explicit support for garbage collection. To create a container type, the \member{tp_flags} field of the type object must include the \constant{Py_TPFLAGS_HAVE_GC} and provide an implementation of the \member{tp_traverse} handler. If instances of the type are mutable, a \member{tp_clear} implementation must also be provided. \begin{datadesc}{Py_TPFLAGS_HAVE_GC} Objects with a type with this flag set must conform with the rules documented here. For convenience these objects will be referred to as container objects. \end{datadesc} Constructors for container types must conform to two rules: \begin{enumerate} \item The memory for the object must be allocated using \cfunction{PyObject_GC_New()} or \cfunction{PyObject_GC_VarNew()}. \item Once all the fields which may contain references to other containers are initialized, it must call \cfunction{PyObject_GC_Track()}. \end{enumerate} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_GC_New}{TYPE, PyTypeObject *type} Analogous to \cfunction{PyObject_New()} but for container objects with the \constant{Py_TPFLAGS_HAVE_GC} flag set. \end{cfuncdesc} \begin{cfuncdesc}{\var{TYPE}*}{PyObject_GC_NewVar}{TYPE, PyTypeObject *type, int size} Analogous to \cfunction{PyObject_NewVar()} but for container objects with the \constant{Py_TPFLAGS_HAVE_GC} flag set. \end{cfuncdesc} \begin{cfuncdesc}{PyVarObject *}{PyObject_GC_Resize}{PyVarObject *op, int} Resize an object allocated by \cfunction{PyObject_NewVar()}. Returns the resized object or \NULL{} on failure. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyObject_GC_Track}{PyObject *op} Adds the object \var{op} to the set of container objects tracked by the collector. The collector can run at unexpected times so objects must be valid while being tracked. This should be called once all the fields followed by the \member{tp_traverse} handler become valid, usually near the end of the constructor. \end{cfuncdesc} \begin{cfuncdesc}{void}{_PyObject_GC_TRACK}{PyObject *op} A macro version of \cfunction{PyObject_GC_Track()}. It should not be used for extension modules. \end{cfuncdesc} Similarly, the deallocator for the object must conform to a similar pair of rules: \begin{enumerate} \item Before fields which refer to other containers are invalidated, \cfunction{PyObject_GC_UnTrack()} must be called. \item The object's memory must be deallocated using \cfunction{PyObject_GC_Del()}. \end{enumerate} \begin{cfuncdesc}{void}{PyObject_GC_Del}{PyObject *op} Releases memory allocated to an object using \cfunction{PyObject_GC_New()} or \cfunction{PyObject_GC_NewVar()}. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyObject_GC_UnTrack}{PyObject *op} Remove the object \var{op} from the set of container objects tracked by the collector. Note that \cfunction{PyObject_GC_Track()} can be called again on this object to add it back to the set of tracked objects. The deallocator (\member{tp_dealloc} handler) should call this for the object before any of the fields used by the \member{tp_traverse} handler become invalid. \end{cfuncdesc} \begin{cfuncdesc}{void}{_PyObject_GC_UNTRACK}{PyObject *op} A macro version of \cfunction{PyObject_GC_UnTrack()}. It should not be used for extension modules. \end{cfuncdesc} The \member{tp_traverse} handler accepts a function parameter of this type: \begin{ctypedesc}[visitproc]{int (*visitproc)(PyObject *object, void *arg)} Type of the visitor function passed to the \member{tp_traverse} handler. The function should be called with an object to traverse as \var{object} and the third parameter to the \member{tp_traverse} handler as \var{arg}. \end{ctypedesc} The \member{tp_traverse} handler must have the following type: \begin{ctypedesc}[traverseproc]{int (*traverseproc)(PyObject *self, visitproc visit, void *arg)} Traversal function for a container object. Implementations must call the \var{visit} function for each object directly contained by \var{self}, with the parameters to \var{visit} being the contained object and the \var{arg} value passed to the handler. If \var{visit} returns a non-zero value then an error has occurred and that value should be returned immediately. \end{ctypedesc} The \member{tp_clear} handler must be of the \ctype{inquiry} type, or \NULL{} if the object is immutable. \begin{ctypedesc}[inquiry]{int (*inquiry)(PyObject *self)} Drop references that may have created reference cycles. Immutable objects do not have to define this method since they can never directly create reference cycles. Note that the object must still be valid after calling this method (don't just call \cfunction{Py_DECREF()} on a reference). The collector will call this method if it detects that this object is involved in a reference cycle. \end{ctypedesc} \subsection{Example Cycle Collector Support \label{example-cycle-support}} This example shows only enough of the implementation of an extension type to show how the garbage collector support needs to be added. It shows the definition of the object structure, the \member{tp_traverse}, \member{tp_clear} and \member{tp_dealloc} implementations, the type structure, and a constructor --- the module initialization needed to export the constructor to Python is not shown as there are no special considerations there for the collector. To make this interesting, assume that the module exposes ways for the \member{container} field of the object to be modified. Note that since no checks are made on the type of the object used to initialize \member{container}, we have to assume that it may be a container. \begin{verbatim} #include "Python.h" typedef struct { PyObject_HEAD PyObject *container; } MyObject; static int my_traverse(MyObject *self, visitproc visit, void *arg) { if (self->container != NULL) return visit(self->container, arg); else return 0; } static int my_clear(MyObject *self) { Py_XDECREF(self->container); self->container = NULL; return 0; } static void my_dealloc(MyObject *self) { PyObject_GC_UnTrack((PyObject *) self); Py_XDECREF(self->container); PyObject_GC_Del(self); } \end{verbatim} \begin{verbatim} statichere PyTypeObject MyObject_Type = { PyObject_HEAD_INIT(NULL) 0, "MyObject", sizeof(MyObject), 0, (destructor)my_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* 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_HAVE_GC, 0, /* tp_doc */ (traverseproc)my_traverse, /* tp_traverse */ (inquiry)my_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ }; /* This constructor should be made accessible from Python. */ static PyObject * new_object(PyObject *unused, PyObject *args) { PyObject *container = NULL; MyObject *result = NULL; if (PyArg_ParseTuple(args, "|O:new_object", &container)) { result = PyObject_GC_New(MyObject, &MyObject_Type); if (result != NULL) { result->container = container; PyObject_GC_Track(result); } } return (PyObject *) result; } \end{verbatim} --- NEW FILE: refcounting.tex --- \chapter{Reference Counting \label{countingRefs}} The macros in this section are used for managing reference counts of Python objects. \begin{cfuncdesc}{void}{Py_INCREF}{PyObject *o} Increment the reference count for object \var{o}. The object must not be \NULL; if you aren't sure that it isn't \NULL, use \cfunction{Py_XINCREF()}. \end{cfuncdesc} \begin{cfuncdesc}{void}{Py_XINCREF}{PyObject *o} Increment the reference count for object \var{o}. The object may be \NULL, in which case the macro has no effect. \end{cfuncdesc} \begin{cfuncdesc}{void}{Py_DECREF}{PyObject *o} Decrement the reference count for object \var{o}. The object must not be \NULL; if you aren't sure that it isn't \NULL, use \cfunction{Py_XDECREF()}. If the reference count reaches zero, the object's type's deallocation function (which must not be \NULL) is invoked. \warning{The deallocation function can cause arbitrary Python code to be invoked (e.g. when a class instance with a \method{__del__()} method is deallocated). While exceptions in such code are not propagated, the executed code has free access to all Python global variables. This means that any object that is reachable from a global variable should be in a consistent state before \cfunction{Py_DECREF()} is invoked. For example, code to delete an object from a list should copy a reference to the deleted object in a temporary variable, update the list data structure, and then call \cfunction{Py_DECREF()} for the temporary variable.} \end{cfuncdesc} \begin{cfuncdesc}{void}{Py_XDECREF}{PyObject *o} Decrement the reference count for object \var{o}. The object may be \NULL, in which case the macro has no effect; otherwise the effect is the same as for \cfunction{Py_DECREF()}, and the same warning applies. \end{cfuncdesc} The following functions or macros are only for use within the interpreter core: \cfunction{_Py_Dealloc()}, \cfunction{_Py_ForgetReference()}, \cfunction{_Py_NewReference()}, as well as the global variable \cdata{_Py_RefTotal}. --- NEW FILE: utilities.tex --- \chapter{Utilities \label{utilities}} The functions in this chapter perform various utility tasks, ranging from helping C code be more portable across platforms, using Python modules from C, and parsing function arguments and constructing Python values from C values. \section{Operating System Utilities \label{os}} \begin{cfuncdesc}{int}{Py_FdIsInteractive}{FILE *fp, char *filename} Return true (nonzero) if the standard I/O file \var{fp} with name \var{filename} is deemed interactive. This is the case for files for which \samp{isatty(fileno(\var{fp}))} is true. If the global flag \cdata{Py_InteractiveFlag} is true, this function also returns true if the \var{filename} pointer is \NULL{} or if the name is equal to one of the strings \code{''} or \code{'???'}. \end{cfuncdesc} \begin{cfuncdesc}{long}{PyOS_GetLastModificationTime}{char *filename} Return the time of last modification of the file \var{filename}. The result is encoded in the same way as the timestamp returned by the standard C library function \cfunction{time()}. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyOS_AfterFork}{} Function to update some internal state after a process fork; this should be called in the new process if the Python interpreter will continue to be used. If a new executable is loaded into the new process, this function does not need to be called. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyOS_CheckStack}{} Return true when the interpreter runs out of stack space. This is a reliable check, but is only available when \constant{USE_STACKCHECK} is defined (currently on Windows using the Microsoft Visual \Cpp{} compiler and on the Macintosh). \constant{USE_CHECKSTACK} will be defined automatically; you should never change the definition in your own code. \end{cfuncdesc} \begin{cfuncdesc}{PyOS_sighandler_t}{PyOS_getsig}{int i} Return the current signal handler for signal \var{i}. This is a thin wrapper around either \cfunction{sigaction()} or \cfunction{signal()}. Do not call those functions directly! \ctype{PyOS_sighandler_t} is a typedef alias for \ctype{void (*)(int)}. \end{cfuncdesc} \begin{cfuncdesc}{PyOS_sighandler_t}{PyOS_setsig}{int i, PyOS_sighandler_t h} Set the signal handler for signal \var{i} to be \var{h}; return the old signal handler. This is a thin wrapper around either \cfunction{sigaction()} or \cfunction{signal()}. Do not call those functions directly! \ctype{PyOS_sighandler_t} is a typedef alias for \ctype{void (*)(int)}. \end{cfuncdesc} \section{Process Control \label{processControl}} \begin{cfuncdesc}{void}{Py_FatalError}{char *message} Print a fatal error message and kill the process. No cleanup is performed. This function should only be invoked when a condition is detected that would make it dangerous to continue using the Python interpreter; e.g., when the object administration appears to be corrupted. On \UNIX, the standard C library function \cfunction{abort()}\ttindex{abort()} is called which will attempt to produce a \file{core} file. \end{cfuncdesc} \begin{cfuncdesc}{void}{Py_Exit}{int status} Exit the current process. This calls \cfunction{Py_Finalize()}\ttindex{Py_Finalize()} and then calls the standard C library function \code{exit(\var{status})}\ttindex{exit()}. \end{cfuncdesc} \begin{cfuncdesc}{int}{Py_AtExit}{void (*func) ()} Register a cleanup function to be called by \cfunction{Py_Finalize()}\ttindex{Py_Finalize()}. The cleanup function will be called with no arguments and should return no value. At most 32 \index{cleanup functions}cleanup functions can be registered. When the registration is successful, \cfunction{Py_AtExit()} returns \code{0}; on failure, it returns \code{-1}. The cleanup function registered last is called first. Each cleanup function will be called at most once. Since Python's internal finallization will have completed before the cleanup function, no Python APIs should be called by \var{func}. \end{cfuncdesc} \section{Importing Modules \label{importing}} \begin{cfuncdesc}{PyObject*}{PyImport_ImportModule}{char *name} This is a simplified interface to \cfunction{PyImport_ImportModuleEx()} below, leaving the \var{globals} and \var{locals} arguments set to \NULL. When the \var{name} argument contains a dot (when it specifies a submodule of a package), the \var{fromlist} argument is set to the list \code{['*']} so that the return value is the named module rather than the top-level package containing it as would otherwise be the case. (Unfortunately, this has an additional side effect when \var{name} in fact specifies a subpackage instead of a submodule: the submodules specified in the package's \code{__all__} variable are \index{package variable!\code{__all__}} \withsubitem{(package variable)}{\ttindex{__all__}}loaded.) Return a new reference to the imported module, or \NULL{} with an exception set on failure (the module may still be created in this case --- examine \code{sys.modules} to find out). \withsubitem{(in module sys)}{\ttindex{modules}} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyImport_ImportModuleEx}{char *name, PyObject *globals, PyObject *locals, PyObject *fromlist} Import a module. This is best described by referring to the built-in Python function \function{__import__()}\bifuncindex{__import__}, as the standard \function{__import__()} function calls this function directly. The return value is a new reference to the imported module or top-level package, or \NULL{} with an exception set on failure (the module may still be created in this case). Like for \function{__import__()}, the return value when a submodule of a package was requested is normally the top-level package, unless a non-empty \var{fromlist} was given. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyImport_Import}{PyObject *name} This is a higher-level interface that calls the current ``import hook function''. It invokes the \function{__import__()} function from the \code{__builtins__} of the current globals. This means that the import is done using whatever import hooks are installed in the current environment, e.g. by \module{rexec}\refstmodindex{rexec} or \module{ihooks}\refstmodindex{ihooks}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyImport_ReloadModule}{PyObject *m} Reload a module. This is best described by referring to the built-in Python function \function{reload()}\bifuncindex{reload}, as the standard \function{reload()} function calls this function directly. Return a new reference to the reloaded module, or \NULL{} with an exception set on failure (the module still exists in this case). \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyImport_AddModule}{char *name} Return the module object corresponding to a module name. The \var{name} argument may be of the form \code{package.module}). First check the modules dictionary if there's one there, and if not, create a new one and insert in in the modules dictionary. \note{This function does not load or import the module; if the module wasn't already loaded, you will get an empty module object. Use \cfunction{PyImport_ImportModule()} or one of its variants to import a module. Return \NULL{} with an exception set on failure.} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyImport_ExecCodeModule}{char *name, PyObject *co} Given a module name (possibly of the form \code{package.module}) and a code object read from a Python bytecode file or obtained from the built-in function \function{compile()}\bifuncindex{compile}, load the module. Return a new reference to the module object, or \NULL{} with an exception set if an error occurred (the module may still be created in this case). (This function would reload the module if it was already imported.) \end{cfuncdesc} \begin{cfuncdesc}{long}{PyImport_GetMagicNumber}{} Return the magic number for Python bytecode files (a.k.a. \file{.pyc} and \file{.pyo} files). The magic number should be present in the first four bytes of the bytecode file, in little-endian byte order. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyImport_GetModuleDict}{} Return the dictionary used for the module administration (a.k.a.\ \code{sys.modules}). Note that this is a per-interpreter variable. \end{cfuncdesc} \begin{cfuncdesc}{void}{_PyImport_Init}{} Initialize the import mechanism. For internal use only. \end{cfuncdesc} \begin{cfuncdesc}{void}{PyImport_Cleanup}{} Empty the module table. For internal use only. \end{cfuncdesc} \begin{cfuncdesc}{void}{_PyImport_Fini}{} Finalize the import mechanism. For internal use only. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{_PyImport_FindExtension}{char *, char *} For internal use only. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{_PyImport_FixupExtension}{char *, char *} For internal use only. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyImport_ImportFrozenModule}{char *name} Load a frozen module named \var{name}. Return \code{1} for success, \code{0} if the module is not found, and \code{-1} with an exception set if the initialization failed. To access the imported module on a successful load, use \cfunction{PyImport_ImportModule()}. (Note the misnomer --- this function would reload the module if it was already imported.) \end{cfuncdesc} \begin{ctypedesc}[_frozen]{struct _frozen} This is the structure type definition for frozen module descriptors, as generated by the \program{freeze}\index{freeze utility} utility (see \file{Tools/freeze/} in the Python source distribution). Its definition, found in \file{Include/import.h}, is: \begin{verbatim} struct _frozen { char *name; unsigned char *code; int size; }; \end{verbatim} \end{ctypedesc} \begin{cvardesc}{struct _frozen*}{PyImport_FrozenModules} This pointer is initialized to point to an array of \ctype{struct _frozen} records, terminated by one whose members are all \NULL{} or zero. When a frozen module is imported, it is searched in this table. Third-party code could play tricks with this to provide a dynamically created collection of frozen modules. \end{cvardesc} \begin{cfuncdesc}{int}{PyImport_AppendInittab}{char *name, void (*initfunc)(void)} Add a single module to the existing table of built-in modules. This is a convenience wrapper around \cfunction{PyImport_ExtendInittab()}, returning \code{-1} if the table could not be extended. The new module can be imported by the name \var{name}, and uses the function \var{initfunc} as the initialization function called on the first attempted import. This should be called before \cfunction{Py_Initialize()}. \end{cfuncdesc} \begin{ctypedesc}[_inittab]{struct _inittab} Structure describing a single entry in the list of built-in modules. Each of these structures gives the name and initialization function for a module built into the interpreter. Programs which embed Python may use an array of these structures in conjunction with \cfunction{PyImport_ExtendInittab()} to provide additional built-in modules. The structure is defined in \file{Include/import.h} as: \begin{verbatim} struct _inittab { char *name; void (*initfunc)(void); }; \end{verbatim} \end{ctypedesc} \begin{cfuncdesc}{int}{PyImport_ExtendInittab}{struct _inittab *newtab} Add a collection of modules to the table of built-in modules. The \var{newtab} array must end with a sentinel entry which contains \NULL{} for the \member{name} field; failure to provide the sentinel value can result in a memory fault. Returns \code{0} on success or \code{-1} if insufficient memory could be allocated to extend the internal table. In the event of failure, no modules are added to the internal table. This should be called before \cfunction{Py_Initialize()}. \end{cfuncdesc} \section{Parsing arguments and building values \label{arg-parsing}} These functions are useful when creating your own extensions functions and methods. Additional information and examples are available in \citetitle[../ext/ext.html]{Extending and Embedding the Python Interpreter}. \begin{cfuncdesc}{int}{PyArg_ParseTuple}{PyObject *args, char *format, \moreargs} Parse the parameters of a function that takes only positional parameters into local variables. Returns true on success; on failure, it returns false and raises the appropriate exception. See \citetitle[../ext/parseTuple.html]{Extending and Embedding the Python Interpreter} for more information. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyArg_ParseTupleAndKeywords}{PyObject *args, PyObject *kw, char *format, char *keywords[], \moreargs} Parse the parameters of a function that takes both positional and keyword parameters into local variables. Returns true on success; on failure, it returns false and raises the appropriate exception. See \citetitle[../ext/parseTupleAndKeywords.html]{Extending and Embedding the Python Interpreter} for more information. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyArg_Parse}{PyObject *args, char *format, \moreargs} Function used to deconstruct the argument lists of ``old-style'' functions --- these are functions which use the \constant{METH_OLDARGS} parameter parsing method. This is not recommended for use in parameter parsing in new code, and most code in the standard interpreter has been modified to no longer use this for that purpose. It does remain a convenient way to decompose other tuples, however, and may continue to be used for that purpose. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{Py_BuildValue}{char *format, \moreargs} Create a new value based on a format string similar to those accepted by the \cfunction{PyArg_Parse*()} family of functions and a sequence of values. Returns the value or \NULL{} in the case of an error; an exception will be raised if \NULL{} is returned. For more information on the format string and additional parameters, see \citetitle[../ext/buildValue.html]{Extending and Embedding the Python Interpreter}. \end{cfuncdesc} --- NEW FILE: veryhigh.tex --- \chapter{The Very High Level Layer \label{veryhigh}} The functions in this chapter will let you execute Python source code given in a file or a buffer, but they will not let you interact in a more detailed way with the interpreter. Several of these functions accept a start symbol from the grammar as a parameter. The available start symbols are \constant{Py_eval_input}, \constant{Py_file_input}, and \constant{Py_single_input}. These are described following the functions which accept them as parameters. Note also that several of these functions take \ctype{FILE*} parameters. On particular issue which needs to be handled carefully is that the \ctype{FILE} structure for different C libraries can be different and incompatible. Under Windows (at least), it is possible for dynamically linked extensions to actually use different libraries, so care should be taken that \ctype{FILE*} parameters are only passed to these functions if it is certain that they were created by the same library that the Python runtime is using. \begin{cfuncdesc}{int}{Py_Main}{int argc, char **argv} The main program for the standard interpreter. This is made available for programs which embed Python. The \var{argc} and \var{argv} parameters should be prepared exactly as those which are passed to a C program's \cfunction{main()} function. It is important to note that the argument list may be modified (but the contents of the strings pointed to by the argument list are not). The return value will be the integer passed to the \function{sys.exit()} function, \code{1} if the interpreter exits due to an exception, or \code{2} if the parameter list does not represent a valid Python command line. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyRun_AnyFile}{FILE *fp, char *filename} If \var{fp} refers to a file associated with an interactive device (console or terminal input or \UNIX{} pseudo-terminal), return the value of \cfunction{PyRun_InteractiveLoop()}, otherwise return the result of \cfunction{PyRun_SimpleFile()}. If \var{filename} is \NULL, this function uses \code{"???"} as the filename. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyRun_SimpleString}{char *command} Executes the Python source code from \var{command} in the \module{__main__} module. If \module{__main__} does not already exist, it is created. Returns \code{0} on success or \code{-1} if an exception was raised. If there was an error, there is no way to get the exception information. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyRun_SimpleFile}{FILE *fp, char *filename} Similar to \cfunction{PyRun_SimpleString()}, but the Python source code is read from \var{fp} instead of an in-memory string. \var{filename} should be the name of the file. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyRun_InteractiveOne}{FILE *fp, char *filename} Read and execute a single statement from a file associated with an interactive device. If \var{filename} is \NULL, \code{"???"} is used instead. The user will be prompted using \code{sys.ps1} and \code{sys.ps2}. Returns \code{0} when the input was executed successfully, \code{-1} if there was an exception, or an error code from the \file{errcode.h} include file distributed as part of Python if there was a parse error. (Note that \file{errcode.h} is not included by \file{Python.h}, so must be included specifically if needed.) \end{cfuncdesc} \begin{cfuncdesc}{int}{PyRun_InteractiveLoop}{FILE *fp, char *filename} Read and execute statements from a file associated with an interactive device until \EOF{} is reached. If \var{filename} is \NULL, \code{"???"} is used instead. The user will be prompted using \code{sys.ps1} and \code{sys.ps2}. Returns \code{0} at \EOF. \end{cfuncdesc} \begin{cfuncdesc}{struct _node*}{PyParser_SimpleParseString}{char *str, int start} Parse Python source code from \var{str} using the start token \var{start}. The result can be used to create a code object which can be evaluated efficiently. This is useful if a code fragment must be evaluated many times. \end{cfuncdesc} \begin{cfuncdesc}{struct _node*}{PyParser_SimpleParseFile}{FILE *fp, char *filename, int start} Similar to \cfunction{PyParser_SimpleParseString()}, but the Python source code is read from \var{fp} instead of an in-memory string. \var{filename} should be the name of the file. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyRun_String}{char *str, int start, PyObject *globals, PyObject *locals} Execute Python source code from \var{str} in the context specified by the dictionaries \var{globals} and \var{locals}. The parameter \var{start} specifies the start token that should be used to parse the source code. Returns the result of executing the code as a Python object, or \NULL{} if an exception was raised. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyRun_File}{FILE *fp, char *filename, int start, PyObject *globals, PyObject *locals} Similar to \cfunction{PyRun_String()}, but the Python source code is read from \var{fp} instead of an in-memory string. \var{filename} should be the name of the file. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{Py_CompileString}{char *str, char *filename, int start} Parse and compile the Python source code in \var{str}, returning the resulting code object. The start token is given by \var{start}; this can be used to constrain the code which can be compiled and should be \constant{Py_eval_input}, \constant{Py_file_input}, or \constant{Py_single_input}. The filename specified by \var{filename} is used to construct the code object and may appear in tracebacks or \exception{SyntaxError} exception messages. This returns \NULL{} if the code cannot be parsed or compiled. \end{cfuncdesc} \begin{cvardesc}{int}{Py_eval_input} The start symbol from the Python grammar for isolated expressions; for use with \cfunction{Py_CompileString()}\ttindex{Py_CompileString()}. \end{cvardesc} \begin{cvardesc}{int}{Py_file_input} The start symbol from the Python grammar for sequences of statements as read from a file or other source; for use with \cfunction{Py_CompileString()}\ttindex{Py_CompileString()}. This is the symbol to use when compiling arbitrarily long Python source code. \end{cvardesc} \begin{cvardesc}{int}{Py_single_input} The start symbol from the Python grammar for a single statement; for use with \cfunction{Py_CompileString()}\ttindex{Py_CompileString()}. This is the symbol used for the interactive interpreter loop. \end{cvardesc} Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.153 retrieving revision 1.154 diff -C2 -d -r1.153 -r1.154 *** api.tex 2001/10/05 22:03:58 1.153 --- api.tex 2001/10/12 19:01:43 1.154 *************** *** 27,34 **** writing but does not document the API functions in detail. ! \strong{Warning:} The current version of this document is incomplete. ! I hope that it is nevertheless useful. I will continue to work on it, ! and release new versions from time to time, independent from Python ! source code releases. \end{abstract} --- 27,34 ---- writing but does not document the API functions in detail. [...6142 lines suppressed...] ! } ! \end{verbatim} --- 36,50 ---- \tableofcontents ! \input{intro} ! \input{veryhigh} ! \input{refcounting} ! \input{exceptions} ! \input{utilities} ! \input{abstract} ! \input{concrete} ! \input{init} ! \input{memory} ! \input{newtypes} From fdrake@users.sourceforge.net Fri Oct 12 20:02:37 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 12 Oct 2001 12:02:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile.deps,1.76,1.77 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv12731 Modified Files: Makefile.deps Log Message: Add entries for the newly split C API manual. Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.76 retrieving revision 1.77 diff -C2 -d -r1.76 -r1.77 *** Makefile.deps 2001/10/05 16:49:31 1.76 --- Makefile.deps 2001/10/12 19:02:35 1.77 *************** *** 18,22 **** ! APIFILES= api/api.tex $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \ texinputs/reportingbugs.tex --- 18,33 ---- ! APIFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \ ! api/api.tex \ ! api/abstract.tex \ ! api/concrete.tex \ ! api/exceptions.tex \ ! api/init.tex \ ! api/intro.tex \ ! api/memory.tex \ ! api/newtypes.tex \ ! api/refcounting.tex \ ! api/utilities.tex \ ! api/veryhigh.tex \ texinputs/reportingbugs.tex From gvanrossum@users.sourceforge.net Fri Oct 12 21:01:55 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 12 Oct 2001 13:01:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.133,2.134 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv29995 Modified Files: fileobject.c Log Message: Band-aid solution to SF bug #470634: readlines() on linux requires 2 ^D's. The problem is that if fread() returns a short count, we attempt another fread() the next time through the loop, and apparently glibc clears or ignores the eof condition so the second fread() requires another ^D to make it see the eof condition. According to the man page (and the C std, I hope) fread() can only return a short count on error or eof. I'm using that in the band-aid solution to avoid calling fread() a second time after a short read. Note that xreadlines() still has this problem: it calls readlines(sizehint) until it gets a zero-length return. Since xreadlines() is mostly used for reading real files, I won't worry about this until we get a bug report. Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.133 retrieving revision 2.134 diff -C2 -d -r2.133 -r2.134 *** fileobject.c 2001/10/10 22:03:27 2.133 --- fileobject.c 2001/10/12 20:01:53 2.134 *************** *** 1046,1049 **** --- 1046,1050 ---- char *p, *q, *end; int err; + int shortread = 0; if (f->f_fp == NULL) *************** *** 1054,1061 **** return NULL; for (;;) { ! Py_BEGIN_ALLOW_THREADS ! errno = 0; ! nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp); ! Py_END_ALLOW_THREADS if (nread == 0) { sizehint = 0; --- 1055,1068 ---- return NULL; for (;;) { ! if (shortread) ! nread = 0; ! else { ! Py_BEGIN_ALLOW_THREADS ! errno = 0; ! nread = fread(buffer+nfilled, 1, ! buffersize-nfilled, f->f_fp); ! Py_END_ALLOW_THREADS ! shortread = (nread < buffersize-nfilled); ! } if (nread == 0) { sizehint = 0; From fdrake@users.sourceforge.net Fri Oct 12 21:50:22 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 12 Oct 2001 13:50:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/hotshot - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Lib/hotshot In directory usw-pr-cvs1:/tmp/cvs-serv14053/hotshot Log Message: Directory /cvsroot/python/python/dist/src/Lib/hotshot added to the repository From gvanrossum@users.sourceforge.net Fri Oct 12 21:52:51 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 12 Oct 2001 13:52:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules gcmodule.c,2.24,2.25 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv14756 Modified Files: gcmodule.c Log Message: Use double curly braces for the generation0/1/2 initializers, to shut up GCC warnings. Index: gcmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/gcmodule.c,v retrieving revision 2.24 retrieving revision 2.25 diff -C2 -d -r2.24 -r2.25 *** gcmodule.c 2001/10/11 18:31:31 2.24 --- gcmodule.c 2001/10/12 20:52:48 2.25 *************** *** 33,39 **** /* linked lists of container objects */ ! PyGC_Head _PyGC_generation0 = {&_PyGC_generation0, &_PyGC_generation0, 0}; ! static PyGC_Head generation1 = {&generation1, &generation1, 0}; ! static PyGC_Head generation2 = {&generation2, &generation2, 0}; static int generation = 0; /* current generation being collected */ --- 33,39 ---- /* linked lists of container objects */ ! PyGC_Head _PyGC_generation0 = {{&_PyGC_generation0, &_PyGC_generation0, 0}}; ! static PyGC_Head generation1 = {{&generation1, &generation1, 0}}; ! static PyGC_Head generation2 = {{&generation2, &generation2, 0}}; static int generation = 0; /* current generation being collected */ From fdrake@users.sourceforge.net Fri Oct 12 21:54:02 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 12 Oct 2001 13:54:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_hotshot.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv15172 Added Files: test_hotshot.py Log Message: A most trivial test for HotShot -- make sure we get reasonable events reported and can read the log back in. --- NEW FILE: test_hotshot.py --- import hotshot import hotshot.log import os import pprint import sys import unittest import warnings import test_support from hotshot.log import ENTER, EXIT, LINE def shortfilename(fn): # We use a really shortened filename since an exact match is made, # and the source may be either a Python source file or a # pre-compiled bytecode file. if fn: return os.path.splitext(os.path.basename(fn))[0] else: return fn class HotShotTestCase(unittest.TestCase): def new_profiler(self, lineevents=0, linetimings=1): self.logfn = test_support.TESTFN return hotshot.Profile(self.logfn, lineevents, linetimings) def get_logreader(self): log = hotshot.log.LogReader(self.logfn) os.unlink(self.logfn) return log def get_events_wotime(self): L = [] for event in self.get_logreader(): what, (filename, lineno, funcname), tdelta = event L.append((what, (shortfilename(filename), lineno, funcname))) return L def check_events(self, expected): events = self.get_events_wotime() if events != expected: self.fail( "events did not match expectation; got:\n%s\nexpected:\n%s" % (pprint.pformat(events), pprint.pformat(expected))) def run_test(self, callable, events, profiler=None): if profiler is None: profiler = self.new_profiler() profiler.runcall(callable) profiler.close() self.check_events(events) def test_line_numbers(self): def f(): y = 2 x = 1 def g(): f() f_lineno = f.func_code.co_firstlineno g_lineno = g.func_code.co_firstlineno events = [(ENTER, ("test_hotshot", g_lineno, "g")), (LINE, ("test_hotshot", g_lineno, "g")), (LINE, ("test_hotshot", g_lineno+1, "g")), (ENTER, ("test_hotshot", f_lineno, "f")), (LINE, ("test_hotshot", f_lineno, "f")), (LINE, ("test_hotshot", f_lineno+1, "f")), (LINE, ("test_hotshot", f_lineno+2, "f")), (EXIT, ("test_hotshot", f_lineno, "f")), (EXIT, ("test_hotshot", g_lineno, "g")), ] self.run_test(g, events, self.new_profiler(lineevents=1)) def test_main(): test_support.run_unittest(HotShotTestCase) if __name__ == "__main__": test_main() From fdrake@users.sourceforge.net Fri Oct 12 21:56:31 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 12 Oct 2001 13:56:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/hotshot __init__.py,NONE,1.1 log.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/hotshot In directory usw-pr-cvs1:/tmp/cvs-serv16013 Added Files: __init__.py log.py Log Message: Preliminary user-level interface to HotShot. We still need the analysis tool; look for that on Monday. --- NEW FILE: __init__.py --- """High-perfomance logging profiler, mostly written in C.""" import _hotshot from _hotshot import ProfilerError class Profile: def __init__(self, logfn, lineevents=0, linetimings=1): self.lineevents = lineevents and 1 or 0 self.linetimings = (linetimings and lineevents) and 1 or 0 self._prof = p = _hotshot.profiler( logfn, self.lineevents, self.linetimings) def close(self): self._prof.close() def start(self): self._prof.start() def stop(self): self._prof.stop() # These methods offer the same interface as the profile.Profile class, # but delegate most of the work to the C implementation underneath. def run(self, cmd): import __main__ dict = __main__.__dict__ return self.runctx(cmd, dict, dict) def runctx(self, cmd, globals, locals): code = compile(cmd, "", "exec") self._prof.runcode(code, globals, locals) return self def runcall(self, func, *args, **kw): self._prof.runcall(func, args, kw) --- NEW FILE: log.py --- import _hotshot import os.path import parser import symbol import sys from _hotshot import \ WHAT_ENTER, \ WHAT_EXIT, \ WHAT_LINENO, \ WHAT_DEFINE_FILE, \ WHAT_ADD_INFO __all__ = ["LogReader", "ENTER", "EXIT", "LINE"] ENTER = WHAT_ENTER EXIT = WHAT_EXIT LINE = WHAT_LINENO try: StopIteration except NameError: StopIteration = IndexError class LogReader: def __init__(self, logfn): # fileno -> filename self._filemap = {} # (fileno, lineno) -> filename, funcname self._funcmap = {} self._info = {} self._nextitem = _hotshot.logreader(logfn).next self._stack = [] # Iteration support: # This adds an optional (& ignored) parameter to next() so that the # same bound method can be used as the __getitem__() method -- this # avoids using an additional method call which kills the performance. def next(self, index=0): try: what, tdelta, fileno, lineno = self._nextitem() except TypeError: # logreader().next() returns None at the end raise StopIteration() if what == WHAT_DEFINE_FILE: self._filemap[fileno] = tdelta return self.next() if what == WHAT_ADD_INFO: key = tdelta.lower() try: L = self._info[key] except KeyError: L = [] self._info[key] = L L.append(lineno) if key == "current-directory": self.cwd = lineno return self.next() if what == WHAT_ENTER: t = self._decode_location(fileno, lineno) filename, funcname = t self._stack.append((filename, funcname, lineno)) elif what == WHAT_EXIT: filename, funcname, lineno = self._stack.pop() else: filename, funcname, firstlineno = self._stack[-1] return what, (filename, lineno, funcname), tdelta if sys.version < "2.2": # Don't add this for newer Python versions; we only want iteration # support, not general sequence support. __getitem__ = next else: def __iter__(self): return self # # helpers # def _decode_location(self, fileno, lineno): try: return self._funcmap[(fileno, lineno)] except KeyError: if self._loadfile(fileno): filename = funcname = None try: filename, funcname = self._funcmap[(fileno, lineno)] except KeyError: filename = self._filemap.get(fileno) funcname = None self._funcmap[(fileno, lineno)] = (filename, funcname) return filename, funcname def _loadfile(self, fileno): try: filename = self._filemap[fileno] except KeyError: print "Could not identify fileId", fileno return 1 if filename is None: return 1 absname = os.path.normcase(os.path.join(self.cwd, filename)) try: fp = open(absname) except IOError: return st = parser.suite(fp.read()) fp.close() # Scan the tree looking for def and lambda nodes, filling in # self._funcmap with all the available information. funcdef = symbol.funcdef lambdef = symbol.lambdef stack = [st.totuple(1)] while stack: tree = stack.pop() try: sym = tree[0] except (IndexError, TypeError): continue if sym == funcdef: self._funcmap[(fileno, tree[2][2])] = filename, tree[2][1] elif sym == lambdef: self._funcmap[(fileno, tree[1][2])] = filename, "" stack.extend(list(tree[1:])) From fdrake@users.sourceforge.net Fri Oct 12 21:57:57 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 12 Oct 2001 13:57:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _hotshot.c,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv16403/Modules Added Files: _hotshot.c Log Message: The HotShot core: look, ma, no hands! --- NEW FILE: _hotshot.c --- /* * This is the High Performance Python Profiler portion of HotShot. */ #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif /* * Which timer to use should be made more configurable, but that should not * be difficult. This will do fo now. */ #ifdef MS_WIN32 [...1329 lines suppressed...] Py_INCREF(&ProfilerType); PyModule_AddObject(module, "ProfilerType", (PyObject *)&ProfilerType); if (ProfilerError == NULL) ProfilerError = PyErr_NewException("hotshot.ProfilerError", NULL, NULL); if (ProfilerError != NULL) { Py_INCREF(ProfilerError); PyModule_AddObject(module, "ProfilerError", ProfilerError); } PyModule_AddIntConstant(module, "WHAT_ENTER", WHAT_ENTER); PyModule_AddIntConstant(module, "WHAT_EXIT", WHAT_EXIT); PyModule_AddIntConstant(module, "WHAT_LINENO", WHAT_LINENO); PyModule_AddIntConstant(module, "WHAT_OTHER", WHAT_OTHER); PyModule_AddIntConstant(module, "WHAT_ADD_INFO", WHAT_ADD_INFO); PyModule_AddIntConstant(module, "WHAT_DEFINE_FILE", WHAT_DEFINE_FILE); PyModule_AddIntConstant(module, "WHAT_LINE_TIMES", WHAT_LINE_TIMES); } } From fdrake@users.sourceforge.net Fri Oct 12 22:00:56 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 12 Oct 2001 14:00:56 -0700 Subject: [Python-checkins] CVS: python/dist/src setup.py,1.59,1.60 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv17427 Modified Files: setup.py Log Message: Add entry for HotShot. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -d -r1.59 -r1.60 *** setup.py 2001/10/08 13:18:37 1.59 --- setup.py 2001/10/12 21:00:48 1.60 *************** *** 213,216 **** --- 213,217 ---- exts.append( Extension('pcre', ['pcremodule.c', 'pypcre.c']) ) + exts.append( Extension('_hotshot', ['_hotshot.c']) ) exts.append( Extension('_weakref', ['_weakref.c']) ) exts.append( Extension('_symtable', ['symtablemodule.c']) ) From gvanrossum@users.sourceforge.net Fri Oct 12 22:49:19 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 12 Oct 2001 14:49:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python thread_pthread.h,2.32,2.33 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv25724 Modified Files: thread_pthread.h Log Message: Add SF patch #468347 -- mask signals for non-main pthreads, by Jason Lowe: This patch updates Python/thread_pthread.h to mask all signals for any thread created. This will keep all signals masked for any thread that isn't the initial thread. For Solaris and Linux, the two platforms I was able to test it on, it solves bug #465673 (pthreads need signal protection) and probably will solve bug #219772 (Interactive InterPreter+ Thread -> core dump at exit). I'd be great if this could get some testing on other platforms, especially HP-UX pre 11.00 and post 11.00, as I had to make some guesses for the DCE thread case. AIX is also a concern as I saw some mention of using sigthreadmask() as a pthread_sigmask() equivalent, but this patch doesn't use sigthreadmask(). I don't have access to AIX. Index: thread_pthread.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_pthread.h,v retrieving revision 2.32 retrieving revision 2.33 diff -C2 -d -r2.32 -r2.33 *** thread_pthread.h 2001/09/10 14:10:54 2.32 --- thread_pthread.h 2001/10/12 21:49:17 2.33 *************** *** 5,8 **** --- 5,9 ---- #include #include + #include *************** *** 70,73 **** --- 71,86 ---- + /* On platforms that don't use standard POSIX threads pthread_sigmask() + * isn't present. DEC threads uses sigprocmask() instead as do most + * other UNIX International compliant systems that don't have the full + * pthread implementation. + */ + #ifdef PY_PTHREAD_STD + # define SET_THREAD_SIGMASK pthread_sigmask + #else + # define SET_THREAD_SIGMASK sigprocmask + #endif + + /* A pthread mutex isn't sufficient to model the Python lock type * because, according to Draft 5 of the docs (P1003.4a/D5), both of the *************** *** 136,139 **** --- 149,153 ---- pthread_t th; int success; + sigset_t oldmask, newmask; #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) pthread_attr_t attrs; *************** *** 152,155 **** --- 166,177 ---- pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM); #endif + + /* Mask all signals in the current thread before creating the new + * thread. This causes the new thread to start with all signals + * blocked. + */ + sigfillset(&newmask); + SET_THREAD_SIGMASK(SIG_BLOCK, &newmask, &oldmask); + success = pthread_create(&th, #if defined(PY_PTHREAD_D4) *************** *** 175,178 **** --- 197,204 ---- #endif ); + + /* Restore signal mask for original thread */ + SET_THREAD_SIGMASK(SIG_SETMASK, &oldmask, NULL); + #ifdef THREAD_STACK_SIZE pthread_attr_destroy(&attrs); From gvanrossum@users.sourceforge.net Fri Oct 12 22:54:31 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 12 Oct 2001 14:54:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.118,1.119 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv27849 Modified Files: ACKS Log Message: Jason Lowe Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.118 retrieving revision 1.119 diff -C2 -d -r1.118 -r1.119 *** ACKS 2001/10/09 11:53:47 1.118 --- ACKS 2001/10/12 21:54:29 1.119 *************** *** 252,255 **** --- 252,256 ---- Martin von Löwis Anne Lord + Jason Lowe Tony Lownds Ray Loyzaga From tim_one@users.sourceforge.net Fri Oct 12 23:08:41 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 12 Oct 2001 15:08:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _hotshot.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv31336/python/Modules Modified Files: _hotshot.c Log Message: Get hotshot closer to compiling on Windows. Still broken: GETTIMEOFDAY. This macro obviously isn't being defined on Windows, so there's logic errors here I'd rather Fred untangled. Index: _hotshot.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_hotshot.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _hotshot.c 2001/10/12 20:57:55 1.1 --- _hotshot.c 2001/10/12 22:08:39 1.2 *************** *** 20,23 **** --- 20,24 ---- #include #include + #include /* for getcwd() */ typedef LARGE_INTEGER hs_time; #else *************** *** 42,45 **** --- 43,54 ---- #define BUFFERSIZE 10240 + #ifndef PATH_MAX + # ifdef MAX_PATH + # define PATH_MAX MAX_PATH + # else + # error "Need a defn. for PATH_MAX in _hotshot.c" + # endif + #endif + typedef struct { PyObject_HEAD *************** *** 366,369 **** --- 375,379 ---- } default: + ; } if (err == ERR_EOF && oldindex != 0) { *************** *** 471,475 **** /* Need to dump data to the log file... */ size_t written = fwrite(self->buffer, 1, self->index, self->logfp); ! if (written == self->index) self->index = 0; else { --- 481,485 ---- /* Need to dump data to the log file... */ size_t written = fwrite(self->buffer, 1, self->index, self->logfp); ! if (written == (size_t)self->index) self->index = 0; else { *************** *** 724,728 **** pack_exit(self, get_tdelta(self)); break; ! case PyTrace_LINE: if (self->linetimings) pack_lineno_tdelta(self, frame->f_lineno, get_tdelta(self)); --- 734,738 ---- pack_exit(self, get_tdelta(self)); break; ! case PyTrace_LINE: if (self->linetimings) pack_lineno_tdelta(self, frame->f_lineno, get_tdelta(self)); *************** *** 1260,1264 **** self->active = 0; self->next_fileno = 0; ! self->logfp = NULL; self->logfilename = PyTuple_GET_ITEM(args, 0); Py_INCREF(self->logfilename); --- 1270,1274 ---- self->active = 0; self->next_fileno = 0; ! self->logfp = NULL; self->logfilename = PyTuple_GET_ITEM(args, 0); Py_INCREF(self->logfilename); From tim_one@users.sourceforge.net Fri Oct 12 23:08:41 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 12 Oct 2001 15:08:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/PC config.c,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory usw-pr-cvs1:/tmp/cvs-serv31336/python/PC Modified Files: config.c Log Message: Get hotshot closer to compiling on Windows. Still broken: GETTIMEOFDAY. This macro obviously isn't being defined on Windows, so there's logic errors here I'd rather Fred untangled. Index: config.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/config.c,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** config.c 2001/08/02 04:15:00 1.32 --- config.c 2001/10/12 22:08:39 1.33 *************** *** 45,48 **** --- 45,49 ---- extern void initxreadlines(void); extern void init_weakref(void); + extern void init_hotshot(void); extern void initxxsubtype(void); *************** *** 99,102 **** --- 100,104 ---- {"xreadlines", initxreadlines}, {"_weakref", init_weakref}, + {"_hotshot", init_hotshot}, {"xxsubtype", initxxsubtype}, From tim_one@users.sourceforge.net Fri Oct 12 23:08:41 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 12 Oct 2001 15:08:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild pythoncore.dsp,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv31336/python/PCbuild Modified Files: pythoncore.dsp Log Message: Get hotshot closer to compiling on Windows. Still broken: GETTIMEOFDAY. This macro obviously isn't being defined on Windows, so there's logic errors here I'd rather Fred untangled. Index: pythoncore.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pythoncore.dsp,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** pythoncore.dsp 2001/10/05 22:14:45 1.24 --- pythoncore.dsp 2001/10/12 22:08:39 1.25 *************** *** 181,184 **** --- 181,199 ---- # Begin Source File + SOURCE=..\Modules\_hotshot.c + + !IF "$(CFG)" == "pythoncore - Win32 Release" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Release" + + !ENDIF + + # End Source File + # Begin Source File + SOURCE=..\Modules\_localemodule.c From gvanrossum@users.sourceforge.net Fri Oct 12 23:14:28 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 12 Oct 2001 15:14:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python pythonrun.c,2.148,2.149 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv1850 Modified Files: pythonrun.c Log Message: SF patch #467455 : Enhanced environment variables, by Toby Dickenson. This patch changes to logic to: if env.var. set and non-empty: if env.var. is an integer: set flag to that integer if flag is zero: # [actually, <= 0 --GvR] set flag to 1 Under this patch, anyone currently using PYTHONVERBOSE=yes will get the same output as before. PYTHONVERBNOSE=2 will generate more verbosity than before. The only unusual case that the following three are still all equivalent: PYTHONVERBOSE=yespleas PYTHONVERBOSE=1 PYTHONVERBOSE=0 Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.148 retrieving revision 2.149 diff -C2 -d -r2.148 -r2.149 *** pythonrun.c 2001/08/31 17:40:15 2.148 --- pythonrun.c 2001/10/12 22:14:26 2.149 *************** *** 88,91 **** --- 88,102 ---- */ + static int + add_flag(int flag, const char *envs) + { + int env = atoi(envs); + if (flag < env) + flag = env; + if (flag < 1) + flag = 1; + return flag; + } + void Py_Initialize(void) *************** *** 102,110 **** if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0') ! Py_DebugFlag = Py_DebugFlag ? Py_DebugFlag : 1; if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0') ! Py_VerboseFlag = Py_VerboseFlag ? Py_VerboseFlag : 1; if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0') ! Py_OptimizeFlag = Py_OptimizeFlag ? Py_OptimizeFlag : 1; interp = PyInterpreterState_New(); --- 113,121 ---- if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0') ! Py_DebugFlag = add_flag(Py_DebugFlag, p); if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0') ! Py_VerboseFlag = add_flag(Py_VerboseFlag, p); if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0') ! Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p); interp = PyInterpreterState_New(); From gvanrossum@users.sourceforge.net Fri Oct 12 23:17:58 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 12 Oct 2001 15:17:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc python.man,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv2490 Modified Files: python.man Log Message: SF patch #467455 : Enhanced environment variables, by Toby Dickenson. This patch changes to logic to: if env.var. set and non-empty: if env.var. is an integer: set flag to that integer if flag is zero: # [actually, <= 0 --GvR] set flag to 1 Under this patch, anyone currently using PYTHONVERBOSE=yes will get the same output as before. PYTHONVERBNOSE=2 will generate more verbosity than before. The only unusual case that the following three are still all equivalent: PYTHONVERBOSE=yespleas PYTHONVERBOSE=1 PYTHONVERBOSE=0 Index: python.man =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/python.man,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** python.man 2001/09/05 18:57:51 1.22 --- python.man 2001/10/12 22:17:56 1.23 *************** *** 340,346 **** 2-digit years are converted based on rules described in the \fItime\fP module documnetation. .IP PYTHONDEBUG If this is set to a non-empty string it is equivalent to specifying ! the \fB\-d\fP option. .IP PYTHONINSPECT If this is set to a non-empty string it is equivalent to specifying --- 340,351 ---- 2-digit years are converted based on rules described in the \fItime\fP module documnetation. + .IP PYTHONOPTIMIZE + If this is set to a non-empty string it is equivalent to specifying + the \fB\-O\fP option. If set to an integer, it is equivalent to + specifying \fB\-O\fP multiple times. .IP PYTHONDEBUG If this is set to a non-empty string it is equivalent to specifying ! the \fB\-d\fP option. If set to an integer, it is equivalent to ! specifying \fB\-d\fP multiple times. .IP PYTHONINSPECT If this is set to a non-empty string it is equivalent to specifying *************** *** 351,355 **** .IP PYTHONVERBOSE If this is set to a non-empty string it is equivalent to specifying ! the \fB\-v\fP option. .SH AUTHOR .nf --- 356,361 ---- .IP PYTHONVERBOSE If this is set to a non-empty string it is equivalent to specifying ! the \fB\-v\fP option. If set to an integer, it is equivalent to ! specifying \fB\-v\fP multiple times. .SH AUTHOR .nf From loewis@users.sourceforge.net Fri Oct 12 23:39:22 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Fri, 12 Oct 2001 15:39:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib asyncore.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv8803 Modified Files: asyncore.py Log Message: Correct __repr__: include module name, avoid extra space for empty status, use 0x format for id. Proposed by Cesar Eduardo Barros in patch #470680. Index: asyncore.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asyncore.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** asyncore.py 2001/10/09 10:10:33 1.21 --- asyncore.py 2001/10/12 22:39:20 1.22 *************** *** 210,214 **** def __repr__ (self): try: ! status = [] if self.accepting and self.addr: status.append ('listening') --- 210,214 ---- def __repr__ (self): try: ! status = [self.__class__.__module__+"."+self.__class__.__name__] if self.accepting and self.addr: status.append ('listening') *************** *** 220,225 **** else: status.append (self.addr) ! return '<%s %s at %x>' % (self.__class__.__name__, ! ' '.join (status), id (self)) except: pass --- 220,224 ---- else: status.append (self.addr) ! return '<%s at %#x>' % (' '.join (status), id (self)) except: pass From tim_one@users.sourceforge.net Sat Oct 13 01:11:12 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 12 Oct 2001 17:11:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _hotshot.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv13341/python/dist/src/Modules Modified Files: _hotshot.c Log Message: My editor can't deal with long backslash-continued strings. Changed 'em. This still doesn't compile on Windows, but at least I have a shot at fixing that now. Index: _hotshot.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_hotshot.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _hotshot.c 2001/10/12 22:08:39 1.2 --- _hotshot.c 2001/10/13 00:11:10 1.3 *************** *** 15,19 **** /* * Which timer to use should be made more configurable, but that should not ! * be difficult. This will do fo now. */ #ifdef MS_WIN32 --- 15,19 ---- /* * Which timer to use should be made more configurable, but that should not ! * be difficult. This will do for now. */ #ifdef MS_WIN32 *************** *** 22,25 **** --- 22,26 ---- #include /* for getcwd() */ typedef LARGE_INTEGER hs_time; + #else #ifndef HAVE_GETTIMEOFDAY *************** *** 90,96 **** /* The log reader... */ ! static char logreader_close__doc__[] = "\ ! close()\n\ ! Close the log file, preventing additional records from being read."; static PyObject * --- 91,97 ---- /* The log reader... */ ! static char logreader_close__doc__[] = ! "close()\n" ! "Close the log file, preventing additional records from being read."; static PyObject * *************** *** 454,460 **** } ! static char next__doc__[] = "\ ! next() -> event-info\n\ ! Return the next event record from the log file."; static PyObject * --- 455,461 ---- } ! static char next__doc__[] = ! "next() -> event-info\n" ! "Return the next event record from the log file."; static PyObject * *************** *** 751,755 **** #ifdef MS_WIN32 ! static LARGE_INTEGER frequency = {0,0}; #endif --- 752,756 ---- #ifdef MS_WIN32 ! static LARGE_INTEGER frequency = {0, 0}; #endif *************** *** 862,868 **** /* Profiler object interface methods. */ ! static char close__doc__[] = "\ ! close()\n\ ! Shut down this profiler and close the log files, even if its active."; static PyObject * --- 863,869 ---- /* Profiler object interface methods. */ ! static char close__doc__[] = ! "close()\n" ! "Shut down this profiler and close the log files, even if its active."; static PyObject * *************** *** 883,889 **** } ! static char runcall__doc__[] = "\ ! runcall(callable[, args[, kw]]) -> callable()\n\ ! Profile a specific function call, returning the result of that call."; static PyObject * --- 884,890 ---- } ! static char runcall__doc__[] = ! "runcall(callable[, args[, kw]]) -> callable()\n" ! "Profile a specific function call, returning the result of that call."; static PyObject * *************** *** 906,913 **** } ! static char runcode__doc__[] = "\ ! runcode(code, globals[, locals])\n\ ! Execute a code object while collecting profile data. If locals is omitted,\n\ ! globals is used for the locals as well."; static PyObject * --- 907,914 ---- } ! static char runcode__doc__[] = ! "runcode(code, globals[, locals])\n" ! "Execute a code object while collecting profile data. If locals is\n" ! "omitted, globals is used for the locals as well."; static PyObject * *************** *** 945,951 **** } ! static char start__doc__[] = "\ ! start()\n\ ! Install this profiler for the current thread."; static PyObject * --- 946,952 ---- } ! static char start__doc__[] = ! "start()\n" ! "Install this profiler for the current thread."; static PyObject * *************** *** 961,967 **** } ! static char stop__doc__[] = "\ ! stop()\n\ ! Remove this profiler from the current thread."; static PyObject * --- 962,968 ---- } ! static char stop__doc__[] = ! "stop()\n" ! "Remove this profiler from the current thread."; static PyObject * *************** *** 1036,1056 **** ! static char profiler_object__doc__[] = "\ ! High-performance profiler object.\n\ ! \n\ ! Methods:\n\ ! \n\ ! close(): Stop the profiler and close the log files.\n\ ! runcall(): Run a single function call with profiling enabled.\n\ ! runcode(): Execute a code object with profiling enabled.\n\ ! start(): Install the profiler and return.\n\ ! stop(): Remove the profiler.\n\ ! \n\ ! Attributes (read-only):\n\ ! \n\ ! callcount: The number of low-level calls to the profiler.\n\ ! closed: True if the profiler has already been closed.\n\ ! lineevents: True if SET_LINENO events are reported to the profiler.\n\ ! linetimings: True if SET_LINENO events collect timing information."; static PyTypeObject ProfilerType = { --- 1037,1057 ---- ! static char profiler_object__doc__[] = ! "High-performance profiler object.\n" ! "\n" ! "Methods:\n" ! "\n" ! "close(): Stop the profiler and close the log files.\n" ! "runcall(): Run a single function call with profiling enabled.\n" ! "runcode(): Execute a code object with profiling enabled.\n" ! "start(): Install the profiler and return.\n" ! "stop(): Remove the profiler.\n" ! "\n" ! "Attributes (read-only):\n" ! "\n" ! "callcount: The number of low-level calls to the profiler.\n" ! "closed: True if the profiler has already been closed.\n" ! "lineevents: True if SET_LINENO events are reported to the profiler.\n" ! "linetimings: True if SET_LINENO events collect timing information."; static PyTypeObject ProfilerType = { *************** *** 1302,1313 **** static char resolution__doc__[] = #ifdef MS_WIN32 ! "resolution() -> (performance-counter-ticks, update-frequency)\n\ ! Return the resolution of the timer provided by the QueryPerformanceCounter()\n\ ! function. The first value is the smallest observed change, and the second\n\ ! if the result of QueryPerformanceFrequency()."; #else ! "resolution() -> (gettimeofday-usecs, getrusage-usecs)\n\ ! Return the resolution of the timers provided by the gettimeofday() and\n\ ! getrusage() system calls, or -1 if the call is not supported."; #endif --- 1303,1314 ---- static char resolution__doc__[] = #ifdef MS_WIN32 ! "resolution() -> (performance-counter-ticks, update-frequency)\n" ! "Return the resolution of the timer provided by the QueryPerformanceCounter()\n" ! "function. The first value is the smallest observed change, and the second\n" ! "is the result of QueryPerformanceFrequency()."; #else ! "resolution() -> (gettimeofday-usecs, getrusage-usecs)\n" ! "Return the resolution of the timers provided by the gettimeofday() and\n" ! "getrusage() system calls, or -1 if the call is not supported."; #endif From tim_one@users.sourceforge.net Sat Oct 13 01:14:31 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 12 Oct 2001 17:14:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _hotshot.c,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv15342/python/dist/src/Modules Modified Files: _hotshot.c Log Message: This compiles on Windows now. Index: _hotshot.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_hotshot.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** _hotshot.c 2001/10/13 00:11:10 1.3 --- _hotshot.c 2001/10/13 00:14:28 1.4 *************** *** 22,25 **** --- 22,26 ---- #include /* for getcwd() */ typedef LARGE_INTEGER hs_time; + #define GETTIMEOFDAY(p) QueryPerformanceCounter(p) #else From tim_one@users.sourceforge.net Sat Oct 13 01:19:42 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 12 Oct 2001 17:19:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_hotshot.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv17446/python/dist/src/Lib/test Modified Files: test_hotshot.py Log Message: You can't unlink open files on Windows. Simply commented it out, and then test_hotshot passes on Windows. Leaving to Fred to fix "the right way" (it seems to be a feature of unittest that all unittests try to unlink open files ). Index: test_hotshot.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_hotshot.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_hotshot.py 2001/10/12 20:53:59 1.1 --- test_hotshot.py 2001/10/13 00:19:39 1.2 *************** *** 29,33 **** def get_logreader(self): log = hotshot.log.LogReader(self.logfn) ! os.unlink(self.logfn) return log --- 29,33 ---- def get_logreader(self): log = hotshot.log.LogReader(self.logfn) ! #XXX os.unlink(self.logfn) return log From tim_one@users.sourceforge.net Sat Oct 13 01:26:27 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 12 Oct 2001 17:26:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild python20.wse,1.93,1.94 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv21410/python/dist/src/PCbuild Modified Files: python20.wse Log Message: Added new hotshot pkg to the Windows installer. Rearranged the growing number of Lib packages into alphabetical order. Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.93 retrieving revision 1.94 diff -C2 -d -r1.93 -r1.94 *** python20.wse 2001/10/09 22:22:36 1.93 --- python20.wse 2001/10/13 00:26:25 1.94 *************** *** 1874,1893 **** end item: Install File - Source=..\lib\lib-tk\*.py - Destination=%MAINDIR%\Lib\lib-tk - Description=Tkinter related library modules - Flags=0000000000000010 - end - item: Remark - end - item: Install File - Source=..\lib\encodings\*.py - Destination=%MAINDIR%\Lib\encodings - Description=Unicode encoding tables - Flags=0000000000000010 - end - item: Remark - end - item: Install File Source=..\Lib\compiler\*.py Destination=%MAINDIR%\Lib\compiler --- 1874,1877 ---- *************** *** 1898,1909 **** end item: Install File - Source=..\Lib\email\*.py - Destination=%MAINDIR%\Lib\email - Description=Library email package - Flags=0000000000000010 - end - item: Remark - end - item: Install File Source=..\lib\distutils\*.py Destination=%MAINDIR%\Lib\distutils --- 1882,1885 ---- *************** *** 1929,1950 **** end item: Install File ! Source=..\lib\xml\*.py ! Destination=%MAINDIR%\Lib\xml ! Description=XML support packages Flags=0000000000000010 end ! item: Install File ! Source=..\lib\xml\dom\*.py ! Destination=%MAINDIR%\Lib\xml\dom ! Flags=0000000000000010 end item: Install File ! Source=..\lib\xml\parsers\*.py ! Destination=%MAINDIR%\Lib\xml\parsers Flags=0000000000000010 end item: Install File ! Source=..\lib\xml\sax\*.py ! Destination=%MAINDIR%\Lib\xml\sax Flags=0000000000000010 end --- 1905,1927 ---- end item: Install File ! Source=..\Lib\email\*.py ! Destination=%MAINDIR%\Lib\email ! Description=Library email package Flags=0000000000000010 end ! item: Remark end item: Install File ! Source=..\lib\encodings\*.py ! Destination=%MAINDIR%\Lib\encodings ! Description=Unicode encoding tables Flags=0000000000000010 end + item: Remark + end item: Install File ! Source=..\Lib\hotshot\*.py ! Destination=%MAINDIR%\Lib\hotshot ! Description=Fast Python profiler Flags=0000000000000010 end *************** *** 1960,1966 **** --- 1937,1974 ---- end item: Install File + Source=..\lib\lib-tk\*.py + Destination=%MAINDIR%\Lib\lib-tk + Description=Tkinter related library modules + Flags=0000000000000010 + end + item: Remark + end + item: Install File Source=..\lib\site-packages\readme Destination=%MAINDIR%\Lib\site-packages\README.txt Description=Site packages + Flags=0000000000000010 + end + item: Remark + end + item: Install File + Source=..\lib\xml\*.py + Destination=%MAINDIR%\Lib\xml + Description=XML support packages + Flags=0000000000000010 + end + item: Install File + Source=..\lib\xml\dom\*.py + Destination=%MAINDIR%\Lib\xml\dom + Flags=0000000000000010 + end + item: Install File + Source=..\lib\xml\parsers\*.py + Destination=%MAINDIR%\Lib\xml\parsers + Flags=0000000000000010 + end + item: Install File + Source=..\lib\xml\sax\*.py + Destination=%MAINDIR%\Lib\xml\sax Flags=0000000000000010 end From fdrake@users.sourceforge.net Sat Oct 13 03:55:42 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 12 Oct 2001 19:55:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/hotshot log.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/hotshot In directory usw-pr-cvs1:/tmp/cvs-serv29294 Modified Files: log.py Log Message: When we reach the end of the log file, close the logreader object. Index: log.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/hotshot/log.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** log.py 2001/10/12 20:56:29 1.1 --- log.py 2001/10/13 02:55:40 1.2 *************** *** 35,39 **** self._info = {} ! self._nextitem = _hotshot.logreader(logfn).next self._stack = [] --- 35,40 ---- self._info = {} ! self._reader = _hotshot.logreader(logfn) ! self._nextitem = self._reader.next self._stack = [] *************** *** 48,51 **** --- 49,53 ---- except TypeError: # logreader().next() returns None at the end + self._reader.close() raise StopIteration() if what == WHAT_DEFINE_FILE: From fdrake@users.sourceforge.net Sat Oct 13 04:00:13 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 12 Oct 2001 20:00:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_hotshot.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv553 Modified Files: test_hotshot.py Log Message: Remove some unused imports. Remove the log file after we are done with it. This should clean up after the test even on Windows, since the file is now closed before we attempt removal. Index: test_hotshot.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_hotshot.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_hotshot.py 2001/10/13 00:19:39 1.2 --- test_hotshot.py 2001/10/13 03:00:11 1.3 *************** *** 3,9 **** import os import pprint - import sys import unittest - import warnings import test_support --- 3,7 ---- *************** *** 22,25 **** --- 20,39 ---- + class UnlinkingLogReader(hotshot.log.LogReader): + """Extend the LogReader so the log file is unlinked when we're + done with it.""" + + def __init__(self, logfn): + self.__logfn = logfn + hotshot.log.LogReader.__init__(self, logfn) + + def next(self, index=None): + try: + return hotshot.log.LogReader.next(self) + except (IndexError, StopIteration): + os.unlink(self.__logfn) + raise + + class HotShotTestCase(unittest.TestCase): def new_profiler(self, lineevents=0, linetimings=1): *************** *** 28,33 **** def get_logreader(self): ! log = hotshot.log.LogReader(self.logfn) ! #XXX os.unlink(self.logfn) return log --- 42,46 ---- def get_logreader(self): ! log = UnlinkingLogReader(self.logfn) return log From fdrake@users.sourceforge.net Sat Oct 13 07:11:30 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 12 Oct 2001 23:11:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.283,2.284 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv2189/Python Modified Files: ceval.c Log Message: Suppress a bunch of "value computed is not used" warnings when building in debug mode (--with-pydebug). Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.283 retrieving revision 2.284 diff -C2 -d -r2.283 -r2.284 *** ceval.c 2001/10/05 20:41:38 2.283 --- ceval.c 2001/10/13 06:11:28 2.284 *************** *** 543,548 **** #ifdef LLTRACE ! #define PUSH(v) (BASIC_PUSH(v), lltrace && prtrace(TOP(), "push")) ! #define POP() (lltrace && prtrace(TOP(), "pop"), BASIC_POP()) #else #define PUSH(v) BASIC_PUSH(v) --- 543,548 ---- #ifdef LLTRACE ! #define PUSH(v) (void)(BASIC_PUSH(v), lltrace && prtrace(TOP(), "push")) ! #define POP() ((void)(lltrace && prtrace(TOP(), "pop")), BASIC_POP()) #else #define PUSH(v) BASIC_PUSH(v) From tim_one@users.sourceforge.net Sat Oct 13 08:37:54 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 13 Oct 2001 00:37:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _hotshot.c,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv18461/python/Modules Modified Files: _hotshot.c Log Message: Speed the Windows code by using native 64-bit int compiler support instead of calling external functions. Index: _hotshot.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_hotshot.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** _hotshot.c 2001/10/13 00:14:28 1.4 --- _hotshot.c 2001/10/13 07:37:52 1.5 *************** *** 21,26 **** #include #include /* for getcwd() */ ! typedef LARGE_INTEGER hs_time; ! #define GETTIMEOFDAY(p) QueryPerformanceCounter(p) #else --- 21,30 ---- #include #include /* for getcwd() */ ! typedef __int64 hs_time; ! #define GETTIMEOFDAY(P_HS_TIME) \ ! { LARGE_INTEGER _temp; \ ! QueryPerformanceCounter(&_temp); \ ! *(P_HS_TIME) = _temp.QuadPart; } ! #else *************** *** 665,674 **** #ifdef MS_WIN32 hs_time tv; ! LARGE_INTEGER diff; ! ! QueryPerformanceCounter(&tv); ! diff = LargeIntegerSubtract(tv, self->prev_timeofday); ! tdelta = diff.LowPart; #else struct timeval tv; --- 669,677 ---- #ifdef MS_WIN32 hs_time tv; ! hs_time diff; ! GETTIMEOFDAY(&tv); ! diff = tv - self->prev_timeofday; ! tdelta = (int)diff; #else struct timeval tv; *************** *** 765,769 **** #ifdef MS_WIN32 ! LARGE_INTEGER diff; QueryPerformanceFrequency(&frequency); #endif --- 768,772 ---- #ifdef MS_WIN32 ! hs_time diff; QueryPerformanceFrequency(&frequency); #endif *************** *** 773,779 **** GETTIMEOFDAY(&tv2); #ifdef MS_WIN32 ! diff = LargeIntegerSubtract(tv2, tv1); ! if (!LargeIntegerEqualToZero(diff)) { ! timeofday_diff = diff.LowPart; break; } --- 776,782 ---- GETTIMEOFDAY(&tv2); #ifdef MS_WIN32 ! diff = tv2 - tv1; ! if (diff != 0) { ! timeofday_diff = (unsigned long)diff; break; } From loewis@users.sourceforge.net Sat Oct 13 09:50:12 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sat, 13 Oct 2001 01:50:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _curses_panel.c,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv6847 Modified Files: _curses_panel.c Log Message: Cast argument to set_panel_userptr to void*. Fixes bug #417240. Index: _curses_panel.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_curses_panel.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** _curses_panel.c 2001/01/27 18:58:04 1.6 --- _curses_panel.c 2001/10/13 08:50:10 1.7 *************** *** 305,309 **** obj = PyTuple_GetItem(args, 0); Py_INCREF(obj); ! return PyCursesCheckERR(set_panel_userptr(self->pan, obj), "set_panel_userptr"); } --- 305,309 ---- obj = PyTuple_GetItem(args, 0); Py_INCREF(obj); ! return PyCursesCheckERR(set_panel_userptr(self->pan, (void*)obj), "set_panel_userptr"); } From loewis@users.sourceforge.net Sat Oct 13 10:00:44 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sat, 13 Oct 2001 02:00:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.179,1.180 _cursesmodule.c,2.55,2.56 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv10406/Modules Modified Files: socketmodule.c _cursesmodule.c Log Message: Test for __sun instead of __sun__, since SUNWspro only defines the latter; gcc defines both. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.179 retrieving revision 1.180 diff -C2 -d -r1.179 -r1.180 *** socketmodule.c 2001/10/12 18:59:27 1.179 --- socketmodule.c 2001/10/13 09:00:42 1.180 *************** *** 95,99 **** #if defined(_AIX) || defined(__osf__) #define HAVE_GETHOSTBYNAME_R_3_ARG ! #elif defined(__sun__) || defined(__sgi) #define HAVE_GETHOSTBYNAME_R_5_ARG #elif defined(linux) --- 95,99 ---- #if defined(_AIX) || defined(__osf__) #define HAVE_GETHOSTBYNAME_R_3_ARG ! #elif defined(__sun) || defined(__sgi) #define HAVE_GETHOSTBYNAME_R_5_ARG #elif defined(linux) Index: _cursesmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_cursesmodule.c,v retrieving revision 2.55 retrieving revision 2.56 diff -C2 -d -r2.55 -r2.56 *** _cursesmodule.c 2001/09/04 19:34:32 2.55 --- _cursesmodule.c 2001/10/13 09:00:42 2.56 *************** *** 119,123 **** #endif ! #if defined(sgi) || defined(__sun__) #define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ typedef chtype attr_t; /* No attr_t type is available */ --- 119,123 ---- #endif ! #if defined(sgi) || defined(__sun) #define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ typedef chtype attr_t; /* No attr_t type is available */ From loewis@users.sourceforge.net Sat Oct 13 10:12:43 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sat, 13 Oct 2001 02:12:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include py_curses.h,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv16024/Include Modified Files: py_curses.h Log Message: Check for term.h and include it on non-ncurses system to get a declaration for tigetstr. Index: py_curses.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/py_curses.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** py_curses.h 2000/12/22 21:51:10 1.1 --- py_curses.h 2001/10/13 09:12:41 1.2 *************** *** 7,10 **** --- 7,14 ---- #else #include + #ifdef HAVE_TERM_H + /* for tigetstr, which is not declared in SysV curses */ + #include + #endif #endif From loewis@users.sourceforge.net Sat Oct 13 10:12:43 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sat, 13 Oct 2001 02:12:43 -0700 Subject: [Python-checkins] CVS: python/dist/src pyconfig.h.in,1.13,1.14 configure,1.258,1.259 configure.in,1.266,1.267 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv16024 Modified Files: pyconfig.h.in configure configure.in Log Message: Check for term.h and include it on non-ncurses system to get a declaration for tigetstr. Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** pyconfig.h.in 2001/10/04 22:44:26 1.13 --- pyconfig.h.in 2001/10/13 09:12:40 1.14 *************** *** 700,703 **** --- 700,706 ---- #undef HAVE_SYS_WAIT_H + /* Define if you have the header file. */ + #undef HAVE_TERM_H + /* Define if you have the header file. */ #undef HAVE_TERMIOS_H Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.258 retrieving revision 1.259 diff -C2 -d -r1.258 -r1.259 *** configure 2001/10/08 13:17:28 1.258 --- configure 2001/10/13 09:12:40 1.259 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.265 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.266 # Guess values for system-dependent variables and create Makefiles. *************** *** 1904,1908 **** sys/audioio.h sys/file.h sys/lock.h sys/modem.h db_185.h db.h \ sys/param.h sys/poll.h sys/select.h sys/socket.h sys/time.h sys/times.h \ ! sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h netpacket/packet.h do --- 1904,1908 ---- sys/audioio.h sys/file.h sys/lock.h sys/modem.h db_185.h db.h \ sys/param.h sys/poll.h sys/select.h sys/socket.h sys/time.h sys/times.h \ ! sys/un.h sys/utsname.h sys/wait.h pty.h term.h libutil.h \ ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h netpacket/packet.h do Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.266 retrieving revision 1.267 diff -C2 -d -r1.266 -r1.267 *** configure.in 2001/10/08 13:17:28 1.266 --- configure.in 2001/10/13 09:12:41 1.267 *************** *** 449,453 **** sys/audioio.h sys/file.h sys/lock.h sys/modem.h db_185.h db.h \ sys/param.h sys/poll.h sys/select.h sys/socket.h sys/time.h sys/times.h \ ! sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \ ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h netpacket/packet.h) AC_HEADER_DIRENT --- 449,453 ---- sys/audioio.h sys/file.h sys/lock.h sys/modem.h db_185.h db.h \ sys/param.h sys/poll.h sys/select.h sys/socket.h sys/time.h sys/times.h \ ! sys/un.h sys/utsname.h sys/wait.h pty.h term.h libutil.h \ ndbm.h db1/ndbm.h gdbm/ndbm.h sys/resource.h netpacket/packet.h) AC_HEADER_DIRENT From loewis@users.sourceforge.net Sat Oct 13 10:33:53 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sat, 13 Oct 2001 02:33:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/lib-tk Tkinter.py,1.159,1.160 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory usw-pr-cvs1:/tmp/cvs-serv21653 Modified Files: Tkinter.py Log Message: Move grid_location into Misc. Fixes bug #426892. Index: Tkinter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/Tkinter.py,v retrieving revision 1.159 retrieving revision 1.160 diff -C2 -d -r1.159 -r1.160 *** Tkinter.py 2001/10/01 17:02:49 1.159 --- Tkinter.py 2001/10/13 09:33:51 1.160 *************** *** 1192,1195 **** --- 1192,1202 ---- return self._grid_configure('columnconfigure', index, cnf, kw) columnconfigure = grid_columnconfigure + def grid_location(self, x, y): + """Return a tuple of column and row which identify the cell + at which the pixel at position X and Y inside the master + widget is located.""" + return self._getints( + self.tk.call( + 'grid', 'location', self._w, x, y)) or None def grid_propagate(self, flag=_noarg_): """Set or get the status for propagation of geometry information. *************** *** 1702,1713 **** return dict info = grid_info ! def grid_location(self, x, y): ! """Return a tuple of column and row which identify the cell ! at which the pixel at position X and Y inside the master ! widget is located.""" ! return self._getints( ! self.tk.call( ! 'grid', 'location', self._w, x, y)) or None ! location = grid_location propagate = grid_propagate = Misc.grid_propagate rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure --- 1709,1713 ---- return dict info = grid_info ! location = grid_location = Misc.grid_location propagate = grid_propagate = Misc.grid_propagate rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure From fdrake@users.sourceforge.net Sat Oct 13 16:57:57 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 13 Oct 2001 08:57:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects stringobject.c,2.137,2.138 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9795 Modified Files: stringobject.c Log Message: Remove extra "]" in splitlines() docstring. Reported by Neal Norwitz. Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.137 retrieving revision 2.138 diff -C2 -d -r2.137 -r2.138 *** stringobject.c 2001/10/05 20:51:39 2.137 --- stringobject.c 2001/10/13 15:57:55 2.138 *************** *** 2539,2543 **** static char splitlines__doc__[] = ! "S.splitlines([keepends]]) -> list of strings\n\ \n\ Return a list of the lines in S, breaking at line boundaries.\n\ --- 2539,2543 ---- static char splitlines__doc__[] = ! "S.splitlines([keepends]) -> list of strings\n\ \n\ Return a list of the lines in S, breaking at line boundaries.\n\ From fdrake@users.sourceforge.net Sat Oct 13 16:59:49 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 13 Oct 2001 08:59:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib markupbase.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv10115 Modified Files: markupbase.py Log Message: Remove extra param from call to self.error(). Reported by Neal Norwitz. Index: markupbase.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/markupbase.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** markupbase.py 2001/09/24 20:04:29 1.2 --- markupbase.py 2001/10/13 15:59:47 1.3 *************** *** 304,306 **** else: self.updatepos(declstartpos, i) ! self.error("expected name token", self.getpos()) --- 304,306 ---- else: self.updatepos(declstartpos, i) ! self.error("expected name token") From fdrake@users.sourceforge.net Sat Oct 13 17:00:55 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 13 Oct 2001 09:00:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib webbrowser.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv10353 Modified Files: webbrowser.py Log Message: _os should be os; reported by Neal Norwitz. Index: webbrowser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/webbrowser.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** webbrowser.py 2001/08/13 14:37:23 1.21 --- webbrowser.py 2001/10/13 16:00:52 1.22 *************** *** 180,184 **** tempdir = os.path.join(tempfile.gettempdir(), ".grail-unix") ! user = pwd.getpwuid(_os.getuid())[0] filename = os.path.join(tempdir, user + "-*") maybes = glob.glob(filename) --- 180,184 ---- tempdir = os.path.join(tempfile.gettempdir(), ".grail-unix") ! user = pwd.getpwuid(os.getuid())[0] filename = os.path.join(tempdir, user + "-*") maybes = glob.glob(filename) From fdrake@users.sourceforge.net Sat Oct 13 19:33:53 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 13 Oct 2001 11:33:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib gzip.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11495 Modified Files: gzip.py Log Message: "f" should be "self"; reported by Neal Norwitz. Index: gzip.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/gzip.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** gzip.py 2001/08/13 14:54:12 1.27 --- gzip.py 2001/10/13 18:33:51 1.28 *************** *** 290,294 **** count = offset - self.offset for i in range(count/1024): ! f.write(1024*'\0') self.write((count%1024)*'\0') elif self.mode == READ: --- 290,294 ---- count = offset - self.offset for i in range(count/1024): ! self.write(1024*'\0') self.write((count%1024)*'\0') elif self.mode == READ: From fdrake@users.sourceforge.net Sat Oct 13 19:34:45 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 13 Oct 2001 11:34:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib rexec.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11709 Modified Files: rexec.py Log Message: Ignore execfile() return value; reported by Neal Norwitz. Index: rexec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/rexec.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** rexec.py 2001/09/13 21:01:29 1.33 --- rexec.py 2001/10/13 18:34:42 1.34 *************** *** 260,264 **** def r_execfile(self, file): m = self.add_module('__main__') ! return execfile(file, m.__dict__) def r_import(self, mname, globals={}, locals={}, fromlist=[]): --- 260,264 ---- def r_execfile(self, file): m = self.add_module('__main__') ! execfile(file, m.__dict__) def r_import(self, mname, globals={}, locals={}, fromlist=[]): From fdrake@users.sourceforge.net Sat Oct 13 19:35:34 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 13 Oct 2001 11:35:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib smtplib.py,1.44,1.45 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11942 Modified Files: smtplib.py Log Message: SMTPError should be SMTPException; reported by Neal Norwitz. Index: smtplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/smtplib.py,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** smtplib.py 2001/10/07 08:53:32 1.44 --- smtplib.py 2001/10/13 18:35:32 1.45 *************** *** 486,490 **** SMTPAuthenticationError The server didn't accept the username/ password combination. ! SMTPError No suitable authentication method was found. """ --- 486,490 ---- SMTPAuthenticationError The server didn't accept the username/ password combination. ! SMTPException No suitable authentication method was found. """ *************** *** 538,542 **** AUTH_PLAIN + " " + encode_plain(user, password)) elif authmethod == None: ! raise SMTPError("No suitable authentication method found.") if code not in [235, 503]: # 235 == 'Authentication successful' --- 538,542 ---- AUTH_PLAIN + " " + encode_plain(user, password)) elif authmethod == None: ! raise SMTPException("No suitable authentication method found.") if code not in [235, 503]: # 235 == 'Authentication successful' From fdrake@users.sourceforge.net Sat Oct 13 19:37:09 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 13 Oct 2001 11:37:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib urllib.py,1.133,1.134 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv12335 Modified Files: urllib.py Log Message: Added missing parameter in call to http_error_default(); reported by Neal Norwitz. Index: urllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/urllib.py,v retrieving revision 1.133 retrieving revision 1.134 diff -C2 -d -r1.133 -r1.134 *** urllib.py 2001/08/27 20:16:53 1.133 --- urllib.py 2001/10/13 18:37:07 1.134 *************** *** 585,589 **** if not headers.has_key('www-authenticate'): URLopener.http_error_default(self, url, fp, ! errmsg, headers) stuff = headers['www-authenticate'] import re --- 585,589 ---- if not headers.has_key('www-authenticate'): URLopener.http_error_default(self, url, fp, ! errcode, errmsg, headers) stuff = headers['www-authenticate'] import re From fdrake@users.sourceforge.net Sat Oct 13 19:38:55 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 13 Oct 2001 11:38:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib cgi.py,1.67,1.68 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv12676 Modified Files: cgi.py Log Message: "ib" should be "boundary"; reported by Neal Norwitz. Index: cgi.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/cgi.py,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -d -r1.67 -r1.68 *** cgi.py 2001/09/05 19:45:34 1.67 --- cgi.py 2001/10/13 18:38:53 1.68 *************** *** 249,253 **** if not valid_boundary(boundary): raise ValueError, ('Invalid boundary in multipart form: %s' ! % `ib`) nextpart = "--" + boundary --- 249,253 ---- if not valid_boundary(boundary): raise ValueError, ('Invalid boundary in multipart form: %s' ! % `boundary`) nextpart = "--" + boundary From gvanrossum@users.sourceforge.net Sat Oct 13 21:02:43 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 13 Oct 2001 13:02:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.101,2.102 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv30394/Objects Modified Files: typeobject.c Log Message: Redid the slot computation. The initial slot assignments are now done using the same algorithm as the slot updates. The slotdefs array is now sorted by slot offset and has an interned string object corresponding to the name added to each item. More can be done but I need to commit this first as a working intermediate stage. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.101 retrieving revision 2.102 diff -C2 -d -r2.101 -r2.102 *** typeobject.c 2001/10/12 14:13:21 2.101 --- typeobject.c 2001/10/13 20:02:41 2.102 *************** *** 3453,3456 **** --- 3453,3461 ---- } getattr = _PyType_Lookup(tp, getattr_str); + if (getattr == NULL && tp->tp_getattro == slot_tp_getattr_hook) { + /* No __getattr__ hook: use a simpler dispatcher */ + tp->tp_getattro = slot_tp_getattro; + return slot_tp_getattro(self, name); + } getattribute = _PyType_Lookup(tp, getattribute_str); if (getattribute != NULL && *************** *** 3460,3471 **** getattribute = NULL; if (getattr == NULL && getattribute == NULL) { ! /* Avoid further slowdowns */ ! /* XXX This is questionable: it means that a class that ! isn't born with __getattr__ or __getattribute__ cannot ! acquire them in later life. But it's a relatively big ! speedup, so I'm keeping it in for now. If this is ! removed, you can also remove the "def __getattr__" from ! class C (marked with another XXX comment) in dynamics() ! in Lib/test/test_descr.py. */ if (tp->tp_getattro == slot_tp_getattr_hook) tp->tp_getattro = PyObject_GenericGetAttr; --- 3465,3469 ---- getattribute = NULL; if (getattr == NULL && getattribute == NULL) { ! /* Use the default dispatcher */ if (tp->tp_getattro == slot_tp_getattr_hook) tp->tp_getattro = PyObject_GenericGetAttr; *************** *** 3814,3818 **** TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc), TPSLOT("__call__", tp_call, slot_tp_call, wrap_call), ! TPSLOT("__getattribute__", tp_getattro, slot_tp_getattro, wrap_binaryfunc), TPSLOT("__getattribute__", tp_getattr, NULL, NULL), --- 3812,3816 ---- TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc), TPSLOT("__call__", tp_call, slot_tp_call, wrap_call), ! TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, wrap_binaryfunc), TPSLOT("__getattribute__", tp_getattr, NULL, NULL), *************** *** 3865,3889 **** } ! staticforward int recurse_down_subclasses(PyTypeObject *type, int offset); static int ! update_one_slot(PyTypeObject *type, int offset) { ! slotdef *p; PyObject *descr; PyWrapperDescrObject *d; void *generic = NULL, *specific = NULL; int use_generic = 0; void **ptr; ! for (p = slotdefs; p->name; p++) { ! if (p->offset != offset) ! continue; descr = _PyType_Lookup(type, p->name_strobj); if (descr == NULL) continue; - ptr = slotptr(type, p->offset); - if (ptr == NULL) - continue; generic = p->function; if (descr->ob_type == &PyWrapperDescr_Type) { --- 3863,3887 ---- } ! staticforward int recurse_down_subclasses(PyTypeObject *type, slotdef *p); static int ! update_one_slot(PyTypeObject *type, slotdef *p0) { ! slotdef *p = p0; PyObject *descr; PyWrapperDescrObject *d; void *generic = NULL, *specific = NULL; int use_generic = 0; + int offset; void **ptr; ! offset = p->offset; ! ptr = slotptr(type, offset); ! if (ptr == NULL) ! return recurse_down_subclasses(type, p); ! do { descr = _PyType_Lookup(type, p->name_strobj); if (descr == NULL) continue; generic = p->function; if (descr->ob_type == &PyWrapperDescr_Type) { *************** *** 3900,3915 **** else use_generic = 1; ! if (specific && !use_generic) ! *ptr = specific; ! else ! *ptr = generic; ! } ! if (recurse_down_subclasses(type, offset) < 0) ! return -1; ! return 0; } static int ! recurse_down_subclasses(PyTypeObject *type, int offset) { PyTypeObject *subclass; --- 3898,3911 ---- else use_generic = 1; ! } while ((++p)->offset == offset); ! if (specific && !use_generic) ! *ptr = specific; ! else ! *ptr = generic; ! return recurse_down_subclasses(type, p0); } static int ! recurse_down_subclasses(PyTypeObject *type, slotdef *p) { PyTypeObject *subclass; *************** *** 3929,3933 **** continue; assert(PyType_Check(subclass)); ! if (update_one_slot(subclass, offset) < 0) return -1; } --- 3925,3929 ---- continue; assert(PyType_Check(subclass)); ! if (update_one_slot(subclass, p) < 0) return -1; } *************** *** 3935,3940 **** } static void ! init_name_strobj(void) { slotdef *p; --- 3931,3947 ---- } + static int + slotdef_cmp(const void *aa, const void *bb) + { + const slotdef *a = (const slotdef *)aa, *b = (const slotdef *)bb; + int c = a->offset - b->offset; + if (c != 0) + return c; + else + return a - b; + } + static void ! init_slotdefs(void) { slotdef *p; *************** *** 3948,3965 **** Py_FatalError("XXX ouch"); } initialized = 1; } static void ! collect_offsets(PyObject *name, int offsets[]) { slotdef *p; ! init_name_strobj(); for (p = slotdefs; p->name; p++) { if (name == p->name_strobj) ! *offsets++ = p->offset; } ! *offsets = 0; } --- 3955,3973 ---- Py_FatalError("XXX ouch"); } + qsort((void *)slotdefs, (size_t)(p-slotdefs), sizeof(slotdef), slotdef_cmp); initialized = 1; } static void ! collect_ptrs(PyObject *name, slotdef *ptrs[]) { slotdef *p; ! init_slotdefs(); for (p = slotdefs; p->name; p++) { if (name == p->name_strobj) ! *ptrs++ = p; } ! *ptrs = NULL; } *************** *** 3967,3976 **** update_slot(PyTypeObject *type, PyObject *name) { ! int offsets[10]; ! int *ip; ! collect_offsets(name, offsets); ! for (ip = offsets; *ip; ip++) { ! if (update_one_slot(type, *ip) < 0) return -1; } --- 3975,3988 ---- update_slot(PyTypeObject *type, PyObject *name) { ! slotdef *ptrs[10]; ! slotdef *p; ! slotdef **pp; ! collect_ptrs(name, ptrs); ! for (pp = ptrs; *pp; pp++) { ! p = *pp; ! while (p > slotdefs && p->offset == (p-1)->offset) ! --p; ! if (update_one_slot(type, p) < 0) return -1; } *************** *** 3985,4024 **** PyTypeObject *base; PyWrapperDescrObject *d; ! int i, n; void **ptr; ! for (p = slotdefs; p->name; p++) { ! ptr = slotptr(type, p->offset); ! if (ptr) ! *ptr = NULL; ! } mro = type->tp_mro; assert(PyTuple_Check(mro)); n = PyTuple_GET_SIZE(mro); ! for (p = slotdefs; p->name; p++) { ! for (i = 0; i < n; i++) { ! base = (PyTypeObject *)PyTuple_GET_ITEM(mro, i); ! assert(PyType_Check(base)); ! descr = PyDict_GetItemString( ! base->tp_defined, p->name); if (descr == NULL) continue; ! ptr = slotptr(type, p->offset); ! if (ptr == NULL) ! continue; if (descr->ob_type == &PyWrapperDescr_Type) { d = (PyWrapperDescrObject *)descr; ! if (d->d_base->wrapper == p->wrapper) { ! if (*ptr == NULL) { ! *ptr = d->d_wrapped; ! continue; ! } ! if (p->wrapper == wrap_binaryfunc_r) ! continue; } } ! *ptr = p->function; ! break; ! } } } --- 3997,4051 ---- PyTypeObject *base; PyWrapperDescrObject *d; ! int i, n, offset; void **ptr; + void *generic, *specific; + int use_generic; ! init_slotdefs(); mro = type->tp_mro; assert(PyTuple_Check(mro)); n = PyTuple_GET_SIZE(mro); ! for (p = slotdefs; p->name; ) { ! offset = p->offset; ! ptr = slotptr(type, offset); ! if (!ptr) { ! do { ! ++p; ! } while (p->offset == offset); ! continue; ! } ! generic = specific = NULL; ! use_generic = 0; ! do { ! descr = NULL; ! for (i = 0; i < n; i++) { ! base = (PyTypeObject *)PyTuple_GET_ITEM(mro, i); ! assert(PyType_Check(base)); ! descr = PyDict_GetItem( ! base->tp_defined, p->name_strobj); ! if (descr != NULL) ! break; ! } if (descr == NULL) continue; ! generic = p->function; if (descr->ob_type == &PyWrapperDescr_Type) { d = (PyWrapperDescrObject *)descr; ! if (d->d_base->wrapper == p->wrapper && ! PyType_IsSubtype(type, d->d_type)) { ! if (specific == NULL || ! specific == d->d_wrapped) ! specific = d->d_wrapped; ! else ! use_generic = 1; } } ! else ! use_generic = 1; ! } while ((++p)->offset == offset); ! if (specific && !use_generic) ! *ptr = specific; ! else ! *ptr = generic; } } From tim_one@users.sourceforge.net Sat Oct 13 21:16:20 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 13 Oct 2001 13:16:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Parser grammar.mak,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Parser In directory usw-pr-cvs1:/tmp/cvs-serv2119/python/Parser Added Files: grammar.mak Log Message: An MSVC makefile to rebuild the grammar files (graminit.[ch]) manually. Ugly, but it works. --- NEW FILE: grammar.mak --- # This manages to rebuild graminit.{h, c} under MSVC 6 (Windows), via # # nmake /f grammar.mak # # The intermediate files can be nuked afterwards: # # nmake /f grammar.mak clean # # I don't understand the maze of preprocessor #define's on Windows, and # as a result this requires linking with python22.lib, so it's of no use # for bootstrapping (the cause appears to be a useless-- in this # particular case --pragma in PC\pyconfig.h, which demands that # python22.lib get linked in). LIBS= ..\PCbuild\python22.lib CFLAGS= /I ..\Include /I ..\PC /D MS_NO_COREDLL GRAMMAR_H= ..\Include\graminit.h GRAMMAR_C= ..\Python\graminit.c GRAMMAR_INPUT= ..\Grammar\Grammar PGEN= pgen.exe POBJS= acceler.obj grammar1.obj listnode.obj node.obj parser.obj \ parsetok.obj tokenizer.obj bitset.obj metagrammar.obj PARSER_OBJS= $(POBJS) myreadline.obj PGOBJS= firstsets.obj grammar.obj pgen.obj printgrammar.obj pgenmain.obj PGENOBJS= $(POBJS) $(PGOBJS) $(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT) $(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) $(PGEN): $(PGENOBJS) $(CC) $(PGENOBJS) $(LIBS) /Fe$(PGEN) clean: del *.obj del $(PGEN) From fdrake@users.sourceforge.net Sun Oct 14 05:45:53 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 13 Oct 2001 21:45:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api utilities.tex,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv14353/api Modified Files: utilities.tex Log Message: Added documentation for the functions listed in marshal.h. Prompted by Jim Ahlstrom. This closes SF patch #470614. Index: utilities.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/utilities.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** utilities.tex 2001/10/12 19:01:43 1.1 --- utilities.tex 2001/10/14 04:45:51 1.2 *************** *** 270,273 **** --- 270,353 ---- + \section{Data marshalling support \label{marshalling-utils}} + + These routines allow C code to work with serialized objects using the + same data format as the \module{marshal} module. There are functions + to write data into the serialization format, and additional functions + that can be used to read the data back. Files used to store marshalled + data must be opened in binary mode. + + Numeric values are stored with the least significant byte first. + + \begin{cfuncdesc}{void}{PyMarshal_WriteLongToFile}{long value, FILE *file} + Marshal a \ctype{long} integer, \var{value}, to \var{file}. This + will only write the least-significant 32 bits of \var{value}; + regardless of the size of the native \ctype{long} type. + \end{cfuncdesc} + + \begin{cfuncdesc}{void}{PyMarshal_WriteShortToFile}{short value, FILE *file} + Marshal a \ctype{short} integer, \var{value}, to \var{file}. + \end{cfuncdesc} + + \begin{cfuncdesc}{void}{PyMarshal_WriteObjectToFile}{PyObject *value, + FILE *file} + Marshal a Python object, \var{value}, to \var{file}. This + will only write the least-significant 16 bits of \var{value}; + regardless of the size of the native \ctype{short} type. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyMarshal_WriteObjectToString}{PyObject *value} + Return a string object containing the marshalled representation of + \var{value}. + \end{cfuncdesc} + + The following functions allow marshalled values to be read back in. + + XXX What about error detection? It appears that reading past the end + of the file will always result in a negative numeric value (where + that's relevant), but it's not clear that negative values won't be + handled properly when there's no error. What's the right way to tell? + Should only non-negative values be written using these routines? + + \begin{cfuncdesc}{long}{PyMarshal_ReadLongFromFile}{FILE *file} + Return a C \ctype{long} from the data stream in a \ctype{FILE*} + opened for reading. Only a 32-bit value can be read in using + this function, regardless of the native size of \ctype{long}. + \end{cfuncdesc} + + \begin{cfuncdesc}{int}{PyMarshal_ReadShortFromFile}{FILE *file} + Return a C \ctype{short} from the data stream in a \ctype{FILE*} + opened for reading. Only a 16-bit value can be read in using + this function, regardless of the native size of \ctype{long}. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyMarshal_ReadObjectFromFile}{FILE *file} + Return a Python object from the data stream in a \ctype{FILE*} + opened for reading. On error, sets the appropriate exception + (\exception{EOFError} or \exception{TypeError}) and returns \NULL. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyMarshal_ReadLastObjectFromFile}{FILE *file} + Return a Python object from the data stream in a \ctype{FILE*} + opened for reading. Unlike + \cfunction{PyMarshal_ReadObjectFromFile()}, this function assumes + that no further objects will be read from the file, allowing it to + aggressively load file data into memory so that the de-serialization + can operate from data in memory rather than reading a byte at a time + from the file. Only use these variant if you are certain that you + won't be reading anything else from the file. On error, sets the + appropriate exception (\exception{EOFError} or + \exception{TypeError}) and returns \NULL. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyMarshal_ReadObjectFromString}{char *string, + int len} + Return a Python object from the data stream in a character buffer + containing \var{len} bytes pointed to by \var{string}. On error, + sets the appropriate exception (\exception{EOFError} or + \exception{TypeError}) and returns \NULL. + \end{cfuncdesc} + + \section{Parsing arguments and building values \label{arg-parsing}} From bwarsaw@users.sourceforge.net Mon Oct 15 05:38:24 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Sun, 14 Oct 2001 21:38:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email Iterators.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv32444/Lib/email Modified Files: Iterators.py Log Message: typed_subpart_iterator(): When getting the main type use 'text' as the failobj, and when getting the subtype use 'plain' as the failobj. text/plain is supposed to be the default if the message contains no Content-Type: header. Index: Iterators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Iterators.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Iterators.py 2001/10/04 17:05:11 1.4 --- Iterators.py 2001/10/15 04:38:22 1.5 *************** *** 29,33 **** """ for subpart in msg.walk(): ! if subpart.get_main_type() == maintype: ! if subtype is None or subpart.get_subtype() == subtype: yield subpart --- 29,33 ---- """ for subpart in msg.walk(): ! if subpart.get_main_type('text') == maintype: ! if subtype is None or subpart.get_subtype('plain') == subtype: yield subpart From bwarsaw@users.sourceforge.net Mon Oct 15 05:39:09 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Sun, 14 Oct 2001 21:39:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_email.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv32719/Lib/test Modified Files: test_email.py Log Message: test_typed_subpart_iterator_default_type(): Test for when the message has no Content-Type: header, it should be treated as text/plain. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_email.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_email.py 2001/10/11 15:44:50 1.9 --- test_email.py 2001/10/15 04:39:02 1.10 *************** *** 887,890 **** --- 887,908 ---- """) + def test_typed_subpart_iterator_default_type(self): + eq = self.assertEqual + msg = self._msgobj('msg_03.txt') + it = Iterators.typed_subpart_iterator(msg, 'text', 'plain') + lines = [] + subparts = 0 + for subpart in it: + subparts += 1 + lines.append(subpart.get_payload()) + eq(subparts, 1) + eq(EMPTYSTRING.join(lines), """\ + + Hi, + + Do you like this message? + + -Me + """) From loewis@users.sourceforge.net Mon Oct 15 09:06:32 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Mon, 15 Oct 2001 01:06:32 -0700 Subject: [Python-checkins] CVS: python/dist/src configure.in,1.267,1.268 configure,1.259,1.260 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv18709 Modified Files: configure.in configure Log Message: Check whether pthreads are available without any options before checking that -Kpthread is supported. Fixes #470781. Port to autoconf 2.52. Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.267 retrieving revision 1.268 diff -C2 -d -r1.267 -r1.268 *** configure.in 2001/10/13 09:12:41 1.267 --- configure.in 2001/10/15 08:06:29 1.268 *************** *** 153,159 **** dnl The following fragment works similar to AC_PROG_CXX. dnl It does not fail if CXX is not found, and it is not executed if ! dnl --with-cxx was given. dnl Finally, it does not test whether CXX is g++. if test "$check_cxx" = "yes" then --- 153,168 ---- dnl The following fragment works similar to AC_PROG_CXX. dnl It does not fail if CXX is not found, and it is not executed if ! dnl --without-cxx was given. dnl Finally, it does not test whether CXX is g++. + dnl Autoconf 2.5x does not have AC_PROG_CXX_WORKS anymore + ifdef([AC_PROG_CXX_WORKS],[], + [AC_DEFUN([AC_PROG_CXX_WORKS], + [AC_LANG_PUSH(C++)dnl + _AC_COMPILER_EXEEXT + AC_LANG_POP() + ] + )]) + if test "$check_cxx" = "yes" then *************** *** 406,409 **** --- 415,448 ---- fi + # On some compilers, pthreads are available without further options + # (e.g. MacOS X). On some of these systems, the compiler will not + # complain if unaccepted options are passed (e.g. gcc on Mac OS X). + # So we have to see first whether pthreads are available without + # options before we can check whether -Kpthread improves anything. + AC_MSG_CHECKING(whether pthreads are available without options) + AC_CACHE_VAL(ac_cv_pthread_is_default, + [AC_TRY_RUN([ + #include + + void* routine(void* p){return NULL;} + + int main(){ + pthread_t p; + if(pthread_create(&p,NULL,routine,NULL)!=0) + return 1; + return 0; + } + ], + ac_cv_pthread_is_default=yes, + ac_cv_pthread_is_default=no, + ac_cv_pthread_is_default=no) + ]) + AC_MSG_RESULT($ac_cv_pthread_is_default) + + + if test $ac_cv_pthread_is_default = yes + then + ac_cv_kpthread=no + else # -Kpthread, if available, provides the right #defines # and linker options to make pthread_create available *************** *** 432,435 **** --- 471,475 ---- CC="$ac_save_cc"]) AC_MSG_RESULT($ac_cv_kpthread) + fi dnl # check for ANSI or K&R ("traditional") preprocessor *************** *** 926,929 **** --- 966,977 ---- then USE_THREAD_MODULE="#" + elif test "$ac_cv_pthread_is_default" = yes + then + AC_DEFINE(WITH_THREAD) + AC_DEFINE(_POSIX_THREADS) + # Defining _REENTRANT on system with POSIX threads should not hurt. + AC_DEFINE(_REENTRANT) + posix_threads=yes + LIBOBJS="$LIBOBJS thread.o" elif test "$ac_cv_kpthread" = "yes" then *************** *** 1121,1125 **** inria) dnl http://www.kame.net/ ! AC_EGREP_CPP(yes, [dnl #include #ifdef IPV6_INRIA_VERSION --- 1169,1173 ---- inria) dnl http://www.kame.net/ ! AC_EGREP_CPP(yes, [ #include #ifdef IPV6_INRIA_VERSION *************** *** 1131,1135 **** kame) dnl http://www.kame.net/ ! AC_EGREP_CPP(yes, [dnl #include #ifdef __KAME__ --- 1179,1183 ---- kame) dnl http://www.kame.net/ ! AC_EGREP_CPP(yes, [ #include #ifdef __KAME__ *************** *** 1144,1148 **** linux-glibc) dnl http://www.v6.linux.or.jp/ ! AC_EGREP_CPP(yes, [dnl #include #if defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2)) --- 1192,1196 ---- linux-glibc) dnl http://www.v6.linux.or.jp/ ! AC_EGREP_CPP(yes, [ #include #if defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2)) *************** *** 1172,1176 **** ;; toshiba) ! AC_EGREP_CPP(yes, [dnl #include #ifdef _TOSHIBA_INET6 --- 1220,1224 ---- ;; toshiba) ! AC_EGREP_CPP(yes, [ #include #ifdef _TOSHIBA_INET6 *************** *** 1183,1187 **** ;; v6d) ! AC_EGREP_CPP(yes, [dnl #include #ifdef __V6D__ --- 1231,1235 ---- ;; v6d) ! AC_EGREP_CPP(yes, [ #include #ifdef __V6D__ *************** *** 1194,1198 **** ;; zeta) ! AC_EGREP_CPP(yes, [dnl #include #ifdef _ZETA_MINAMI_INET6 --- 1242,1246 ---- ;; zeta) ! AC_EGREP_CPP(yes, [ #include #ifdef _ZETA_MINAMI_INET6 Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.259 retrieving revision 1.260 diff -C2 -d -r1.259 -r1.260 *** configure 2001/10/13 09:12:40 1.259 --- configure 2001/10/15 08:06:29 1.260 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.266 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.267 [...4816 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 < *************** *** 7225,7229 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7228: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 7296,7300 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7299: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then From fdrake@users.sourceforge.net Mon Oct 15 14:45:51 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 15 Oct 2001 06:45:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libbinascii.tex,1.21,1.22 libzlib.tex,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv20687 Modified Files: libbinascii.tex libzlib.tex Log Message: Added notes to clarify that binascii.crc32(), zlib.crc32(), and zlib.adler32() are not suitable as general hash functions. Index: libbinascii.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libbinascii.tex,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** libbinascii.tex 2001/09/30 20:32:10 1.21 --- libbinascii.tex 2001/10/15 13:45:49 1.22 *************** *** 93,97 **** \begin{funcdesc}{crc32}{data\optional{, crc}} Compute CRC-32, the 32-bit checksum of data, starting with an initial ! crc. This is consistent with the ZIP file checksum. Use as follows: \begin{verbatim} print binascii.crc32("hello world") --- 93,99 ---- \begin{funcdesc}{crc32}{data\optional{, crc}} Compute CRC-32, the 32-bit checksum of data, starting with an initial ! crc. This is consistent with the ZIP file checksum. Since the ! algorithm is designed for use as a checksum algorithm, it is not ! suitable for use as a general hash algorithm. Use as follows: \begin{verbatim} print binascii.crc32("hello world") Index: libzlib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libzlib.tex,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** libzlib.tex 2001/06/25 15:30:13 1.25 --- libzlib.tex 2001/10/15 13:45:49 1.26 *************** *** 30,34 **** concatenation of several input strings. The algorithm is not cryptographically strong, and should not be used for ! authentication or digital signatures. \end{funcdesc} --- 30,36 ---- concatenation of several input strings. The algorithm is not cryptographically strong, and should not be used for ! authentication or digital signatures. Since the algorithm is ! designed for use as a checksum algorithm, it is not suitable for ! use as a general hash algorithm. \end{funcdesc} *************** *** 59,63 **** computing a running checksum over the concatenation of several input strings. The algorithm is not cryptographically strong, and ! should not be used for authentication or digital signatures. \end{funcdesc} --- 61,67 ---- computing a running checksum over the concatenation of several input strings. The algorithm is not cryptographically strong, and ! should not be used for authentication or digital signatures. Since ! the algorithm is designed for use as a checksum algorithm, it is not ! suitable for use as a general hash algorithm. \end{funcdesc} From gvanrossum@users.sourceforge.net Mon Oct 15 14:46:12 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 06:46:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib imaplib.py,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv20796 Modified Files: imaplib.py Log Message: SF bug #469910 by Alfonso Baciero: Bugfix for imaplib for macintosh Pass binary mode to makefile(). Index: imaplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/imaplib.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** imaplib.py 2001/08/13 15:34:41 1.34 --- imaplib.py 2001/10/15 13:46:10 1.35 *************** *** 208,212 **** self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((self.host, self.port)) ! self.file = self.sock.makefile('r') --- 208,212 ---- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((self.host, self.port)) ! self.file = self.sock.makefile('rb') From gvanrossum@users.sourceforge.net Mon Oct 15 14:47:10 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 06:47:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.119,1.120 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv21176 Modified Files: ACKS Log Message: SF bug #469910 by Alfonso Baciero: Bugfix for imaplib for macintosh Pass binary mode to makefile(). Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.119 retrieving revision 1.120 diff -C2 -d -r1.119 -r1.120 *** ACKS 2001/10/12 21:54:29 1.119 --- ACKS 2001/10/15 13:47:08 1.120 *************** *** 21,24 **** --- 21,25 ---- David Ascher Donovan Baarda + Alfonso Baciero Stig Bakken Greg Ball From loewis@users.sourceforge.net Mon Oct 15 15:34:44 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Mon, 15 Oct 2001 07:34:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python thread_pthread.h,2.33,2.34 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv3346/Python Modified Files: thread_pthread.h Log Message: Do not define _POSIX_THREADS if unistd.h defines it. Check for pthread_sigmask before using it. Fixes remaining problem in #470781. Index: thread_pthread.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_pthread.h,v retrieving revision 2.33 retrieving revision 2.34 diff -C2 -d -r2.33 -r2.34 *** thread_pthread.h 2001/10/12 21:49:17 2.33 --- thread_pthread.h 2001/10/15 14:34:42 2.34 *************** *** 76,80 **** * pthread implementation. */ ! #ifdef PY_PTHREAD_STD # define SET_THREAD_SIGMASK pthread_sigmask #else --- 76,80 ---- * pthread implementation. */ ! #ifdef HAVE_PTHREAD_SIGMASK # define SET_THREAD_SIGMASK pthread_sigmask #else From loewis@users.sourceforge.net Mon Oct 15 15:34:44 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Mon, 15 Oct 2001 07:34:44 -0700 Subject: [Python-checkins] CVS: python/dist/src pyconfig.h.in,1.14,1.15 configure,1.260,1.261 configure.in,1.268,1.269 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv3346 Modified Files: pyconfig.h.in configure configure.in Log Message: Do not define _POSIX_THREADS if unistd.h defines it. Check for pthread_sigmask before using it. Fixes remaining problem in #470781. Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** pyconfig.h.in 2001/10/13 09:12:40 1.14 --- pyconfig.h.in 2001/10/15 14:34:42 1.15 *************** *** 478,481 **** --- 478,484 ---- #undef HAVE_PTHREAD_INIT + /* Define if you have the pthread_sigmask function. */ + #undef HAVE_PTHREAD_SIGMASK + /* Define if you have the putenv function. */ #undef HAVE_PUTENV Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.260 retrieving revision 1.261 diff -C2 -d -r1.260 -r1.261 *** configure 2001/10/15 08:06:29 1.260 --- configure 2001/10/15 14:34:42 1.261 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.267 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.268 [...2880 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 < *************** *** 7296,7300 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7299: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 7340,7344 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7343: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.268 retrieving revision 1.269 diff -C2 -d -r1.268 -r1.269 *** configure.in 2001/10/15 08:06:29 1.268 --- configure.in 2001/10/15 14:34:42 1.269 *************** *** 969,973 **** then AC_DEFINE(WITH_THREAD) - AC_DEFINE(_POSIX_THREADS) # Defining _REENTRANT on system with POSIX threads should not hurt. AC_DEFINE(_REENTRANT) --- 969,972 ---- *************** *** 978,982 **** CC="$CC -Kpthread" AC_DEFINE(WITH_THREAD) - AC_DEFINE(_POSIX_THREADS) posix_threads=yes LIBOBJS="$LIBOBJS thread.o" --- 977,980 ---- *************** *** 988,991 **** --- 986,1001 ---- then LDFLAGS="$LDFLAGS -L$withval" fi + + # According to the POSIX spec, a pthreads implementation must + # define _POSIX_THREADS in unistd.h. Some apparently don't (which ones?) + AC_MSG_CHECKING(for _POSIX_THREADS in unistd.h) + AC_EGREP_CPP(yes, + [#include + #ifdef _POSIX_THREADS + yes + #endif + ], unistd_defines_pthreads=yes, unistd_defines_pthreads=no) + AC_MSG_RESULT($unistd_defines_pthreads) + AC_DEFINE(_REENTRANT) AC_CHECK_HEADER(mach/cthreads.h, [AC_DEFINE(WITH_THREAD) *************** *** 1014,1032 **** AC_MSG_RESULT(yes) AC_DEFINE(WITH_THREAD) ! case $ac_sys_system in ! Darwin*) ;; ! *) AC_DEFINE(_POSIX_THREADS) ! posix_threads=yes ! ;; ! esac LIBOBJS="$LIBOBJS thread.o"],[ LIBS=$_libs AC_CHECK_FUNC(pthread_detach, [AC_DEFINE(WITH_THREAD) ! case $ac_sys_system in ! Darwin*) ;; ! *) AC_DEFINE(_POSIX_THREADS) ! posix_threads=yes ! ;; ! esac LIBOBJS="$LIBOBJS thread.o"],[ AC_CHECK_HEADER(kernel/OS.h, [AC_DEFINE(WITH_THREAD) --- 1024,1032 ---- AC_MSG_RESULT(yes) AC_DEFINE(WITH_THREAD) ! posix_threads=yes LIBOBJS="$LIBOBJS thread.o"],[ LIBS=$_libs AC_CHECK_FUNC(pthread_detach, [AC_DEFINE(WITH_THREAD) ! posix_threads=yes LIBOBJS="$LIBOBJS thread.o"],[ AC_CHECK_HEADER(kernel/OS.h, [AC_DEFINE(WITH_THREAD) *************** *** 1034,1058 **** LIBOBJS="$LIBOBJS thread.o"],[ AC_CHECK_LIB(pthreads, pthread_create, [AC_DEFINE(WITH_THREAD) - AC_DEFINE(_POSIX_THREADS) posix_threads=yes LIBS="$LIBS -lpthreads" LIBOBJS="$LIBOBJS thread.o"], [ AC_CHECK_LIB(c_r, pthread_create, [AC_DEFINE(WITH_THREAD) - AC_DEFINE(_POSIX_THREADS) posix_threads=yes LIBS="$LIBS -lc_r" LIBOBJS="$LIBOBJS thread.o"], [ AC_CHECK_LIB(thread, __d6_pthread_create, [AC_DEFINE(WITH_THREAD) - AC_DEFINE(_POSIX_THREADS) posix_threads=yes LIBS="$LIBS -lthread" LIBOBJS="$LIBOBJS thread.o"], [ AC_CHECK_LIB(pthread, __pthread_create_system, [AC_DEFINE(WITH_THREAD) - AC_DEFINE(_POSIX_THREADS) posix_threads=yes LIBS="$LIBS -lpthread" LIBOBJS="$LIBOBJS thread.o"], [ AC_CHECK_LIB(cma, pthread_create, [AC_DEFINE(WITH_THREAD) - AC_DEFINE(_POSIX_THREADS) posix_threads=yes LIBS="$LIBS -lcma" --- 1034,1053 ---- *************** *** 1062,1065 **** --- 1057,1064 ---- if test "$posix_threads" = "yes"; then + if test "$unistd_defines_pthreads" = "no"; then + AC_DEFINE(_POSIX_THREADS) + fi + AC_MSG_CHECKING(if PTHREAD_SCOPE_SYSTEM is supported) AC_CACHE_VAL(ac_cv_pthread_system_supported, *************** *** 1083,1086 **** --- 1082,1086 ---- AC_DEFINE(PTHREAD_SYSTEM_SCHED_SUPPORTED) fi + AC_CHECK_FUNCS(pthread_sigmask) fi From gvanrossum@users.sourceforge.net Mon Oct 15 16:44:06 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 08:44:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Grammar Grammar,1.44,1.45 Message-ID: Update of /cvsroot/python/python/dist/src/Grammar In directory usw-pr-cvs1:/tmp/cvs-serv24320/Grammar Modified Files: Grammar Log Message: Very subtle syntax change: in a list comprehension, the testlist in "for in may no longer be a single test followed by a comma. This solves SF bug #431886. Note that if the testlist contains more than one test, a trailing comma is still allowed, for maximum backward compatibility; but this example is not: [(x, y) for x in range(10), for y in range(10)] ^ The fix involved creating a new nonterminal 'testlist_safe' whose definition doesn't allow the trailing comma if there's only one test: testlist_safe: test [(',' test)+ [',']] Index: Grammar =================================================================== RCS file: /cvsroot/python/python/dist/src/Grammar/Grammar,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** Grammar 2001/08/08 05:00:17 1.44 --- Grammar 2001/10/15 15:44:04 1.45 *************** *** 90,93 **** --- 90,94 ---- exprlist: expr (',' expr)* [','] testlist: test (',' test)* [','] + testlist_safe: test [(',' test)+ [',']] dictmaker: test ':' test (',' test ':' test)* [','] *************** *** 98,101 **** list_iter: list_for | list_if ! list_for: 'for' exprlist 'in' testlist [list_iter] list_if: 'if' test [list_iter] --- 99,102 ---- list_iter: list_for | list_if ! list_for: 'for' exprlist 'in' testlist_safe [list_iter] list_if: 'if' test [list_iter] From gvanrossum@users.sourceforge.net Mon Oct 15 16:44:07 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 08:44:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include graminit.h,2.17,2.18 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv24320/Include Modified Files: graminit.h Log Message: Very subtle syntax change: in a list comprehension, the testlist in "for in may no longer be a single test followed by a comma. This solves SF bug #431886. Note that if the testlist contains more than one test, a trailing comma is still allowed, for maximum backward compatibility; but this example is not: [(x, y) for x in range(10), for y in range(10)] ^ The fix involved creating a new nonterminal 'testlist_safe' whose definition doesn't allow the trailing comma if there's only one test: testlist_safe: test [(',' test)+ [',']] Index: graminit.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/graminit.h,v retrieving revision 2.17 retrieving revision 2.18 diff -C2 -d -r2.17 -r2.18 *** graminit.h 2001/06/18 22:08:13 2.17 --- graminit.h 2001/10/15 15:44:04 2.18 *************** *** 57,65 **** #define exprlist 312 #define testlist 313 ! #define dictmaker 314 ! #define classdef 315 ! #define arglist 316 ! #define argument 317 ! #define list_iter 318 ! #define list_for 319 ! #define list_if 320 --- 57,66 ---- #define exprlist 312 #define testlist 313 ! #define testlist_safe 314 ! #define dictmaker 315 ! #define classdef 316 ! #define arglist 317 ! #define argument 318 ! #define list_iter 319 ! #define list_for 320 ! #define list_if 321 From gvanrossum@users.sourceforge.net Mon Oct 15 16:44:07 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 08:44:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules parsermodule.c,2.65,2.66 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv24320/Modules Modified Files: parsermodule.c Log Message: Very subtle syntax change: in a list comprehension, the testlist in "for in may no longer be a single test followed by a comma. This solves SF bug #431886. Note that if the testlist contains more than one test, a trailing comma is still allowed, for maximum backward compatibility; but this example is not: [(x, y) for x in range(10), for y in range(10)] ^ The fix involved creating a new nonterminal 'testlist_safe' whose definition doesn't allow the trailing comma if there's only one test: testlist_safe: test [(',' test)+ [',']] Index: parsermodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/parsermodule.c,v retrieving revision 2.65 retrieving revision 2.66 diff -C2 -d -r2.65 -r2.66 *** parsermodule.c 2001/08/15 16:44:56 2.65 --- parsermodule.c 2001/10/15 15:44:05 2.66 *************** *** 1040,1043 **** --- 1040,1051 ---- + static int + validate_testlist_safe(node *tree) + { + return (validate_repeating_list(tree, testlist_safe, + validate_test, "testlist_safe")); + } + + /* '*' NAME [',' '**' NAME] | '**' NAME */ *************** *** 1219,1223 **** && validate_exprlist(CHILD(tree, 1)) && validate_name(CHILD(tree, 2), "in") ! && validate_testlist(CHILD(tree, 3))); return res; --- 1227,1231 ---- && validate_exprlist(CHILD(tree, 1)) && validate_name(CHILD(tree, 2), "in") ! && validate_testlist_safe(CHILD(tree, 3))); return res; From gvanrossum@users.sourceforge.net Mon Oct 15 16:44:07 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 08:44:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python compile.c,2.224,2.225 graminit.c,2.30,2.31 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv24320/Python Modified Files: compile.c graminit.c Log Message: Very subtle syntax change: in a list comprehension, the testlist in "for in may no longer be a single test followed by a comma. This solves SF bug #431886. Note that if the testlist contains more than one test, a trailing comma is still allowed, for maximum backward compatibility; but this example is not: [(x, y) for x in range(10), for y in range(10)] ^ The fix involved creating a new nonterminal 'testlist_safe' whose definition doesn't allow the trailing comma if there's only one test: testlist_safe: test [(',' test)+ [',']] Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.224 retrieving revision 2.225 diff -C2 -d -r2.224 -r2.225 *** compile.c 2001/09/20 20:46:19 2.224 --- compile.c 2001/10/15 15:44:05 2.225 *************** *** 3711,3714 **** --- 3711,3715 ---- case testlist: + case testlist_safe: com_list(c, n, 0); break; Index: graminit.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/graminit.c,v retrieving revision 2.30 retrieving revision 2.31 diff -C2 -d -r2.30 -r2.31 *** graminit.c 2001/08/08 05:00:18 2.30 --- graminit.c 2001/10/15 15:44:05 2.31 *************** *** 1256,1261 **** {21, 1}, }; ! static arc arcs_58_1[1] = { ! {14, 2}, }; static arc arcs_58_2[1] = { --- 1256,1262 ---- {21, 1}, }; ! static arc arcs_58_1[2] = { ! {22, 2}, ! {0, 1}, }; static arc arcs_58_2[1] = { *************** *** 1267,1276 **** }; static arc arcs_58_4[2] = { ! {21, 1}, {0, 4}, }; static state states_58[5] = { {1, arcs_58_0}, ! {1, arcs_58_1}, {1, arcs_58_2}, {2, arcs_58_3}, --- 1268,1277 ---- }; static arc arcs_58_4[2] = { ! {21, 3}, {0, 4}, }; static state states_58[5] = { {1, arcs_58_0}, ! {2, arcs_58_1}, {1, arcs_58_2}, {2, arcs_58_3}, *************** *** 1278,1437 **** }; static arc arcs_59_0[1] = { ! {142, 1}, }; static arc arcs_59_1[1] = { {12, 2}, }; ! static arc arcs_59_2[2] = { {16, 3}, {14, 4}, }; ! static arc arcs_59_3[1] = { {9, 5}, }; ! static arc arcs_59_4[1] = { {15, 6}, }; ! static arc arcs_59_5[1] = { {18, 7}, }; ! static arc arcs_59_6[1] = { {0, 6}, }; ! static arc arcs_59_7[1] = { {14, 4}, }; ! static state states_59[8] = { ! {1, arcs_59_0}, ! {1, arcs_59_1}, ! {2, arcs_59_2}, ! {1, arcs_59_3}, ! {1, arcs_59_4}, ! {1, arcs_59_5}, ! {1, arcs_59_6}, ! {1, arcs_59_7}, }; ! static arc arcs_60_0[3] = { ! {143, 1}, {23, 2}, {24, 3}, }; ! static arc arcs_60_1[2] = { {22, 4}, {0, 1}, }; ! static arc arcs_60_2[1] = { {21, 5}, }; ! static arc arcs_60_3[1] = { {21, 6}, }; ! static arc arcs_60_4[4] = { ! {143, 1}, {23, 2}, {24, 3}, {0, 4}, }; ! static arc arcs_60_5[2] = { {22, 7}, {0, 5}, }; ! static arc arcs_60_6[1] = { {0, 6}, }; ! static arc arcs_60_7[1] = { {24, 3}, }; ! static state states_60[8] = { ! {3, arcs_60_0}, ! {2, arcs_60_1}, ! {1, arcs_60_2}, ! {1, arcs_60_3}, ! {4, arcs_60_4}, ! {2, arcs_60_5}, ! {1, arcs_60_6}, ! {1, arcs_60_7}, }; ! static arc arcs_61_0[1] = { {21, 1}, }; ! static arc arcs_61_1[2] = { {20, 2}, {0, 1}, }; ! static arc arcs_61_2[1] = { {21, 3}, }; ! static arc arcs_61_3[1] = { {0, 3}, }; ! static state states_61[4] = { ! {1, arcs_61_0}, ! {2, arcs_61_1}, ! {1, arcs_61_2}, ! {1, arcs_61_3}, }; ! static arc arcs_62_0[2] = { {136, 1}, ! {145, 1}, }; ! static arc arcs_62_1[1] = { {0, 1}, }; ! static state states_62[2] = { ! {2, arcs_62_0}, ! {1, arcs_62_1}, }; ! static arc arcs_63_0[1] = { {85, 1}, }; ! static arc arcs_63_1[1] = { {53, 2}, }; ! static arc arcs_63_2[1] = { {74, 3}, }; ! static arc arcs_63_3[1] = { ! {9, 4}, }; ! static arc arcs_63_4[2] = { ! {144, 5}, {0, 4}, }; ! static arc arcs_63_5[1] = { {0, 5}, }; ! static state states_63[6] = { ! {1, arcs_63_0}, ! {1, arcs_63_1}, ! {1, arcs_63_2}, ! {1, arcs_63_3}, ! {2, arcs_63_4}, ! {1, arcs_63_5}, }; ! static arc arcs_64_0[1] = { {81, 1}, }; ! static arc arcs_64_1[1] = { {21, 2}, }; ! static arc arcs_64_2[2] = { ! {144, 3}, {0, 2}, }; ! static arc arcs_64_3[1] = { {0, 3}, }; ! static state states_64[4] = { ! {1, arcs_64_0}, ! {1, arcs_64_1}, ! {2, arcs_64_2}, ! {1, arcs_64_3}, }; ! static dfa dfas[65] = { {256, "single_input", 0, 3, states_0, ! "\004\030\001\000\000\000\124\360\213\011\162\000\002\000\140\210\344\102\000"}, {257, "file_input", 0, 2, states_1, ! "\204\030\001\000\000\000\124\360\213\011\162\000\002\000\140\210\344\102\000"}, {258, "eval_input", 0, 3, states_2, "\000\020\001\000\000\000\000\000\000\000\000\000\002\000\140\210\344\002\000"}, --- 1279,1462 ---- }; static arc arcs_59_0[1] = { ! {21, 1}, }; static arc arcs_59_1[1] = { + {14, 2}, + }; + static arc arcs_59_2[1] = { + {21, 3}, + }; + static arc arcs_59_3[2] = { + {22, 4}, + {0, 3}, + }; + static arc arcs_59_4[2] = { + {21, 1}, + {0, 4}, + }; + static state states_59[5] = { + {1, arcs_59_0}, + {1, arcs_59_1}, + {1, arcs_59_2}, + {2, arcs_59_3}, + {2, arcs_59_4}, + }; + static arc arcs_60_0[1] = { + {143, 1}, + }; + static arc arcs_60_1[1] = { {12, 2}, }; ! static arc arcs_60_2[2] = { {16, 3}, {14, 4}, }; ! static arc arcs_60_3[1] = { {9, 5}, }; ! static arc arcs_60_4[1] = { {15, 6}, }; ! static arc arcs_60_5[1] = { {18, 7}, }; ! static arc arcs_60_6[1] = { {0, 6}, }; ! static arc arcs_60_7[1] = { {14, 4}, }; ! static state states_60[8] = { ! {1, arcs_60_0}, ! {1, arcs_60_1}, ! {2, arcs_60_2}, ! {1, arcs_60_3}, ! {1, arcs_60_4}, ! {1, arcs_60_5}, ! {1, arcs_60_6}, ! {1, arcs_60_7}, }; ! static arc arcs_61_0[3] = { ! {144, 1}, {23, 2}, {24, 3}, }; ! static arc arcs_61_1[2] = { {22, 4}, {0, 1}, }; ! static arc arcs_61_2[1] = { {21, 5}, }; ! static arc arcs_61_3[1] = { {21, 6}, }; ! static arc arcs_61_4[4] = { ! {144, 1}, {23, 2}, {24, 3}, {0, 4}, }; ! static arc arcs_61_5[2] = { {22, 7}, {0, 5}, }; ! static arc arcs_61_6[1] = { {0, 6}, }; ! static arc arcs_61_7[1] = { {24, 3}, }; ! static state states_61[8] = { ! {3, arcs_61_0}, ! {2, arcs_61_1}, ! {1, arcs_61_2}, ! {1, arcs_61_3}, ! {4, arcs_61_4}, ! {2, arcs_61_5}, ! {1, arcs_61_6}, ! {1, arcs_61_7}, }; ! static arc arcs_62_0[1] = { {21, 1}, }; ! static arc arcs_62_1[2] = { {20, 2}, {0, 1}, }; ! static arc arcs_62_2[1] = { {21, 3}, }; ! static arc arcs_62_3[1] = { {0, 3}, }; ! static state states_62[4] = { ! {1, arcs_62_0}, ! {2, arcs_62_1}, ! {1, arcs_62_2}, ! {1, arcs_62_3}, }; ! static arc arcs_63_0[2] = { {136, 1}, ! {146, 1}, }; ! static arc arcs_63_1[1] = { {0, 1}, }; ! static state states_63[2] = { ! {2, arcs_63_0}, ! {1, arcs_63_1}, }; ! static arc arcs_64_0[1] = { {85, 1}, }; ! static arc arcs_64_1[1] = { {53, 2}, }; ! static arc arcs_64_2[1] = { {74, 3}, }; ! static arc arcs_64_3[1] = { ! {142, 4}, }; ! static arc arcs_64_4[2] = { ! {145, 5}, {0, 4}, }; ! static arc arcs_64_5[1] = { {0, 5}, }; ! static state states_64[6] = { ! {1, arcs_64_0}, ! {1, arcs_64_1}, ! {1, arcs_64_2}, ! {1, arcs_64_3}, ! {2, arcs_64_4}, ! {1, arcs_64_5}, }; ! static arc arcs_65_0[1] = { {81, 1}, }; ! static arc arcs_65_1[1] = { {21, 2}, }; ! static arc arcs_65_2[2] = { ! {145, 3}, {0, 2}, }; ! static arc arcs_65_3[1] = { {0, 3}, }; ! static state states_65[4] = { ! {1, arcs_65_0}, ! {1, arcs_65_1}, ! {2, arcs_65_2}, ! {1, arcs_65_3}, }; ! static dfa dfas[66] = { {256, "single_input", 0, 3, states_0, ! "\004\030\001\000\000\000\124\360\213\011\162\000\002\000\140\210\344\202\000"}, {257, "file_input", 0, 2, states_1, ! "\204\030\001\000\000\000\124\360\213\011\162\000\002\000\140\210\344\202\000"}, {258, "eval_input", 0, 3, states_2, "\000\020\001\000\000\000\000\000\000\000\000\000\002\000\140\210\344\002\000"}, *************** *** 1447,1451 **** "\000\020\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {264, "stmt", 0, 2, states_8, ! "\000\030\001\000\000\000\124\360\213\011\162\000\002\000\140\210\344\102\000"}, {265, "simple_stmt", 0, 4, states_9, "\000\020\001\000\000\000\124\360\213\011\000\000\002\000\140\210\344\002\000"}, --- 1472,1476 ---- "\000\020\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {264, "stmt", 0, 2, states_8, ! "\000\030\001\000\000\000\124\360\213\011\162\000\002\000\140\210\344\202\000"}, {265, "simple_stmt", 0, 4, states_9, "\000\020\001\000\000\000\124\360\213\011\000\000\002\000\140\210\344\002\000"}, *************** *** 1489,1493 **** "\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000"}, {285, "compound_stmt", 0, 2, states_29, ! "\000\010\000\000\000\000\000\000\000\000\162\000\000\000\000\000\000\100\000"}, {286, "if_stmt", 0, 8, states_30, "\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"}, --- 1514,1518 ---- "\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000"}, {285, "compound_stmt", 0, 2, states_29, ! "\000\010\000\000\000\000\000\000\000\000\162\000\000\000\000\000\000\200\000"}, {286, "if_stmt", 0, 8, states_30, "\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"}, *************** *** 1546,1565 **** {313, "testlist", 0, 3, states_57, "\000\020\001\000\000\000\000\000\000\000\000\000\002\000\140\210\344\002\000"}, ! {314, "dictmaker", 0, 5, states_58, "\000\020\001\000\000\000\000\000\000\000\000\000\002\000\140\210\344\002\000"}, ! {315, "classdef", 0, 8, states_59, ! "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\100\000"}, ! {316, "arglist", 0, 8, states_60, "\000\020\201\001\000\000\000\000\000\000\000\000\002\000\140\210\344\002\000"}, ! {317, "argument", 0, 4, states_61, "\000\020\001\000\000\000\000\000\000\000\000\000\002\000\140\210\344\002\000"}, ! {318, "list_iter", 0, 2, states_62, "\000\000\000\000\000\000\000\000\000\000\042\000\000\000\000\000\000\000\000"}, ! {319, "list_for", 0, 6, states_63, "\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000"}, ! {320, "list_if", 0, 4, states_64, "\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"}, }; ! static label labels[146] = { {0, "EMPTY"}, {256, 0}, --- 1571,1592 ---- {313, "testlist", 0, 3, states_57, "\000\020\001\000\000\000\000\000\000\000\000\000\002\000\140\210\344\002\000"}, ! {314, "testlist_safe", 0, 5, states_58, "\000\020\001\000\000\000\000\000\000\000\000\000\002\000\140\210\344\002\000"}, ! {315, "dictmaker", 0, 5, states_59, ! "\000\020\001\000\000\000\000\000\000\000\000\000\002\000\140\210\344\002\000"}, ! {316, "classdef", 0, 8, states_60, ! "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000"}, ! {317, "arglist", 0, 8, states_61, "\000\020\201\001\000\000\000\000\000\000\000\000\002\000\140\210\344\002\000"}, ! {318, "argument", 0, 4, states_62, "\000\020\001\000\000\000\000\000\000\000\000\000\002\000\140\210\344\002\000"}, ! {319, "list_iter", 0, 2, states_63, "\000\000\000\000\000\000\000\000\000\000\042\000\000\000\000\000\000\000\000"}, ! {320, "list_for", 0, 6, states_64, "\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000"}, ! {321, "list_if", 0, 4, states_65, "\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"}, }; ! static label labels[147] = { {0, "EMPTY"}, {256, 0}, *************** *** 1642,1646 **** {288, 0}, {289, 0}, ! {315, 0}, {1, "if"}, {1, "elif"}, --- 1669,1673 ---- {288, 0}, {289, 0}, ! {316, 0}, {1, "if"}, {1, "elif"}, *************** *** 1693,1716 **** {10, 0}, {26, 0}, ! {314, 0}, {27, 0}, {25, 0}, {2, 0}, {3, 0}, ! {319, 0}, {1, "lambda"}, ! {316, 0}, {309, 0}, {310, 0}, {311, 0}, {1, "class"}, - {317, 0}, {318, 0}, ! {320, 0}, }; grammar _PyParser_Grammar = { ! 65, dfas, ! {146, labels}, 256 }; --- 1720,1744 ---- {10, 0}, {26, 0}, ! {315, 0}, {27, 0}, {25, 0}, {2, 0}, {3, 0}, ! {320, 0}, {1, "lambda"}, ! {317, 0}, {309, 0}, {310, 0}, {311, 0}, + {314, 0}, {1, "class"}, {318, 0}, ! {319, 0}, ! {321, 0}, }; grammar _PyParser_Grammar = { ! 66, dfas, ! {147, labels}, 256 }; From gvanrossum@users.sourceforge.net Mon Oct 15 16:54:01 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 08:54:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.275,1.276 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv29005 Modified Files: NEWS Log Message: Note about fix in list comprehensions. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.275 retrieving revision 1.276 diff -C2 -d -r1.275 -r1.276 *** NEWS 2001/10/09 22:39:40 1.275 --- NEWS 2001/10/15 15:53:58 1.276 *************** *** 23,26 **** --- 23,35 ---- Core + - A very subtle syntactical pitfall in list comprehensions was fixed. + For example: [a+b for a in 'abc', for b in 'def']. The comma in + this example is a mistake. Previously, this would silently let 'a' + iterate over the singleton tuple ('abc',), yielding ['abcd', 'abce', + 'abcf'] rather than the intended ['ad', 'ae', 'af', 'bd', 'be', + 'bf', 'cd', 'ce', 'cf']. Now, this is flagged as a syntax error. + Note that [a for a in ] is a convoluted way to say + [] anyway, so it's not like any expressiveness is lost. + - binascii has now two quopri support functions, a2b_qp and b2a_qp. From gvanrossum@users.sourceforge.net Mon Oct 15 18:23:15 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 10:23:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include node.h,2.18,2.19 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv22162 Modified Files: node.h Log Message: Use an assert() for the REQ() macro instead of making up our own assertion. Index: node.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/node.h,v retrieving revision 2.18 retrieving revision 2.19 diff -C2 -d -r2.18 -r2.19 *** node.h 2000/09/01 23:29:26 2.18 --- node.h 2001/10/15 17:23:13 2.19 *************** *** 28,41 **** /* Assert that the type of a node is what we expect */ ! #ifndef Py_DEBUG ! #define REQ(n, type) { /*pass*/ ; } ! #else ! #define REQ(n, type) \ ! { if (TYPE(n) != (type)) { \ ! fprintf(stderr, "FATAL: node type %d, required %d\n", \ ! TYPE(n), type); \ ! abort(); \ ! } } ! #endif extern DL_IMPORT(void) PyNode_ListTree(node *); --- 28,32 ---- /* Assert that the type of a node is what we expect */ ! #define REQ(n, type) assert(TYPE(n) == (type)) extern DL_IMPORT(void) PyNode_ListTree(node *); From gvanrossum@users.sourceforge.net Mon Oct 15 19:44:03 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 11:44:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib quopri.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv14343 Modified Files: quopri.py Log Message: Patch 471400: escape single-dot lines; by Jason Hildebrand. RFC 2049 recommends never outputting a line consisting of a single dot. Index: quopri.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/quopri.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** quopri.py 2001/10/04 05:36:56 1.17 --- quopri.py 2001/10/15 18:44:01 1.18 *************** *** 62,65 **** --- 62,67 ---- if s and s[-1:] in ' \t': output.write(s[:-1] + quote(s[-1]) + lineEnd) + elif s == '.': + output.write(quote(s) + lineEnd) else: output.write(s + lineEnd) From gvanrossum@users.sourceforge.net Mon Oct 15 19:44:28 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 11:44:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.120,1.121 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv14491 Modified Files: ACKS Log Message: Patch 471400: escape single-dot lines; by Jason Hildebrand. RFC 2049 recommends never outputting a line consisting of a single dot. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.120 retrieving revision 1.121 diff -C2 -d -r1.120 -r1.121 *** ACKS 2001/10/15 13:47:08 1.120 --- ACKS 2001/10/15 18:44:26 1.121 *************** *** 181,184 **** --- 181,185 ---- Magnus L. Hetland Kevan Heydon + Jason Hildebrand Konrad Hinsen David Hobley From gvanrossum@users.sourceforge.net Mon Oct 15 20:44:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 12:44:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.102,2.103 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv2339 Modified Files: typeobject.c Log Message: Add (void *) casts to solve some problems on HP-UX 11.0, as discussed on SF bug #467145. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.102 retrieving revision 2.103 diff -C2 -d -r2.102 -r2.103 *** typeobject.c 2001/10/13 20:02:41 2.102 --- typeobject.c 2001/10/15 19:44:24 2.103 *************** *** 3462,3466 **** getattribute->ob_type == &PyWrapperDescr_Type && ((PyWrapperDescrObject *)getattribute)->d_wrapped == ! PyObject_GenericGetAttr) getattribute = NULL; if (getattr == NULL && getattribute == NULL) { --- 3462,3466 ---- getattribute->ob_type == &PyWrapperDescr_Type && ((PyWrapperDescrObject *)getattribute)->d_wrapped == ! (void *)PyObject_GenericGetAttr) getattribute = NULL; if (getattr == NULL && getattribute == NULL) { *************** *** 3701,3707 **** #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ! {NAME, offsetof(PyTypeObject, SLOT), FUNCTION, WRAPPER} #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ! {NAME, offsetof(etype, SLOT), FUNCTION, WRAPPER} #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER) --- 3701,3707 ---- #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ! {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER} #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ! {NAME, offsetof(etype, SLOT), (void *)(FUNCTION), WRAPPER} #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER) From gvanrossum@users.sourceforge.net Mon Oct 15 20:55:14 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 12:55:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.121,1.122 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv6739 Modified Files: ACKS Log Message: Another contributor. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.121 retrieving revision 1.122 diff -C2 -d -r1.121 -r1.122 *** ACKS 2001/10/15 18:44:26 1.121 --- ACKS 2001/10/15 19:55:12 1.122 *************** *** 413,416 **** --- 413,417 ---- R Lindsay Todd Bennett Todd + Richard Townsend Laurence Tratt John Tromp From montanaro@users.sourceforge.net Mon Oct 15 21:51:40 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Mon, 15 Oct 2001 13:51:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.284,2.285 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv2103 Modified Files: ceval.c Log Message: make getarray static - it's only called from ceval.c and is not an extern-able name. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.284 retrieving revision 2.285 diff -C2 -d -r2.284 -r2.285 *** ceval.c 2001/10/13 06:11:28 2.284 --- ceval.c 2001/10/15 20:51:38 2.285 *************** *** 3645,3649 **** #ifdef DYNAMIC_EXECUTION_PROFILE ! PyObject * getarray(long a[256]) { --- 3645,3649 ---- #ifdef DYNAMIC_EXECUTION_PROFILE ! static PyObject * getarray(long a[256]) { From gvanrossum@users.sourceforge.net Mon Oct 15 22:05:12 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 14:05:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.95,2.96 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv7710/Include Modified Files: object.h Log Message: Completely get rid of __dynamic__ and the corresponding Py_TPFLAGS_DYNAMICTYPE bit. There is no longer a performance benefit, and I don't really see the use case any more. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.95 retrieving revision 2.96 diff -C2 -d -r2.95 -r2.96 *** object.h 2001/10/08 15:18:27 2.95 --- object.h 2001/10/15 21:05:10 2.96 *************** *** 433,439 **** #define Py_TPFLAGS_BASETYPE (1L<<10) - /* Set if the type's __dict__ may change */ - #define Py_TPFLAGS_DYNAMICTYPE (1L<<11) - /* Set if the type is 'ready' -- fully initialized */ #define Py_TPFLAGS_READY (1L<<12) --- 433,436 ---- From gvanrossum@users.sourceforge.net Mon Oct 15 22:05:12 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 14:05:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.103,2.104 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv7710/Objects Modified Files: typeobject.c Log Message: Completely get rid of __dynamic__ and the corresponding Py_TPFLAGS_DYNAMICTYPE bit. There is no longer a performance benefit, and I don't really see the use case any more. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.103 retrieving revision 2.104 diff -C2 -d -r2.103 -r2.104 *** typeobject.c 2001/10/15 19:44:24 2.103 --- typeobject.c 2001/10/15 21:05:10 2.104 *************** *** 57,61 **** type_set_module(PyTypeObject *type, PyObject *value, void *context) { ! if (!(type->tp_flags & Py_TPFLAGS_DYNAMICTYPE) || strrchr(type->tp_name, '.')) { PyErr_Format(PyExc_TypeError, --- 57,61 ---- type_set_module(PyTypeObject *type, PyObject *value, void *context) { ! if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) || strrchr(type->tp_name, '.')) { PyErr_Format(PyExc_TypeError, *************** *** 78,85 **** return Py_None; } - if (type->tp_flags & Py_TPFLAGS_DYNAMICTYPE) { - Py_INCREF(type->tp_dict); - return type->tp_dict; - } return PyDictProxy_New(type->tp_dict); } --- 78,81 ---- *************** *** 92,112 **** return Py_None; } - if (type->tp_flags & Py_TPFLAGS_DYNAMICTYPE) { - Py_INCREF(type->tp_defined); - return type->tp_defined; - } return PyDictProxy_New(type->tp_defined); } - static PyObject * - type_dynamic(PyTypeObject *type, void *context) - { - PyObject *res; - - res = (type->tp_flags & Py_TPFLAGS_DYNAMICTYPE) ? Py_True : Py_False; - Py_INCREF(res); - return res; - } - PyGetSetDef type_getsets[] = { {"__name__", (getter)type_name, NULL, NULL}, --- 88,94 ---- *************** *** 114,118 **** {"__dict__", (getter)type_dict, NULL, NULL}, {"__defined__", (getter)type_defined, NULL, NULL}, - {"__dynamic__", (getter)type_dynamic, NULL, NULL}, {0} }; --- 96,99 ---- *************** *** 712,716 **** etype *et; PyMemberDef *mp; ! int i, nbases, nslots, slotoffset, dynamic, add_dict, add_weak; /* Special case: type(x) should return x->ob_type */ --- 693,697 ---- etype *et; PyMemberDef *mp; ! int i, nbases, nslots, slotoffset, add_dict, add_weak; /* Special case: type(x) should return x->ob_type */ *************** *** 778,813 **** } - /* Should this be a dynamic class (i.e. modifiable __dict__)? - Look in two places for a variable named __dynamic__: - 1) in the class dict - 2) in the module dict (globals) - The first variable that is an int >= 0 is used. - Otherwise, the default is dynamic. */ - dynamic = -1; /* Not yet determined */ - /* Look in the class */ - tmp = PyDict_GetItemString(dict, "__dynamic__"); - if (tmp != NULL) { - dynamic = PyInt_AsLong(tmp); - if (dynamic < 0) - PyErr_Clear(); - } - if (dynamic < 0) { - /* Look in the module globals */ - tmp = PyEval_GetGlobals(); - if (tmp != NULL) { - tmp = PyDict_GetItemString(tmp, "__dynamic__"); - if (tmp != NULL) { - dynamic = PyInt_AsLong(tmp); - if (dynamic < 0) - PyErr_Clear(); - } - } - } - if (dynamic < 0) { - /* Default to dynamic */ - dynamic = 1; - - } - /* Check for a __slots__ sequence variable in dict, and count it */ slots = PyDict_GetItemString(dict, "__slots__"); --- 759,762 ---- *************** *** 869,874 **** type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | Py_TPFLAGS_BASETYPE; - if (dynamic) - type->tp_flags |= Py_TPFLAGS_DYNAMICTYPE; if (base->tp_flags & Py_TPFLAGS_HAVE_GC) type->tp_flags |= Py_TPFLAGS_HAVE_GC; --- 818,821 ---- *************** *** 1026,1038 **** int i, n; PyObject *mro, *res, *dict; - - /* For static types, look in tp_dict */ - if (!(type->tp_flags & Py_TPFLAGS_DYNAMICTYPE)) { - dict = type->tp_dict; - assert(dict && PyDict_Check(dict)); - return PyDict_GetItem(dict, name); - } ! /* For dynamic types, look in tp_defined of types in MRO */ mro = type->tp_mro; assert(PyTuple_Check(mro)); --- 973,978 ---- int i, n; PyObject *mro, *res, *dict; ! /* Look in tp_defined of types in MRO */ mro = type->tp_mro; assert(PyTuple_Check(mro)); *************** *** 1105,1115 **** type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) { ! if (type->tp_flags & Py_TPFLAGS_DYNAMICTYPE) { ! if (PyObject_GenericSetAttr((PyObject *)type, name, value) < 0) ! return -1; ! return update_slot(type, name); } ! PyErr_SetString(PyExc_TypeError, "can't set static type attributes"); ! return -1; } --- 1045,1058 ---- type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) { ! if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { ! PyErr_Format( ! PyExc_TypeError, ! "can't set attributes of built-in/extension type '%s'", ! type->tp_name); ! return -1; } ! if (PyObject_GenericSetAttr((PyObject *)type, name, value) < 0) ! return -1; ! return update_slot(type, name); } *************** *** 1795,1799 **** PyType_Ready(PyTypeObject *type) { ! PyObject *dict, *bases, *x; PyTypeObject *base; int i, n; --- 1738,1742 ---- PyType_Ready(PyTypeObject *type) { ! PyObject *dict, *bases; PyTypeObject *base; int i, n; *************** *** 1872,1906 **** /* Initialize tp_dict properly */ ! if (!PyType_HasFeature(type, Py_TPFLAGS_DYNAMICTYPE)) { ! /* For a static type, tp_dict is the consolidation ! of the tp_defined of its bases in MRO. */ ! Py_DECREF(type->tp_dict); ! type->tp_dict = PyDict_Copy(type->tp_defined); ! if (type->tp_dict == NULL) ! goto error; ! bases = type->tp_mro; ! assert(bases != NULL); ! assert(PyTuple_Check(bases)); ! n = PyTuple_GET_SIZE(bases); ! for (i = 1; i < n; i++) { ! base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); ! assert(PyType_Check(base)); ! x = base->tp_defined; ! if (x != NULL && PyDict_Merge(type->tp_dict, x, 0) < 0) ! goto error; ! inherit_slots(type, base); ! } ! } ! else { ! /* For a dynamic type, we simply inherit the base slots. */ ! bases = type->tp_mro; ! assert(bases != NULL); ! assert(PyTuple_Check(bases)); ! n = PyTuple_GET_SIZE(bases); ! for (i = 1; i < n; i++) { ! base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); ! assert(PyType_Check(base)); ! inherit_slots(type, base); ! } } --- 1815,1826 ---- /* Initialize tp_dict properly */ ! bases = type->tp_mro; ! assert(bases != NULL); ! assert(PyTuple_Check(bases)); ! n = PyTuple_GET_SIZE(bases); ! for (i = 1; i < n; i++) { ! base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); ! assert(PyType_Check(base)); ! inherit_slots(type, base); } From gvanrossum@users.sourceforge.net Mon Oct 15 22:05:12 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 14:05:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.88,1.89 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv7710/Lib/test Modified Files: test_descr.py Log Message: Completely get rid of __dynamic__ and the corresponding Py_TPFLAGS_DYNAMICTYPE bit. There is no longer a performance benefit, and I don't really see the use case any more. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.88 retrieving revision 1.89 diff -C2 -d -r1.88 -r1.89 *** test_descr.py 2001/10/12 02:38:24 1.88 --- test_descr.py 2001/10/15 21:05:10 1.89 *************** *** 18,21 **** --- 18,23 ---- t = type(a) m = getattr(t, meth) + while meth not in t.__dict__: + t = t.__bases__[0] vereq(m, t.__dict__[meth]) vereq(m(a), res) *************** *** 29,32 **** --- 31,36 ---- t = type(a) m = getattr(t, meth) + while meth not in t.__dict__: + t = t.__bases__[0] vereq(m, t.__dict__[meth]) vereq(m(a, b), res) *************** *** 40,43 **** --- 44,49 ---- t = type(a) m = getattr(t, meth) + while meth not in t.__dict__: + t = t.__bases__[0] vereq(m, t.__dict__[meth]) vereq(m(a, b, c), res) *************** *** 52,55 **** --- 58,63 ---- t = type(a) m = getattr(t, meth) + while meth not in t.__dict__: + t = t.__bases__[0] vereq(m, t.__dict__[meth]) dict['a'] = deepcopy(a) *************** *** 68,71 **** --- 76,81 ---- t = type(a) m = getattr(t, meth) + while meth not in t.__dict__: + t = t.__bases__[0] vereq(m, t.__dict__[meth]) dict['a'] = deepcopy(a) *************** *** 83,86 **** --- 93,98 ---- vereq(dict['a'], res) t = type(a) + while meth not in t.__dict__: + t = t.__bases__[0] m = getattr(t, meth) vereq(m, t.__dict__[meth]) *************** *** 105,114 **** class NewStatic(object): "Another docstring." - __dynamic__ = 0 vereq(NewStatic.__doc__, "Another docstring.") vereq(NewStatic.__dict__['__doc__'], "Another docstring.") class NewStatic2(object): - __dynamic__ = 0 pass verify(NewStatic2.__doc__ is None) --- 117,124 ---- *************** *** 116,125 **** class NewDynamic(object): "Another docstring." - __dynamic__ = 1 vereq(NewDynamic.__doc__, "Another docstring.") vereq(NewDynamic.__dict__['__doc__'], "Another docstring.") class NewDynamic2(object): - __dynamic__ = 1 pass verify(NewDynamic2.__doc__ is None) --- 126,133 ---- *************** *** 629,633 **** # This trick only works for dynamic classes def __new__(metaclass, name, bases, dict): - assert dict.get("__dynamic__", 1) cls = super(autosuper, metaclass).__new__(metaclass, name, bases, dict) --- 637,640 ---- *************** *** 864,892 **** def dynamics(): ! if verbose: print "Testing __dynamic__..." ! vereq(object.__dynamic__, 0) ! vereq(list.__dynamic__, 0) ! class S1: ! __metaclass__ = type ! __dynamic__ = 0 ! vereq(S1.__dynamic__, 0) ! class S(object): ! __dynamic__ = 0 ! vereq(S.__dynamic__, 0) class D(object): - __dynamic__ = 1 - vereq(D.__dynamic__, 1) - class E(D, S): pass ! vereq(E.__dynamic__, 1) ! class F(S, D): pass ! vereq(F.__dynamic__, 1) ! try: ! S.foo = 1 ! except (AttributeError, TypeError): pass - else: - verify(0, "assignment to a static class attribute should be illegal") D.foo = 1 vereq(D.foo, 1) --- 871,881 ---- def dynamics(): ! if verbose: print "Testing class attribute propagation..." class D(object): pass ! class E(D): pass ! class F(D): pass D.foo = 1 vereq(D.foo, 1) *************** *** 894,915 **** vereq(E.foo, 1) vereq(F.foo, 1) - class SS(D): - __dynamic__ = 0 - vereq(SS.__dynamic__, 0) - vereq(SS.foo, 1) - try: - SS.foo = 1 - except (AttributeError, TypeError): - pass - else: - verify(0, "assignment to SS.foo should be illegal") # Test dynamic instances class C(object): ! __dynamic__ = 1 ! # XXX Ideally the following def shouldn't be necessary, ! # but it's too much of a performance burden. ! # See XXX comment in slot_tp_getattr_hook. ! def __getattr__(self, name): ! raise AttributeError, name a = C() verify(not hasattr(a, "foobar")) --- 883,889 ---- vereq(E.foo, 1) vereq(F.foo, 1) # Test dynamic instances class C(object): ! pass a = C() verify(not hasattr(a, "foobar")) *************** *** 952,956 **** # Test handling of int*seq and seq*int class I(int): ! __dynamic__ = 1 # XXX why? vereq("a"*I(2), "aa") vereq(I(2)*"a", "aa") --- 926,930 ---- # Test handling of int*seq and seq*int class I(int): ! pass vereq("a"*I(2), "aa") vereq(I(2)*"a", "aa") *************** *** 961,965 **** # Test handling of long*seq and seq*long class L(long): ! __dynamic__ = 1 # XXX why? vereq("a"*L(2L), "aa") vereq(L(2L)*"a", "aa") --- 935,939 ---- # Test handling of long*seq and seq*long class L(long): ! pass vereq("a"*L(2L), "aa") vereq(L(2L)*"a", "aa") *************** *** 970,974 **** # Test comparison of classes with dynamic metaclasses class dynamicmetaclass(type): ! __dynamic__ = 1 # XXX ??? class someclass: __metaclass__ = dynamicmetaclass --- 944,948 ---- # Test comparison of classes with dynamic metaclasses class dynamicmetaclass(type): ! pass class someclass: __metaclass__ = dynamicmetaclass *************** *** 1256,1260 **** # Test the default behavior for dynamic classes class D(object): - __dynamic__ = 1 # XXX why? def __getitem__(self, i): if 0 <= i < 10: return i --- 1230,1233 ---- *************** *** 1319,1323 **** # Test overridden behavior for dynamic classes class DProxy(object): - __dynamic__ = 1 def __init__(self, x): self.x = x --- 1292,1295 ---- *************** *** 1470,1474 **** class C(A): - __dynamic__ = 1 def meth(self, a): return "C(%r)" % a + self.__super.meth(a) --- 1442,1445 ---- *************** *** 1566,1570 **** class madcomplex(complex): - __dynamic__ = 0 # XXX Shouldn't be necessary def __repr__(self): return "%.17gj%+.17g" % (self.imag, self.real) --- 1537,1540 ---- *************** *** 1968,1977 **** print "Testing rich comparisons..." class Z(complex): ! __dynamic__ = 0 z = Z(1) vereq(z, 1+0j) vereq(1+0j, z) class ZZ(complex): - __dynamic__ = 0 def __eq__(self, other): try: --- 1938,1946 ---- print "Testing rich comparisons..." class Z(complex): ! pass z = Z(1) vereq(z, 1+0j) vereq(1+0j, z) class ZZ(complex): def __eq__(self, other): try: *************** *** 2060,2065 **** coerce(0L, F(0)) coerce(0., F(0)) ! class C(complex): ! __dynamic__ = 0 coerce(C(0), 0) coerce(C(0), 0L) --- 2029,2033 ---- coerce(0L, F(0)) coerce(0., F(0)) ! class C(complex): pass coerce(C(0), 0) coerce(C(0), 0L) From gvanrossum@users.sourceforge.net Mon Oct 15 22:12:56 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 14:12:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.180,1.181 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv10059 Modified Files: socketmodule.c Log Message: Fix a bunch of warnings reported by Skip. To whoever who changed a bunch of (PyCFunction) casts to (PyNoArgsFunction) in PyMethodDef initializers: don't do that. The cast is to shut the compiler up. The compiler wants the function pointer initializer to be a PyCFunction. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.180 retrieving revision 1.181 diff -C2 -d -r1.180 -r1.181 *** socketmodule.c 2001/10/13 09:00:42 1.180 --- socketmodule.c 2001/10/15 21:12:54 1.181 *************** *** 1623,1631 **** static PyMethodDef PySocketSock_methods[] = { ! {"accept", (PyNoArgsFunction)PySocketSock_accept, METH_NOARGS, accept_doc}, {"bind", (PyCFunction)PySocketSock_bind, METH_O, bind_doc}, ! {"close", (PyNoArgsFunction)PySocketSock_close, METH_NOARGS, close_doc}, {"connect", (PyCFunction)PySocketSock_connect, METH_O, --- 1623,1631 ---- static PyMethodDef PySocketSock_methods[] = { ! {"accept", (PyCFunction)PySocketSock_accept, METH_NOARGS, accept_doc}, {"bind", (PyCFunction)PySocketSock_bind, METH_O, bind_doc}, ! {"close", (PyCFunction)PySocketSock_close, METH_NOARGS, close_doc}, {"connect", (PyCFunction)PySocketSock_connect, METH_O, *************** *** 1634,1647 **** connect_ex_doc}, #ifndef NO_DUP ! {"dup", (PyNoArgsFunction)PySocketSock_dup, METH_NOARGS, dup_doc}, #endif ! {"fileno", (PyNoArgsFunction)PySocketSock_fileno, METH_NOARGS, fileno_doc}, #ifdef HAVE_GETPEERNAME ! {"getpeername", (PyNoArgsFunction)PySocketSock_getpeername, METH_NOARGS, getpeername_doc}, #endif ! {"getsockname", (PyNoArgsFunction)PySocketSock_getsockname, METH_NOARGS, getsockname_doc}, {"getsockopt", (PyCFunction)PySocketSock_getsockopt, METH_VARARGS, --- 1634,1647 ---- connect_ex_doc}, #ifndef NO_DUP ! {"dup", (PyCFunction)PySocketSock_dup, METH_NOARGS, dup_doc}, #endif ! {"fileno", (PyCFunction)PySocketSock_fileno, METH_NOARGS, fileno_doc}, #ifdef HAVE_GETPEERNAME ! {"getpeername", (PyCFunction)PySocketSock_getpeername, METH_NOARGS, getpeername_doc}, #endif ! {"getsockname", (PyCFunction)PySocketSock_getsockname, METH_NOARGS, getsockname_doc}, {"getsockopt", (PyCFunction)PySocketSock_getsockopt, METH_VARARGS, *************** *** 2734,2739 **** {"read", (PyCFunction)PySSL_SSLread, 1, PySSL_SSLread_doc}, ! {"server", (PyNoArgsFunction)PySSL_server, METH_NOARGS}, ! {"issuer", (PyNoArgsFunction)PySSL_issuer, METH_NOARGS}, {NULL, NULL} }; --- 2734,2739 ---- {"read", (PyCFunction)PySSL_SSLread, 1, PySSL_SSLread_doc}, ! {"server", (PyCFunction)PySSL_server, METH_NOARGS}, ! {"issuer", (PyCFunction)PySSL_issuer, METH_NOARGS}, {NULL, NULL} }; From gvanrossum@users.sourceforge.net Mon Oct 15 22:24:14 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 14:24:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules xxmodule.c,2.23,2.24 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv12693 Modified Files: xxmodule.c Log Message: Remove a couple of tp_xxx fields that you are not expected to initialize (or use or even know about :-). Index: xxmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/xxmodule.c,v retrieving revision 2.23 retrieving revision 2.24 diff -C2 -d -r2.23 -r2.24 *** xxmodule.c 2001/10/09 10:46:58 2.23 --- xxmodule.c 2001/10/15 21:24:12 2.24 *************** *** 139,147 **** 0, /*tp_free*/ 0, /*tp_is_gc*/ - 0, /*tp_bases*/ - 0, /*tp_mro*/ - 0, /*tp_defined*/ - 0, /*tp_subclasses*/ - 0, /*tp_weaklist*/ }; /* --------------------------------------------------------------------- */ --- 139,142 ---- From jhylton@users.sourceforge.net Mon Oct 15 22:29:30 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Mon, 15 Oct 2001 14:29:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pickle.py,1.52,1.53 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv14137/Lib Modified Files: pickle.py Log Message: Use cStringIO when available. Remove test code. It's available in Lib/test/picklertester.py. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** pickle.py 2001/09/21 19:21:45 1.52 --- pickle.py 2001/10/15 21:29:28 1.53 *************** *** 959,963 **** # Shorthands ! from StringIO import StringIO def dump(object, file, bin = 0): --- 959,966 ---- # Shorthands ! try: ! from cStringIO import StringIO ! except ImportError: ! from StringIO import StringIO def dump(object, file, bin = 0): *************** *** 975,1011 **** file = StringIO(str) return Unpickler(file).load() - - - # The rest is used for testing only - - class C: - def __cmp__(self, other): - return cmp(self.__dict__, other.__dict__) - - def test(): - fn = 'out' - c = C() - c.foo = 1 - c.bar = 2 - x = [0, 1, 2, 3] - y = ('abc', 'abc', c, c) - x.append(y) - x.append(y) - x.append(5) - f = open(fn, 'w') - F = Pickler(f) - F.dump(x) - f.close() - f = open(fn, 'r') - U = Unpickler(f) - x2 = U.load() - print x - print x2 - print x == x2 - print map(id, x) - print map(id, x2) - print F.memo - print U.memo - - if __name__ == '__main__': - test() --- 978,979 ---- From jhylton@users.sourceforge.net Mon Oct 15 22:38:00 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Mon, 15 Oct 2001 14:38:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules cPickle.c,2.65,2.66 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv16510/Modules Modified Files: cPickle.c Log Message: Better fix for core dumps on recursive objects in fast mode. Raise ValueError when an object contains an arbitrarily nested reference to itself. (The previous fix just produced invalid pickles.) Solution is very much like Py_ReprEnter() and Py_ReprLeave(): fast_save_enter() and fast_save_leave() that tracks the fast_container limit and keeps a fast_memo of objects currently being pickled. The cost of the solution is moderately expensive for deeply nested structures, but it still seems to be faster than normal pickling, based on tests with deeply nested lists. Once FAST_LIMIT is exceeded, the new code is about twice as slow as fast-mode code that doesn't check for recursion. It's still twice as fast as the normal pickling code. In the absence of deeply nested structures, I couldn't measure a difference. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.65 retrieving revision 2.66 diff -C2 -d -r2.65 -r2.66 *** cPickle.c 2001/10/12 04:11:06 2.65 --- cPickle.c 2001/10/15 21:37:58 2.66 *************** *** 319,322 **** --- 319,323 ---- PyObject *dispatch_table; int fast_container; /* count nested container dumps */ + PyObject *fast_memo; } Picklerobject; *************** *** 888,891 **** --- 889,937 ---- static int + fast_save_enter(Picklerobject *self, PyObject *obj) + { + /* if fast_container < 0, we're doing an error exit. */ + if (++self->fast_container >= FAST_LIMIT) { + PyObject *key = NULL; + if (self->fast_memo == NULL) { + self->fast_memo = PyDict_New(); + if (self->fast_memo == NULL) { + self->fast_container = -1; + return 0; + } + } + key = PyLong_FromVoidPtr(obj); + if (key == NULL) + return 0; + if (PyDict_GetItem(self->fast_memo, key)) { + PyErr_Format(PyExc_ValueError, + "fast mode: can't pickle cyclic objects including object type %s at %p", + obj->ob_type->tp_name, obj); + self->fast_container = -1; + return 0; + } + if (PyDict_SetItem(self->fast_memo, key, Py_None) < 0) { + self->fast_container = -1; + return 0; + } + } + return 1; + } + + int + fast_save_leave(Picklerobject *self, PyObject *obj) + { + if (self->fast_container-- >= FAST_LIMIT) { + PyObject *key = PyLong_FromVoidPtr(obj); + if (key == NULL) + return 0; + if (PyDict_DelItem(self->fast_memo, key) < 0) { + return 0; + } + } + return 1; + } + + static int save_none(Picklerobject *self, PyObject *args) { static char none = NONE; *************** *** 1358,1370 **** save_list(Picklerobject *self, PyObject *args) { PyObject *element = 0; ! int s_len, len, i, using_appends, res = -1, unfast = 0; char s[3]; static char append = APPEND, appends = APPENDS; ! if (self->fast && self->fast_container++ > FAST_LIMIT) { ! self->fast = 0; ! unfast = 1; ! } if (self->bin) { --- 1404,1414 ---- save_list(Picklerobject *self, PyObject *args) { PyObject *element = 0; ! int s_len, len, i, using_appends, res = -1; char s[3]; static char append = APPEND, appends = APPENDS; ! if (self->fast && !fast_save_enter(self, args)) ! goto finally; if (self->bin) { *************** *** 1418,1426 **** finally: ! if (self->fast || unfast) { ! self->fast_container--; ! if (unfast && self->fast_container < FAST_LIMIT) ! self->fast = 1; ! } return res; --- 1462,1467 ---- finally: ! if (self->fast && !fast_save_leave(self, args)) ! res = -1; return res; *************** *** 1431,1443 **** save_dict(Picklerobject *self, PyObject *args) { PyObject *key = 0, *value = 0; ! int i, len, res = -1, using_setitems, unfast = 0; char s[3]; static char setitem = SETITEM, setitems = SETITEMS; ! if (self->fast && self->fast_container++ > FAST_LIMIT) { ! self->fast = 0; ! unfast = 1; ! } if (self->bin) { --- 1472,1482 ---- save_dict(Picklerobject *self, PyObject *args) { PyObject *key = 0, *value = 0; ! int i, len, res = -1, using_setitems; char s[3]; static char setitem = SETITEM, setitems = SETITEMS; ! if (self->fast && !fast_save_enter(self, args)) ! goto finally; if (self->bin) { *************** *** 1492,1501 **** finally: ! if (self->fast || unfast) { ! self->fast_container--; ! if (unfast && self->fast_container < FAST_LIMIT) ! self->fast = 1; ! } ! return res; --- 1531,1536 ---- finally: ! if (self->fast && !fast_save_leave(self, args)) ! res = -1; return res; *************** *** 1508,1519 **** *getinitargs_func = 0, *getstate_func = 0, *class_args = 0; char *module_str, *name_str; ! int module_size, name_size, res = -1, unfast = 0; static char inst = INST, obj = OBJ, build = BUILD; ! if (self->fast && self->fast_container++ > FAST_LIMIT) { ! self->fast = 0; ! unfast = 1; ! } if ((*self->write_func)(self, &MARKv, 1) < 0) --- 1543,1552 ---- *getinitargs_func = 0, *getstate_func = 0, *class_args = 0; char *module_str, *name_str; ! int module_size, name_size, res = -1; static char inst = INST, obj = OBJ, build = BUILD; ! if (self->fast && !fast_save_enter(self, args)) ! goto finally; if ((*self->write_func)(self, &MARKv, 1) < 0) *************** *** 1623,1631 **** finally: ! if (self->fast || unfast) { ! self->fast_container--; ! if (unfast && self->fast_container < FAST_LIMIT) ! self->fast = 1; ! } Py_XDECREF(module); --- 1656,1661 ---- finally: ! if (self->fast && !fast_save_leave(self, args)) ! res = -1; Py_XDECREF(module); *************** *** 1670,1674 **** if (mod == NULL) { /* Py_ErrClear(); ?? */ ! cPickle_ErrFormat(PicklingError, "Can't pickle %s: it's not found as %s.%s", "OSS", args, module, global_name); --- 1700,1704 ---- if (mod == NULL) { /* Py_ErrClear(); ?? */ ! cPickle_ErrFormat(PicklingError, "Can't pickle %s: it's not found as %s.%s", "OSS", args, module, global_name); *************** *** 2252,2255 **** --- 2282,2286 ---- self->fast = 0; self->fast_container = 0; + self->fast_memo = NULL; self->buf_size = 0; self->dispatch_table = NULL; *************** *** 2340,2343 **** --- 2371,2375 ---- Py_XDECREF(self->write); Py_XDECREF(self->memo); + Py_XDECREF(self->fast_memo); Py_XDECREF(self->arg); Py_XDECREF(self->file); From jhylton@users.sourceforge.net Mon Oct 15 22:38:58 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Mon, 15 Oct 2001 14:38:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_cpickle,1.3,NONE test_pickle,1.2,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv16822/Lib/test/output Removed Files: test_cpickle test_pickle Log Message: Covert pickle tests to use unittest. Extend tests to cover a few more cases. For cPickle, test several of the undocumented features. --- test_cpickle DELETED --- --- test_pickle DELETED --- From jhylton@users.sourceforge.net Mon Oct 15 22:38:58 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Mon, 15 Oct 2001 14:38:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test pickletester.py,1.8,1.9 test_cpickle.py,1.7,1.8 test_pickle.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv16822/Lib/test Modified Files: pickletester.py test_cpickle.py test_pickle.py Log Message: Covert pickle tests to use unittest. Extend tests to cover a few more cases. For cPickle, test several of the undocumented features. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** pickletester.py 2001/08/28 22:21:18 1.8 --- pickletester.py 2001/10/15 21:38:56 1.9 *************** *** 1,8 **** ! # test_pickle and test_cpickle both use this. ! from test_support import TestFailed, have_unicode - import sys ! # break into multiple strings to please font-lock-mode DATA = """(lp1 I0 --- 1,26 ---- ! import unittest from test_support import TestFailed, have_unicode ! class C: ! def __cmp__(self, other): ! return cmp(self.__dict__, other.__dict__) ! ! import __main__ ! __main__.C = C ! C.__module__ = "__main__" ! ! class myint(int): ! def __init__(self, x): ! self.str = str(x) ! ! class initarg(C): ! def __init__(self, a, b): ! self.a = a ! self.b = b ! ! def __getinitargs__(self): ! return self.a, self.b ! ! # break into multiple strings to avoid confusing font-lock-mode DATA = """(lp1 I0 *************** *** 58,73 **** 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh' + \ '\x06tq\nh\nK\x05e.' ! ! class C: ! def __cmp__(self, other): ! return cmp(self.__dict__, other.__dict__) ! ! import __main__ ! __main__.C = C ! C.__module__ = "__main__" ! ! # Call this with the module to be tested (pickle or cPickle). ! ! def dotest(pickle): c = C() c.foo = 1 --- 76,81 ---- 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh' + \ '\x06tq\nh\nK\x05e.' ! ! def create_data(): c = C() c.foo = 1 *************** *** 87,238 **** x.append(y) x.append(5) ! r = [] ! r.append(r) ! print "dumps()" ! s = pickle.dumps(x) ! print "loads()" ! x2 = pickle.loads(s) ! if x2 == x: ! print "ok" ! else: ! print "bad" ! print "loads() DATA" ! x2 = pickle.loads(DATA) ! if x2 == x: ! print "ok" ! else: ! print "bad" ! print "dumps() binary" ! s = pickle.dumps(x, 1) ! print "loads() binary" ! x2 = pickle.loads(s) ! if x2 == x: ! print "ok" ! else: ! print "bad" ! print "loads() BINDATA" ! x2 = pickle.loads(BINDATA) ! if x2 == x: ! print "ok" ! else: ! print "bad" ! print "dumps() RECURSIVE" ! s = pickle.dumps(r) ! x2 = pickle.loads(s) ! if x2 == r: ! print "ok" ! else: ! print "bad" ! # don't create cyclic garbage ! del x2[0] ! del r[0] ! # Test protection against closed files ! import tempfile, os ! fn = tempfile.mktemp() ! f = open(fn, "w") ! f.close() ! try: ! pickle.dump(123, f) ! except ValueError: ! pass ! else: ! print "dump to closed file should raise ValueError" ! f = open(fn, "r") ! f.close() ! try: ! pickle.load(f) ! except ValueError: ! pass ! else: ! print "load from closed file should raise ValueError" ! os.remove(fn) ! # Test specific bad cases ! for i in range(10): ! try: ! x = pickle.loads('garyp') ! except KeyError, y: ! # pickle ! del y ! except pickle.BadPickleGet, y: ! # cPickle ! del y ! else: ! print "unexpected success!" ! break ! # Test insecure strings ! insecure = ["abc", "2 + 2", # not quoted ! "'abc' + 'def'", # not a single quoted string ! "'abc", # quote is not closed ! "'abc\"", # open quote and close quote don't match ! "'abc' ?", # junk after close quote ! # some tests of the quoting rules ! "'abc\"\''", ! "'\\\\a\'\'\'\\\'\\\\\''", ! ] ! for s in insecure: ! buf = "S" + s + "\012p0\012." ! try: ! x = pickle.loads(buf) ! except ValueError: ! pass ! else: ! print "accepted insecure string: %s" % repr(buf) ! # Test some Unicode end cases if have_unicode: ! endcases = [unicode(''), unicode('<\\u>'), unicode('<\\\u1234>'), ! unicode('<\n>'), unicode('<\\>')] ! else: ! endcases = [] ! for u in endcases: ! try: ! u2 = pickle.loads(pickle.dumps(u)) ! except Exception, msg: ! print "Endcase exception: %s => %s(%s)" % \ ! (`u`, msg.__class__.__name__, str(msg)) ! else: ! if u2 != u: ! print "Endcase failure: %s => %s" % (`u`, `u2`) ! # Test the full range of Python ints. ! n = sys.maxint ! while n: ! for expected in (-n, n): ! for binary_mode in (0, 1): ! s = pickle.dumps(expected, binary_mode) ! got = pickle.loads(s) ! if expected != got: ! raise TestFailed("for %s-mode pickle of %d, pickle " ! "string is %s, loaded back as %s" % ( ! binary_mode and "binary" or "text", ! expected, ! repr(s), ! got)) ! n = n >> 1 ! # Fake a pickle from a sizeof(long)==8 box. ! maxint64 = (1L << 63) - 1 ! data = 'I' + str(maxint64) + '\n.' ! got = pickle.loads(data) ! if maxint64 != got: ! raise TestFailed("maxint64 test failed %r %r" % (maxint64, got)) ! # Try too with a bogus literal. ! data = 'I' + str(maxint64) + 'JUNK\n.' ! try: ! got = pickle.loads(data) ! except ValueError: pass ! else: ! raise TestFailed("should have raised error on bogus INT literal") --- 95,252 ---- x.append(y) x.append(5) ! return x ! class AbstractPickleTests(unittest.TestCase): ! _testdata = create_data() ! def setUp(self): ! # subclass must define self.dumps, self.loads, self.error ! pass ! def test_misc(self): ! # test various datatypes not tested by testdata ! x = myint(4) ! s = self.dumps(x) ! y = self.loads(s) ! self.assertEqual(x, y) ! x = (1, ()) ! s = self.dumps(x) ! y = self.loads(s) ! self.assertEqual(x, y) ! x = initarg(1, x) ! s = self.dumps(x) ! y = self.loads(s) ! self.assertEqual(x, y) ! # XXX test __reduce__ protocol? ! def test_identity(self): ! s = self.dumps(self._testdata) ! x = self.loads(s) ! self.assertEqual(x, self._testdata) ! def test_constant(self): ! x = self.loads(DATA) ! self.assertEqual(x, self._testdata) ! x = self.loads(BINDATA) ! self.assertEqual(x, self._testdata) ! def test_binary(self): ! s = self.dumps(self._testdata, 1) ! x = self.loads(s) ! self.assertEqual(x, self._testdata) ! def test_recursive_list(self): ! l = [] ! l.append(l) ! s = self.dumps(l) ! x = self.loads(s) ! self.assertEqual(x, l) ! self.assertEqual(x, x[0]) ! self.assertEqual(id(x), id(x[0])) ! def test_recursive_dict(self): ! d = {} ! d[1] = d ! s = self.dumps(d) ! x = self.loads(s) ! self.assertEqual(x, d) ! self.assertEqual(x[1], x) ! self.assertEqual(id(x[1]), id(x)) ! def test_recursive_inst(self): ! i = C() ! i.attr = i ! s = self.dumps(i) ! x = self.loads(s) ! self.assertEqual(x, i) ! self.assertEqual(x.attr, x) ! self.assertEqual(id(x.attr), id(x)) ! ! def test_recursive_multi(self): ! l = [] ! d = {1:l} ! i = C() ! i.attr = d ! l.append(i) ! s = self.dumps(l) ! x = self.loads(s) ! self.assertEqual(x, l) ! self.assertEqual(x[0], i) ! self.assertEqual(x[0].attr, d) ! self.assertEqual(x[0].attr[1], x) ! self.assertEqual(x[0].attr[1][0], i) ! self.assertEqual(x[0].attr[1][0].attr, d) ! ! def test_garyp(self): ! self.assertRaises(self.error, self.loads, 'garyp') ! ! def test_insecure_strings(self): ! insecure = ["abc", "2 + 2", # not quoted ! "'abc' + 'def'", # not a single quoted string ! "'abc", # quote is not closed ! "'abc\"", # open quote and close quote don't match ! "'abc' ?", # junk after close quote ! # some tests of the quoting rules ! "'abc\"\''", ! "'\\\\a\'\'\'\\\'\\\\\''", ! ] ! for s in insecure: ! buf = "S" + s + "\012p0\012." ! self.assertRaises(ValueError, self.loads, buf) ! if have_unicode: ! def test_unicode(self): ! endcases = [unicode(''), unicode('<\\u>'), unicode('<\\\u1234>'), ! unicode('<\n>'), unicode('<\\>')] ! for u in endcases: ! p = self.dumps(u) ! u2 = self.loads(p) ! self.assertEqual(u2, u) ! def test_ints(self): ! import sys ! n = sys.maxint ! while n: ! for expected in (-n, n): ! s = self.dumps(expected) ! n2 = self.loads(s) ! self.assertEqual(expected, n2) ! n = n >> 1 ! def test_maxint64(self): ! maxint64 = (1L << 63) - 1 ! data = 'I' + str(maxint64) + '\n.' ! got = self.loads(data) ! self.assertEqual(got, maxint64) ! ! # Try too with a bogus literal. ! data = 'I' + str(maxint64) + 'JUNK\n.' ! self.assertRaises(ValueError, self.loads, data) ! ! def test_reduce(self): pass ! ! def test_getinitargs(self): ! pass ! ! class AbstractPickleModuleTests(unittest.TestCase): ! ! def test_dump_closed_file(self): ! import tempfile, os ! fn = tempfile.mktemp() ! f = open(fn, "w") ! f.close() ! self.assertRaises(ValueError, self.module.dump, 123, f) ! os.remove(fn) ! ! def test_load_closed_file(self): ! import tempfile, os ! fn = tempfile.mktemp() ! f = open(fn, "w") ! f.close() ! self.assertRaises(ValueError, self.module.dump, 123, f) ! os.remove(fn) Index: test_cpickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_cpickle.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_cpickle.py 2001/01/22 22:05:20 1.7 --- test_cpickle.py 2001/10/15 21:38:56 1.8 *************** *** 1,3 **** import cPickle ! import pickletester ! pickletester.dotest(cPickle) --- 1,86 ---- import cPickle ! from cStringIO import StringIO ! from pickletester import AbstractPickleTests, AbstractPickleModuleTests ! from test_support import run_unittest ! ! class cPickleTests(AbstractPickleTests, AbstractPickleModuleTests): ! ! def setUp(self): ! self.dumps = cPickle.dumps ! self.loads = cPickle.loads ! ! error = cPickle.BadPickleGet ! module = cPickle ! ! class cPicklePicklerTests(AbstractPickleTests): ! ! def dumps(self, arg, bin=0): ! f = StringIO() ! p = cPickle.Pickler(f, bin) ! p.dump(arg) ! f.seek(0) ! return f.read() ! ! def loads(self, buf): ! f = StringIO(buf) ! p = cPickle.Unpickler(f) ! return p.load() ! ! error = cPickle.BadPickleGet ! ! class cPickleListPicklerTests(AbstractPickleTests): ! ! def dumps(self, arg, bin=0): ! p = cPickle.Pickler(bin) ! p.dump(arg) ! return p.getvalue() ! ! def loads(self, *args): ! f = StringIO(args[0]) ! p = cPickle.Unpickler(f) ! return p.load() ! ! error = cPickle.BadPickleGet ! ! class cPickleFastPicklerTests(AbstractPickleTests): ! ! def dumps(self, arg, bin=0): ! f = StringIO() ! p = cPickle.Pickler(f, bin) ! p.fast = 1 ! p.dump(arg) ! f.seek(0) ! return f.read() ! ! def loads(self, *args): ! f = StringIO(args[0]) ! p = cPickle.Unpickler(f) ! return p.load() ! ! error = cPickle.BadPickleGet ! ! def test_recursive_list(self): ! self.assertRaises(ValueError, ! AbstractPickleTests.test_recursive_list, ! self) ! ! def test_recursive_inst(self): ! self.assertRaises(ValueError, ! AbstractPickleTests.test_recursive_inst, ! self) ! ! def test_recursive_dict(self): ! self.assertRaises(ValueError, ! AbstractPickleTests.test_recursive_dict, ! self) ! ! def test_recursive_multi(self): ! self.assertRaises(ValueError, ! AbstractPickleTests.test_recursive_multi, ! self) ! ! if __name__ == "__main__": ! run_unittest(cPickleTests) ! run_unittest(cPicklePicklerTests) ! run_unittest(cPickleListPicklerTests) ! run_unittest(cPickleFastPicklerTests) Index: test_pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pickle.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_pickle.py 2001/01/22 22:05:20 1.6 --- test_pickle.py 2001/10/15 21:38:56 1.7 *************** *** 1,3 **** import pickle ! import pickletester ! pickletester.dotest(pickle) --- 1,33 ---- import pickle ! from cStringIO import StringIO ! from pickletester import AbstractPickleTests, AbstractPickleModuleTests ! from test_support import run_unittest ! ! class PickleTests(AbstractPickleTests, AbstractPickleModuleTests): ! ! def setUp(self): ! self.dumps = pickle.dumps ! self.loads = pickle.loads ! ! module = pickle ! error = KeyError ! ! class PicklerTests(AbstractPickleTests): ! ! error = KeyError ! ! def dumps(self, arg, bin=0): ! f = StringIO() ! p = pickle.Pickler(f, bin) ! p.dump(arg) ! f.seek(0) ! return f.read() ! ! def loads(self, buf): ! f = StringIO(buf) ! u = pickle.Unpickler(f) ! return u.load() ! ! if __name__ == "__main__": ! run_unittest(PickleTests) ! run_unittest(PicklerTests) From fdrake@users.sourceforge.net Mon Oct 15 23:05:34 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 15 Oct 2001 15:05:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/hotshot log.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/hotshot In directory usw-pr-cvs1:/tmp/cvs-serv25918/Lib/hotshot Modified Files: log.py Log Message: Avoid deep recursion when reading the header of the log file. Add support for extracting function names from the log file, keeping the extract-names-from-sources support as a fallback. Index: log.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/hotshot/log.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** log.py 2001/10/13 02:55:40 1.2 --- log.py 2001/10/15 22:05:32 1.3 *************** *** 10,13 **** --- 10,14 ---- WHAT_LINENO, \ WHAT_DEFINE_FILE, \ + WHAT_DEFINE_FUNC, \ WHAT_ADD_INFO *************** *** 45,77 **** def next(self, index=0): ! try: ! what, tdelta, fileno, lineno = self._nextitem() ! except TypeError: ! # logreader().next() returns None at the end ! self._reader.close() ! raise StopIteration() ! if what == WHAT_DEFINE_FILE: ! self._filemap[fileno] = tdelta ! return self.next() ! if what == WHAT_ADD_INFO: ! key = tdelta.lower() try: ! L = self._info[key] ! except KeyError: ! L = [] ! self._info[key] = L ! L.append(lineno) ! if key == "current-directory": ! self.cwd = lineno ! return self.next() ! if what == WHAT_ENTER: ! t = self._decode_location(fileno, lineno) ! filename, funcname = t ! self._stack.append((filename, funcname, lineno)) ! elif what == WHAT_EXIT: ! filename, funcname, lineno = self._stack.pop() ! else: ! filename, funcname, firstlineno = self._stack[-1] ! return what, (filename, lineno, funcname), tdelta if sys.version < "2.2": --- 46,83 ---- def next(self, index=0): ! while 1: try: ! what, tdelta, fileno, lineno = self._nextitem() ! except TypeError: ! # logreader().next() returns None at the end ! self._reader.close() ! raise StopIteration() ! if what == WHAT_DEFINE_FILE: ! self._filemap[fileno] = tdelta ! continue ! if what == WHAT_DEFINE_FUNC: ! filename = self._filemap[fileno] ! self._funcmap[(fileno, lineno)] = (filename, tdelta) ! continue ! if what == WHAT_ADD_INFO: ! key = tdelta.lower() ! try: ! L = self._info[key] ! except KeyError: ! L = [] ! self._info[key] = L ! L.append(lineno) ! if key == "current-directory": ! self.cwd = lineno ! continue ! if what == WHAT_ENTER: ! t = self._decode_location(fileno, lineno) ! filename, funcname = t ! self._stack.append((filename, funcname, lineno)) ! elif what == WHAT_EXIT: ! filename, funcname, lineno = self._stack.pop() ! else: ! filename, funcname, firstlineno = self._stack[-1] ! return what, (filename, lineno, funcname), tdelta if sys.version < "2.2": *************** *** 91,94 **** --- 97,105 ---- return self._funcmap[(fileno, lineno)] except KeyError: + # + # This should only be needed when the log file does not + # contain all the DEFINE_FUNC records needed to allow the + # function name to be retrieved from the log file. + # if self._loadfile(fileno): filename = funcname = None From fdrake@users.sourceforge.net Mon Oct 15 23:11:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 15 Oct 2001 15:11:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _hotshot.c,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv27908/Modules Modified Files: _hotshot.c Log Message: Removed useless code to count the number of calls into the profiler. Added support for saving the names of the functions observed into the profile log. Added support for using the profiler to measure coverage without collecting timing information (which is the slow part). Coverage logs can also be substantially smaller than profiling logs where per-line information is being collected. Updated comments on the log format; corrected record type values in some of the record descriptions. Index: _hotshot.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_hotshot.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** _hotshot.c 2001/10/13 07:37:52 1.5 --- _hotshot.c 2001/10/15 22:11:02 1.6 *************** *** 66,73 **** int lineevents; int linetimings; /* size_t filled; */ int active; int next_fileno; - long callcount; hs_time prev_timeofday; } ProfilerObject; --- 66,73 ---- int lineevents; int linetimings; + int frametimings; /* size_t filled; */ int active; int next_fileno; hs_time prev_timeofday; } ProfilerObject; *************** *** 79,82 **** --- 79,83 ---- int index; int linetimings; + int frametimings; unsigned char buffer[BUFFERSIZE]; } LogReaderObject; *************** *** 155,158 **** --- 156,161 ---- * 0x23 DEFINE_FILE define an int->filename mapping * 0x33 LINE_TIMES indicates if LINENO events have tdeltas + * 0x43 DEFINE_FUNC define a (fileno,lineno)->funcname mapping + * 0x53 FRAME_TIMES indicates if ENTER/EXIT events have tdeltas * * Packed Integers *************** *** 175,184 **** * * MPI(2,type) fileno -- type is 0x00 - * PI tdelta * PI lineno * * EXIT records * ! * MPI(2,type) tdelta -- type is 0x01 * * LINENO records --- 178,188 ---- * * MPI(2,type) fileno -- type is 0x00 * PI lineno + * PI tdelta -- iff frame times are enabled * * EXIT records * ! * MPI(2,type) tdelta -- type is 0x01; tdelta will be 0 ! * if frame times are disabled * * LINENO records *************** *** 189,193 **** * ADD_INFO records * ! * BYTE type -- always 0x03 * PI len1 -- length of first string * BYTE string1[len1] -- len1 bytes of string data --- 193,197 ---- * ADD_INFO records * ! * BYTE type -- always 0x13 * PI len1 -- length of first string * BYTE string1[len1] -- len1 bytes of string data *************** *** 197,209 **** * DEFINE_FILE records * ! * BYTE type -- always 0x13 * PI fileno * PI len -- length of filename * BYTE filename[len] -- len bytes of string data * * LINE_TIMES records ! * BYTE type -- always 0x23 * BYTE have_tdelta -- 0 if LINENO does *not* have * timing information */ --- 201,238 ---- * DEFINE_FILE records * ! * BYTE type -- always 0x23 * PI fileno * PI len -- length of filename * BYTE filename[len] -- len bytes of string data * + * DEFINE_FUNC records + * + * BYTE type -- always 0x43 + * PI fileno + * PI lineno + * PI len -- length of funcname + * BYTE funcname[len] -- len bytes of string data + * * LINE_TIMES records ! * ! * This record can be used only before the start of ENTER/EXIT/LINENO ! * records. If have_tdelta is true, LINENO records will include the ! * tdelta field, otherwise it will be omitted. If this record is not ! * given, LINENO records will not contain the tdelta field. ! * ! * BYTE type -- always 0x33 * BYTE have_tdelta -- 0 if LINENO does *not* have * timing information + * FRAME_TIMES records + * + * This record can be used only before the start of ENTER/EXIT/LINENO + * records. If have_tdelta is true, ENTER and EXIT records will + * include the tdelta field, otherwise it will be omitted. If this + * record is not given, ENTER and EXIT records will contain the tdelta + * field. + * + * BYTE type -- always 0x53 + * BYTE have_tdelta -- 0 if ENTER/EXIT do *not* have + * timing information */ *************** *** 215,218 **** --- 244,249 ---- #define WHAT_DEFINE_FILE 0x23 #define WHAT_LINE_TIMES 0x33 + #define WHAT_DEFINE_FUNC 0x43 + #define WHAT_FRAME_TIMES 0x53 #define ERR_NONE 0 *************** *** 339,345 **** err = unpack_packed_int(self, &fileno, 2); if (!err) { ! err = unpack_packed_int(self, &tdelta, 0); ! if (!err) ! err = unpack_packed_int(self, &lineno, 0); } break; --- 370,376 ---- err = unpack_packed_int(self, &fileno, 2); if (!err) { ! err = unpack_packed_int(self, &lineno, 0); ! if (self->frametimings && !err) ! err = unpack_packed_int(self, &tdelta, 0); } break; *************** *** 372,375 **** --- 403,414 ---- } break; + case WHAT_DEFINE_FUNC: + err = unpack_packed_int(self, &fileno, 0); + if (!err) { + err = unpack_packed_int(self, &lineno, 0); + if (!err) + err = unpack_string(self, &s1); + } + break; case WHAT_LINE_TIMES: if (self->index >= self->filled) *************** *** 380,383 **** --- 419,430 ---- goto restart; } + case WHAT_FRAME_TIMES: + if (self->index >= self->filled) + err = ERR_EOF; + else { + self->frametimings = self->buffer[self->index] ? 1 : 0; + self->index++; + goto restart; + } default: ; *************** *** 400,411 **** PyTuple_SET_ITEM(result, 0, PyInt_FromLong(what)); PyTuple_SET_ITEM(result, 2, PyInt_FromLong(fileno)); ! if (s1 == NULL) { PyTuple_SET_ITEM(result, 1, PyInt_FromLong(tdelta)); ! PyTuple_SET_ITEM(result, 3, PyInt_FromLong(lineno)); ! } ! else { PyTuple_SET_ITEM(result, 1, s1); PyTuple_SET_ITEM(result, 3, s2); - } } /* The only other case is err == ERR_EXCEPTION, in which case the --- 447,458 ---- PyTuple_SET_ITEM(result, 0, PyInt_FromLong(what)); PyTuple_SET_ITEM(result, 2, PyInt_FromLong(fileno)); ! if (s1 == NULL) PyTuple_SET_ITEM(result, 1, PyInt_FromLong(tdelta)); ! else PyTuple_SET_ITEM(result, 1, s1); + if (s2 == NULL) + PyTuple_SET_ITEM(result, 3, PyInt_FromLong(lineno)); + else PyTuple_SET_ITEM(result, 3, s2); } /* The only other case is err == ERR_EXCEPTION, in which case the *************** *** 551,561 **** static void ! pack_string(ProfilerObject *self, const char *s) { ! int len = strlen(s); ! ! pack_packed_int(self, len); ! if (len + self->index >= BUFFERSIZE) (void) flush_data(self); memcpy(self->buffer + self->index, s, len); self->index += len; --- 598,606 ---- static void ! pack_string(ProfilerObject *self, const char *s, int len) { ! if (len + PISIZE + self->index >= BUFFERSIZE) (void) flush_data(self); + pack_packed_int(self, len); memcpy(self->buffer + self->index, s, len); self->index += len; *************** *** 572,577 **** self->buffer[self->index] = WHAT_ADD_INFO; self->index++; ! pack_string(self, s1); ! pack_string(self, s2); } --- 617,622 ---- self->buffer[self->index] = WHAT_ADD_INFO; self->index++; ! pack_string(self, s1, len1); ! pack_string(self, s2, len2); } *************** *** 586,590 **** self->index++; pack_packed_int(self, fileno); ! pack_string(self, filename); } --- 631,650 ---- self->index++; pack_packed_int(self, fileno); ! pack_string(self, filename, len); ! } ! ! static void ! pack_define_func(ProfilerObject *self, int fileno, int lineno, ! const char *funcname) ! { ! int len = strlen(funcname); ! ! if (len + PISIZE*3 + 1 + self->index >= BUFFERSIZE) ! (void) flush_data(self); ! self->buffer[self->index] = WHAT_DEFINE_FUNC; ! self->index++; ! pack_packed_int(self, fileno); ! pack_packed_int(self, lineno); ! pack_string(self, funcname, len); } *************** *** 599,602 **** --- 659,672 ---- } + static void + pack_frame_times(ProfilerObject *self) + { + if (2 + self->index >= BUFFERSIZE) + (void) flush_data(self); + self->buffer[self->index] = WHAT_FRAME_TIMES; + self->buffer[self->index + 1] = self->frametimings ? 1 : 0; + self->index += 2; + } + static inline void pack_enter(ProfilerObject *self, int fileno, int tdelta, int lineno) *************** *** 605,610 **** (void) flush_data(self); pack_modified_packed_int(self, fileno, 2, WHAT_ENTER); - pack_packed_int(self, tdelta); pack_packed_int(self, lineno); } --- 675,681 ---- (void) flush_data(self); pack_modified_packed_int(self, fileno, 2, WHAT_ENTER); pack_packed_int(self, lineno); + if (self->frametimings) + pack_packed_int(self, tdelta); } *************** *** 614,618 **** if (MPISIZE + self->index >= BUFFERSIZE) (void) flush_data(self); ! pack_modified_packed_int(self, tdelta, 2, WHAT_EXIT); } --- 685,694 ---- if (MPISIZE + self->index >= BUFFERSIZE) (void) flush_data(self); ! if (self->frametimings) ! pack_modified_packed_int(self, tdelta, 2, WHAT_EXIT); ! else { ! self->buffer[self->index] = WHAT_EXIT; ! self->index++; ! } } *************** *** 637,662 **** get_fileno(ProfilerObject *self, PyCodeObject *fcode) { ! PyObject *idobj; int fileno; ! idobj = PyDict_GetItem(self->filemap, fcode->co_filename); ! if (idobj == NULL) { /* first sighting of this file */ fileno = self->next_fileno; ! idobj = PyInt_FromLong(fileno); ! if (idobj == NULL) { return -1; } ! if (PyDict_SetItem(self->filemap, fcode->co_filename, idobj)) { ! Py_DECREF(idobj); return -1; } self->next_fileno++; ! Py_DECREF(idobj); pack_define_file(self, fileno, PyString_AS_STRING(fcode->co_filename)); } else { /* already know this ID */ ! fileno = PyInt_AS_LONG(idobj); } return fileno; --- 713,761 ---- get_fileno(ProfilerObject *self, PyCodeObject *fcode) { ! /* This is only used for ENTER events. */ ! ! PyObject *obj; ! PyObject *dict; int fileno; ! obj = PyDict_GetItem(self->filemap, fcode->co_filename); ! if (obj == NULL) { /* first sighting of this file */ + dict = PyDict_New(); + if (dict == NULL) { + return -1; + } fileno = self->next_fileno; ! obj = Py_BuildValue("iN", fileno, dict); ! if (obj == NULL) { return -1; } ! if (PyDict_SetItem(self->filemap, fcode->co_filename, obj)) { ! Py_DECREF(obj); return -1; } self->next_fileno++; ! Py_DECREF(obj); pack_define_file(self, fileno, PyString_AS_STRING(fcode->co_filename)); } else { /* already know this ID */ ! fileno = PyInt_AS_LONG(PyTuple_GET_ITEM(obj, 0)); ! dict = PyTuple_GET_ITEM(obj, 1); ! } ! /* make sure we save a function name for this (fileno, lineno) */ ! obj = PyInt_FromLong(fcode->co_firstlineno); ! if (obj == NULL) { ! /* We just won't have it saved; too bad. */ ! PyErr_Clear(); ! } ! else { ! PyObject *name = PyDict_GetItem(dict, obj); ! if (name == NULL) { ! pack_define_func(self, fileno, fcode->co_firstlineno, ! PyString_AS_STRING(fcode->co_name)); ! if (PyDict_SetItem(dict, obj, fcode->co_name)) ! return -1; ! } } return fileno; *************** *** 696,703 **** PyObject *arg) { ! int tdelta = get_tdelta(self); int fileno; ! self->callcount++; switch (what) { case PyTrace_CALL: --- 795,803 ---- PyObject *arg) { ! int tdelta = -1; int fileno; ! if (self->frametimings) ! tdelta = get_tdelta(self); switch (what) { case PyTrace_CALL: *************** *** 727,731 **** int fileno; - self->callcount++; switch (what) { case PyTrace_CALL: --- 827,830 ---- *************** *** 733,737 **** if (fileno < 0) return -1; ! pack_enter(self, fileno, get_tdelta(self), frame->f_code->co_firstlineno); break; --- 832,836 ---- if (fileno < 0) return -1; ! pack_enter(self, fileno, self->frametimings ? get_tdelta(self) : -1, frame->f_code->co_firstlineno); break; *************** *** 1015,1022 **** */ static struct memberlist profiler_members[] = { ! {"callcount", T_LONG, offsetof(ProfilerObject, callcount), READONLY}, ! {"closed", T_INT, -1, READONLY}, ! {"lineevents", T_LONG, offsetof(ProfilerObject, lineevents), READONLY}, ! {"linetimings", T_LONG, offsetof(ProfilerObject, linetimings), READONLY}, {NULL} }; --- 1114,1121 ---- */ static struct memberlist profiler_members[] = { ! {"closed", T_INT, -1, READONLY}, ! {"frametimings", T_LONG, offsetof(ProfilerObject, linetimings), READONLY}, ! {"lineevents", T_LONG, offsetof(ProfilerObject, lineevents), READONLY}, ! {"linetimings", T_LONG, offsetof(ProfilerObject, linetimings), READONLY}, {NULL} }; *************** *** 1046,1061 **** "Methods:\n" "\n" ! "close(): Stop the profiler and close the log files.\n" ! "runcall(): Run a single function call with profiling enabled.\n" ! "runcode(): Execute a code object with profiling enabled.\n" ! "start(): Install the profiler and return.\n" ! "stop(): Remove the profiler.\n" "\n" "Attributes (read-only):\n" "\n" ! "callcount: The number of low-level calls to the profiler.\n" ! "closed: True if the profiler has already been closed.\n" ! "lineevents: True if SET_LINENO events are reported to the profiler.\n" ! "linetimings: True if SET_LINENO events collect timing information."; static PyTypeObject ProfilerType = { --- 1145,1160 ---- "Methods:\n" "\n" ! "close(): Stop the profiler and close the log files.\n" ! "runcall(): Run a single function call with profiling enabled.\n" ! "runcode(): Execute a code object with profiling enabled.\n" ! "start(): Install the profiler and return.\n" ! "stop(): Remove the profiler.\n" "\n" "Attributes (read-only):\n" "\n" ! "closed: True if the profiler has already been closed.\n" ! "frametimings: True if ENTER/EXIT events collect timing information.\n" ! "lineevents: True if SET_LINENO events are reported to the profiler.\n" ! "linetimings: True if SET_LINENO events collect timing information."; static PyTypeObject ProfilerType = { *************** *** 1161,1164 **** --- 1260,1264 ---- self->filled = 0; self->index = 0; + self->frametimings = 1; self->linetimings = 0; self->logfp = fopen(filename, "rb"); *************** *** 1235,1238 **** --- 1335,1339 ---- pack_add_info(self, "Observed-Interval-gettimeofday", cwdbuffer); #endif + pack_frame_times(self); pack_line_times(self); *************** *** 1269,1273 **** if (self == NULL) return NULL; ! self->callcount = 0; self->lineevents = lineevents ? 1 : 0; self->linetimings = (lineevents && linetimings) ? 1 : 0; --- 1370,1374 ---- if (self == NULL) return NULL; ! self->frametimings = 1; self->lineevents = lineevents ? 1 : 0; self->linetimings = (lineevents && linetimings) ? 1 : 0; *************** *** 1305,1308 **** --- 1406,1432 ---- } + static char coverage__doc__[] = "\ + coverage(logfilename) -> profiler\n\ + Returns a profiler that doesn't collect any timing information, which is\n\ + useful in building a coverage analysis tool."; + + static PyObject * + hotshot_coverage(PyObject *unused, PyObject *args) + { + char *logfilename; + PyObject *result = NULL; + + if (PyArg_ParseTuple(args, "s:coverage", &logfilename)) { + result = hotshot_profiler(unused, args); + if (result != NULL) { + ProfilerObject *self = (ProfilerObject *) result; + self->frametimings = 0; + self->linetimings = 0; + self->lineevents = 1; + } + } + return result; + } + static char resolution__doc__[] = #ifdef MS_WIN32 *************** *** 1339,1342 **** --- 1463,1467 ---- static PyMethodDef functions[] = { + {"coverage", hotshot_coverage, METH_VARARGS, coverage__doc__}, {"profiler", hotshot_profiler, METH_VARARGS, profiler__doc__}, {"logreader", hotshot_logreader, METH_VARARGS, logreader__doc__}, *************** *** 1379,1382 **** --- 1504,1508 ---- PyModule_AddIntConstant(module, "WHAT_ADD_INFO", WHAT_ADD_INFO); PyModule_AddIntConstant(module, "WHAT_DEFINE_FILE", WHAT_DEFINE_FILE); + PyModule_AddIntConstant(module, "WHAT_DEFINE_FUNC", WHAT_DEFINE_FUNC); PyModule_AddIntConstant(module, "WHAT_LINE_TIMES", WHAT_LINE_TIMES); } From fdrake@users.sourceforge.net Mon Oct 15 23:14:31 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 15 Oct 2001 15:14:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/hotshot __init__.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/hotshot In directory usw-pr-cvs1:/tmp/cvs-serv28627 Modified Files: __init__.py Log Message: runcall(): Expose the return value of the profiled function; this allows changing an application to collect profile data on one part of the app while still making use of the profiled component, without relying on side effects. Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/hotshot/__init__.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** __init__.py 2001/10/12 20:56:29 1.1 --- __init__.py 2001/10/15 22:14:29 1.2 *************** *** 36,38 **** def runcall(self, func, *args, **kw): ! self._prof.runcall(func, args, kw) --- 36,38 ---- def runcall(self, func, *args, **kw): ! return self._prof.runcall(func, args, kw) From fdrake@users.sourceforge.net Mon Oct 15 23:18:55 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 15 Oct 2001 15:18:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/hotshot stats.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/hotshot In directory usw-pr-cvs1:/tmp/cvs-serv29495 Added Files: stats.py Log Message: pstats-compatible analysis module. hotshot.stats.load(logfilename) returns a pstats.Stats instance, which is about as compatible as it gets. --- NEW FILE: stats.py --- """Statistics analyzer for HotShot.""" import profile import pstats import hotshot.log from hotshot.log import ENTER, EXIT def load(filename): return StatsLoader(filename).load() class StatsLoader: def __init__(self, logfn): self._logfn = logfn self._code = {} self._stack = [] self.pop_frame = self._stack.pop def load(self): # The timer selected by the profiler should never be used, so make # sure it doesn't work: p = Profile() p.get_time = _brokentimer log = hotshot.log.LogReader(self._logfn) taccum = 0 for event in log: what, (filename, lineno, funcname), tdelta = event if tdelta > 0: taccum += tdelta # We multiply taccum to convert from the microseconds we # have to the seconds that the profile/pstats module work # with; this allows the numbers to have some basis in # reality (ignoring calibration issues for now). if what == ENTER: frame = self.new_frame(filename, lineno, funcname) p.trace_dispatch_call(frame, taccum * .000001) taccum = 0 elif what == EXIT: frame = self.pop_frame() p.trace_dispatch_return(frame, taccum * .000001) taccum = 0 # no further work for line events assert not self._stack return pstats.Stats(p) def new_frame(self, *args): # args must be filename, firstlineno, funcname # our code objects are cached since we don't need to create # new ones every time try: code = self._code[args] except KeyError: code = FakeCode(*args) self._code[args] = code # frame objects are create fresh, since the back pointer will # vary considerably if self._stack: back = self._stack[-1] else: back = None frame = FakeFrame(code, back) self._stack.append(frame) return frame class Profile(profile.Profile): def simulate_cmd_complete(self): pass class FakeCode: def __init__(self, filename, firstlineno, funcname): self.co_filename = filename self.co_firstlineno = firstlineno self.co_name = self.__name__ = funcname class FakeFrame: def __init__(self, code, back): self.f_back = back self.f_code = code def _brokentimer(): raise RuntimeError, "this timer should not be called" From gvanrossum@users.sourceforge.net Mon Oct 15 23:03:34 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 15:03:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.276,1.277 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv23185/Misc Modified Files: NEWS Log Message: Get rid of __defined__ and tp_defined -- there's no need to distinguish __dict__ and __defined__ any more. In the C structure, tp_cache takes its place -- but this hasn't been implemented yet. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.276 retrieving revision 1.277 diff -C2 -d -r1.276 -r1.277 *** NEWS 2001/10/15 15:53:58 1.276 --- NEWS 2001/10/15 22:03:32 1.277 *************** *** 5,17 **** Type/class unification and new-style classes ! - New-style classes are now dynamic by default. Previous, they were ! static (meaning class attributes could not be assigned to) and ! dynamic classes had to be requested by adding __dynamic__ = 1 to the ! body of the class or to the module. Static classes are faster than ! dynamic classes, but dynamic classes are now at most 50% slower than ! static classes; previously, they could be up to 10x slower. (This ! was accomplished by making dynamic classes faster, not by making ! static classes slower. :-) Note that according to one benchmark, ! static classes are about the same speed as classic classes. - C.__doc__ now works as expected for new-style classes (in 2.2a4 it --- 5,16 ---- Type/class unification and new-style classes ! - New-style classes are now always dynamic (except for built-in and ! extension types). There was no longer a performance penalty, and I ! no longer see another reason to keep this baggage around. One relic ! remains: the __dict__ or a new-style class is a read-only proxy. ! You must set the class's attribute to modify. As a consequence, the ! __defined__ attribute of new-style types no longer exists, for lack ! of need: there is once again only one __dict__ (although in the ! future a __cache__ may be resurrected in its place). - C.__doc__ now works as expected for new-style classes (in 2.2a4 it From gvanrossum@users.sourceforge.net Mon Oct 15 23:03:34 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 15:03:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib inspect.py,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv23185/Lib Modified Files: inspect.py Log Message: Get rid of __defined__ and tp_defined -- there's no need to distinguish __dict__ and __defined__ any more. In the C structure, tp_cache takes its place -- but this hasn't been implemented yet. Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** inspect.py 2001/09/23 02:00:29 1.25 --- inspect.py 2001/10/15 22:03:31 1.26 *************** *** 201,222 **** # Figure out where it was defined. - # A complication: static classes in 2.2 copy dict entries from - # bases into derived classes, so it's not enough just to look for - # "the first" class with the name in its dict. OTOH: - # 1. Some-- but not all --methods in 2.2 come with an __objclass__ - # attr that answers the question directly. - # 2. Some-- but not all --classes in 2.2 have a __defined__ dict - # saying which names were defined by the class. homecls = getattr(obj, "__objclass__", None) if homecls is None: ! # Try __defined__. ! for base in mro: ! if hasattr(base, "__defined__"): ! if name in base.__defined__: ! homecls = base ! break ! if homecls is None: ! # Last chance (and first chance for classic classes): search ! # the dicts. for base in mro: if name in base.__dict__: --- 201,207 ---- # Figure out where it was defined. homecls = getattr(obj, "__objclass__", None) if homecls is None: ! # search the dicts. for base in mro: if name in base.__dict__: From gvanrossum@users.sourceforge.net Mon Oct 15 23:03:34 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 15:03:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.104,2.105 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv23185/Objects Modified Files: typeobject.c Log Message: Get rid of __defined__ and tp_defined -- there's no need to distinguish __dict__ and __defined__ any more. In the C structure, tp_cache takes its place -- but this hasn't been implemented yet. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.104 retrieving revision 2.105 diff -C2 -d -r2.104 -r2.105 *** typeobject.c 2001/10/15 21:05:10 2.104 --- typeobject.c 2001/10/15 22:03:32 2.105 *************** *** 45,49 **** if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) return PyString_FromString("__builtin__"); ! mod = PyDict_GetItemString(type->tp_defined, "__module__"); if (mod != NULL && PyString_Check(mod)) { Py_INCREF(mod); --- 45,49 ---- if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) return PyString_FromString("__builtin__"); ! mod = PyDict_GetItemString(type->tp_dict, "__module__"); if (mod != NULL && PyString_Check(mod)) { Py_INCREF(mod); *************** *** 81,99 **** } - static PyObject * - type_defined(PyTypeObject *type, void *context) - { - if (type->tp_defined == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - return PyDictProxy_New(type->tp_defined); - } - PyGetSetDef type_getsets[] = { {"__name__", (getter)type_name, NULL, NULL}, {"__module__", (getter)type_module, (setter)type_set_module, NULL}, {"__dict__", (getter)type_dict, NULL, NULL}, - {"__defined__", (getter)type_defined, NULL, NULL}, {0} }; --- 81,88 ---- *************** *** 839,844 **** type->tp_base = base; ! /* Initialize tp_defined from passed-in dict */ ! type->tp_defined = dict = PyDict_Copy(dict); if (dict == NULL) { Py_DECREF(type); --- 828,833 ---- type->tp_base = base; ! /* Initialize tp_dict from passed-in dict */ ! type->tp_dict = dict = PyDict_Copy(dict); if (dict == NULL) { Py_DECREF(type); *************** *** 974,978 **** PyObject *mro, *res, *dict; ! /* Look in tp_defined of types in MRO */ mro = type->tp_mro; assert(PyTuple_Check(mro)); --- 963,967 ---- PyObject *mro, *res, *dict; ! /* Look in tp_dict of types in MRO */ mro = type->tp_mro; assert(PyTuple_Check(mro)); *************** *** 981,985 **** type = (PyTypeObject *) PyTuple_GET_ITEM(mro, i); assert(PyType_Check(type)); ! dict = type->tp_defined; assert(dict && PyDict_Check(dict)); res = PyDict_GetItem(dict, name); --- 970,974 ---- type = (PyTypeObject *) PyTuple_GET_ITEM(mro, i); assert(PyType_Check(type)); ! dict = type->tp_dict; assert(dict && PyDict_Check(dict)); res = PyDict_GetItem(dict, name); *************** *** 1015,1019 **** } ! /* Look in tp_defined of this type and its bases */ res = _PyType_Lookup(type, name); if (res != NULL) { --- 1004,1008 ---- } ! /* Look in tp_dict of this type and its bases */ res = _PyType_Lookup(type, name); if (res != NULL) { *************** *** 1071,1075 **** Py_XDECREF(type->tp_bases); Py_XDECREF(type->tp_mro); ! Py_XDECREF(type->tp_defined); Py_XDECREF(type->tp_subclasses); Py_XDECREF(et->name); --- 1060,1064 ---- Py_XDECREF(type->tp_bases); Py_XDECREF(type->tp_mro); ! Py_XDECREF(type->tp_cache); Py_XDECREF(type->tp_subclasses); Py_XDECREF(et->name); *************** *** 1137,1141 **** VISIT(type->tp_dict); ! VISIT(type->tp_defined); VISIT(type->tp_mro); VISIT(type->tp_bases); --- 1126,1130 ---- VISIT(type->tp_dict); ! VISIT(type->tp_cache); VISIT(type->tp_mro); VISIT(type->tp_bases); *************** *** 1168,1172 **** CLEAR(type->tp_dict); ! CLEAR(type->tp_defined); CLEAR(type->tp_mro); CLEAR(type->tp_bases); --- 1157,1161 ---- CLEAR(type->tp_dict); ! CLEAR(type->tp_cache); CLEAR(type->tp_mro); CLEAR(type->tp_bases); *************** *** 1456,1460 **** add_methods(PyTypeObject *type, PyMethodDef *meth) { ! PyObject *dict = type->tp_defined; for (; meth->ml_name != NULL; meth++) { --- 1445,1449 ---- add_methods(PyTypeObject *type, PyMethodDef *meth) { ! PyObject *dict = type->tp_dict; for (; meth->ml_name != NULL; meth++) { *************** *** 1475,1479 **** add_members(PyTypeObject *type, PyMemberDef *memb) { ! PyObject *dict = type->tp_defined; for (; memb->name != NULL; memb++) { --- 1464,1468 ---- add_members(PyTypeObject *type, PyMemberDef *memb) { ! PyObject *dict = type->tp_dict; for (; memb->name != NULL; memb++) { *************** *** 1494,1498 **** add_getset(PyTypeObject *type, PyGetSetDef *gsp) { ! PyObject *dict = type->tp_defined; for (; gsp->name != NULL; gsp++) { --- 1483,1487 ---- add_getset(PyTypeObject *type, PyGetSetDef *gsp) { ! PyObject *dict = type->tp_dict; for (; gsp->name != NULL; gsp++) { *************** *** 1747,1751 **** } assert((type->tp_flags & Py_TPFLAGS_READYING) == 0); - assert(type->tp_dict == NULL); type->tp_flags |= Py_TPFLAGS_READYING; --- 1736,1739 ---- *************** *** 1774,1787 **** } ! /* Initialize tp_defined */ ! dict = type->tp_defined; if (dict == NULL) { dict = PyDict_New(); if (dict == NULL) goto error; ! type->tp_defined = dict; } ! /* Add type-specific descriptors to tp_defined */ if (add_operators(type) < 0) goto error; --- 1762,1775 ---- } ! /* Initialize tp_dict */ ! dict = type->tp_dict; if (dict == NULL) { dict = PyDict_New(); if (dict == NULL) goto error; ! type->tp_dict = dict; } ! /* Add type-specific descriptors to tp_dict */ if (add_operators(type) < 0) goto error; *************** *** 1799,1808 **** } - /* Temporarily make tp_dict the same object as tp_defined. - (This is needed to call mro(), and can stay this way for - dynamic types). */ - Py_INCREF(type->tp_defined); - type->tp_dict = type->tp_defined; - /* Calculate method resolution order */ if (mro_internal(type) < 0) { --- 1787,1790 ---- *************** *** 2677,2686 **** PyObject *func; ! if (PyDict_GetItemString(type->tp_defined, "__new__") != NULL) return 0; func = PyCFunction_New(tp_new_methoddef, (PyObject *)type); if (func == NULL) return -1; ! return PyDict_SetItemString(type->tp_defined, "__new__", func); } --- 2659,2668 ---- PyObject *func; ! if (PyDict_GetItemString(type->tp_dict, "__new__") != NULL) return 0; func = PyCFunction_New(tp_new_methoddef, (PyObject *)type); if (func == NULL) return -1; ! return PyDict_SetItemString(type->tp_dict, "__new__", func); } *************** *** 2688,2692 **** add_wrappers(PyTypeObject *type, struct wrapperbase *wraps, void *wrapped) { ! PyObject *dict = type->tp_defined; for (; wraps->name != NULL; wraps++) { --- 2670,2674 ---- add_wrappers(PyTypeObject *type, struct wrapperbase *wraps, void *wrapped) { ! PyObject *dict = type->tp_dict; for (; wraps->name != NULL; wraps++) { *************** *** 2707,2711 **** dictionary with method descriptors for function slots. For each function slot (like tp_repr) that's defined in the type, one or ! more corresponding descriptors are added in the type's tp_defined dictionary under the appropriate name (like __repr__). Some function slots cause more than one descriptor to be added (for --- 2689,2693 ---- dictionary with method descriptors for function slots. For each function slot (like tp_repr) that's defined in the type, one or ! more corresponding descriptors are added in the type's tp_dict dictionary under the appropriate name (like __repr__). Some function slots cause more than one descriptor to be added (for *************** *** 2714,2718 **** descriptor (for example both sq_item and mp_subscript generate a __getitem__ descriptor). This only adds new descriptors and ! doesn't overwrite entries in tp_defined that were previously defined. The descriptors contain a reference to the C function they must call, so that it's safe if they are copied into a --- 2696,2700 ---- descriptor (for example both sq_item and mp_subscript generate a __getitem__ descriptor). This only adds new descriptors and ! doesn't overwrite entries in tp_dict that were previously defined. The descriptors contain a reference to the C function they must call, so that it's safe if they are copied into a *************** *** 3943,3947 **** assert(PyType_Check(base)); descr = PyDict_GetItem( ! base->tp_defined, p->name_strobj); if (descr != NULL) break; --- 3925,3929 ---- assert(PyType_Check(base)); descr = PyDict_GetItem( ! base->tp_dict, p->name_strobj); if (descr != NULL) break; *************** *** 4056,4060 **** assert(PyType_Check(tmp)); res = PyDict_GetItem( ! ((PyTypeObject *)tmp)->tp_defined, name); if (res != NULL) { Py_INCREF(res); --- 4038,4042 ---- assert(PyType_Check(tmp)); res = PyDict_GetItem( ! ((PyTypeObject *)tmp)->tp_dict, name); if (res != NULL) { Py_INCREF(res); From gvanrossum@users.sourceforge.net Mon Oct 15 23:03:33 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 15:03:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.96,2.97 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv23185/Include Modified Files: object.h Log Message: Get rid of __defined__ and tp_defined -- there's no need to distinguish __dict__ and __defined__ any more. In the C structure, tp_cache takes its place -- but this hasn't been implemented yet. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.96 retrieving revision 2.97 diff -C2 -d -r2.96 -r2.97 *** object.h 2001/10/15 21:05:10 2.96 --- object.h 2001/10/15 22:03:31 2.97 *************** *** 289,293 **** PyObject *tp_bases; PyObject *tp_mro; /* method resolution order */ ! PyObject *tp_defined; PyObject *tp_subclasses; PyObject *tp_weaklist; --- 289,293 ---- PyObject *tp_bases; PyObject *tp_mro; /* method resolution order */ ! PyObject *tp_cache; PyObject *tp_subclasses; PyObject *tp_weaklist; From tim_one@users.sourceforge.net Mon Oct 15 23:49:29 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 15 Oct 2001 15:49:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_gc.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv4851/python/Lib/test Modified Files: test_gc.py Log Message: Remove obsolete __static__/__dynamic__ distinction. Index: test_gc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_gc.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** test_gc.py 2001/10/05 20:51:38 1.11 --- test_gc.py 2001/10/15 22:49:27 1.12 *************** *** 51,68 **** expect_nonzero(gc.collect(), "class") ! def test_staticclass(): class A(object): ! __dynamic__ = 0 gc.collect() del A expect_nonzero(gc.collect(), "staticclass") - def test_dynamicclass(): - class A(object): - __dynamic__ = 1 - gc.collect() - del A - expect_nonzero(gc.collect(), "dynamicclass") - def test_instance(): class A: --- 51,61 ---- expect_nonzero(gc.collect(), "class") ! def test_newstyleclass(): class A(object): ! pass gc.collect() del A expect_nonzero(gc.collect(), "staticclass") def test_instance(): class A: *************** *** 186,191 **** run_test("tuples", test_tuple) run_test("classes", test_class) ! run_test("static classes", test_staticclass) ! run_test("dynamic classes", test_dynamicclass) run_test("instances", test_instance) run_test("new instances", test_newinstance) --- 179,183 ---- run_test("tuples", test_tuple) run_test("classes", test_class) ! run_test("new style classes", test_newstyleclass) run_test("instances", test_instance) run_test("new instances", test_newinstance) From tim_one@users.sourceforge.net Mon Oct 15 23:52:27 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 15 Oct 2001 15:52:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_inspect.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv5355/python/Lib/test Modified Files: test_inspect.py Log Message: Remove obsolete __dynamic__ distinction. Index: test_inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_inspect.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_inspect.py 2001/09/23 02:00:29 1.6 --- test_inspect.py 2001/10/15 22:52:25 1.7 *************** *** 298,374 **** test(('datablob', 'data', A) in attrs, 'missing data') ! # Repeat all that, but w/ new-style non-dynamic classes. ! ! class A(object): ! __dynamic__ = 0 ! ! def s(): pass ! s = staticmethod(s) ! ! def c(cls): pass ! c = classmethod(c) ! ! def getp(self): pass ! p = property(getp) ! ! def m(self): pass ! ! def m1(self): pass ! ! datablob = '1' ! ! attrs = attrs_wo_objs(A) ! test(('s', 'static method', A) in attrs, 'missing static method') ! test(('c', 'class method', A) in attrs, 'missing class method') ! test(('p', 'property', A) in attrs, 'missing property') ! test(('m', 'method', A) in attrs, 'missing plain method') ! test(('m1', 'method', A) in attrs, 'missing plain method') ! test(('datablob', 'data', A) in attrs, 'missing data') ! ! class B(A): ! __dynamic__ = 0 ! ! def m(self): pass ! ! attrs = attrs_wo_objs(B) ! test(('s', 'static method', A) in attrs, 'missing static method') ! test(('c', 'class method', A) in attrs, 'missing class method') ! test(('p', 'property', A) in attrs, 'missing property') ! test(('m', 'method', B) in attrs, 'missing plain method') ! test(('m1', 'method', A) in attrs, 'missing plain method') ! test(('datablob', 'data', A) in attrs, 'missing data') ! ! ! class C(A): ! __dynamic__ = 0 ! ! def m(self): pass ! def c(self): pass ! ! attrs = attrs_wo_objs(C) ! test(('s', 'static method', A) in attrs, 'missing static method') ! test(('c', 'method', C) in attrs, 'missing plain method') ! test(('p', 'property', A) in attrs, 'missing property') ! test(('m', 'method', C) in attrs, 'missing plain method') ! test(('m1', 'method', A) in attrs, 'missing plain method') ! test(('datablob', 'data', A) in attrs, 'missing data') ! ! class D(B, C): ! __dynamic__ = 0 ! ! def m1(self): pass ! ! attrs = attrs_wo_objs(D) ! test(('s', 'static method', A) in attrs, 'missing static method') ! test(('c', 'method', C) in attrs, 'missing plain method') ! test(('p', 'property', A) in attrs, 'missing property') ! test(('m', 'method', B) in attrs, 'missing plain method') ! test(('m1', 'method', D) in attrs, 'missing plain method') ! test(('datablob', 'data', A) in attrs, 'missing data') ! ! # And again, but w/ new-style dynamic classes. class A(object): - __dynamic__ = 1 def s(): pass --- 298,304 ---- test(('datablob', 'data', A) in attrs, 'missing data') ! # Repeat all that, but w/ new-style classes. class A(object): def s(): pass *************** *** 396,400 **** class B(A): - __dynamic__ = 1 def m(self): pass --- 326,329 ---- *************** *** 410,414 **** class C(A): - __dynamic__ = 1 def m(self): pass --- 339,342 ---- *************** *** 424,428 **** class D(B, C): - __dynamic__ = 1 def m1(self): pass --- 352,355 ---- From tim_one@users.sourceforge.net Mon Oct 15 23:53:32 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 15 Oct 2001 15:53:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/xml/dom minidom.py,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory usw-pr-cvs1:/tmp/cvs-serv5600/python/Lib/xml/dom Modified Files: minidom.py Log Message: Remove obsolete __dynamic__ distinction. Index: minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/dom/minidom.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** minidom.py 2001/09/29 04:58:32 1.39 --- minidom.py 2001/10/15 22:53:29 1.40 *************** *** 35,40 **** if list is type([]): class NodeList(list): - __dynamic__ = 0 - def item(self, index): if 0 <= index < len(self): --- 35,38 ---- From tim_one@users.sourceforge.net Tue Oct 16 00:00:02 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 15 Oct 2001 16:00:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test pydocfodder.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv7114/python/Lib/test Modified Files: pydocfodder.py Log Message: Remove obsolete __dynamic__ distinction. Index: pydocfodder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pydocfodder.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pydocfodder.py 2001/09/26 20:31:52 1.1 --- pydocfodder.py 2001/10/15 22:59:59 1.2 *************** *** 79,86 **** ! class A_new_dynamic(object): ! "A new-style dynamic class." ! ! __dynamic__ = 1 def A_method(self): --- 79,84 ---- ! class A_new(object): ! "A new-style class." def A_method(self): *************** *** 119,127 **** A_int_alias = int - - class B_new_dynamic(A_new_dynamic): - "A new-style dynamic class, derived from A_new_dynamic." ! __dynamic__ = 1 def AB_method(self): --- 117,123 ---- A_int_alias = int ! class B_new(A_new): ! "A new-style class, derived from A_new." def AB_method(self): *************** *** 141,149 **** def BCD_method(self): "Method defined in B, C and D." - - class C_new_dynamic(A_new_dynamic): - "A new-style dynamic class, derived from A_new_dynamic." ! __dynamic__ = 1 def AC_method(self): --- 137,143 ---- def BCD_method(self): "Method defined in B, C and D." ! class C_new(A_new): ! "A new-style class, derived from A_new." def AC_method(self): *************** *** 164,282 **** "Method defined in C and D." ! class D_new_dynamic(B_new_dynamic, C_new_dynamic): ! """A new-style dynamic class, derived from B_new_dynamic and ! C_new_dynamic. """ - - __dynamic__ = 1 - - def AD_method(self): - "Method defined in A and D." - def ABD_method(self): - "Method defined in A, B and D." - def ACD_method(self): - "Method defined in A, C and D." - def ABCD_method(self): - "Method defined in A, B, C and D." - def BD_method(self): - "Method defined in B and D." - def BCD_method(self): - "Method defined in B, C and D." - def CD_method(self): - "Method defined in C and D." - def D_method(self): - "Method defined in D." - - - class A_new_static(object): - "A new-style static class." - - __dynamic__ = 0 - - def A_method(self): - "Method defined in A." - def AB_method(self): - "Method defined in A and B." - def AC_method(self): - "Method defined in A and C." - def AD_method(self): - "Method defined in A and D." - def ABC_method(self): - "Method defined in A, B and C." - def ABD_method(self): - "Method defined in A, B and D." - def ACD_method(self): - "Method defined in A, C and D." - def ABCD_method(self): - "Method defined in A, B, C and D." - - def A_classmethod(cls, x): - "A class method defined in A." - A_classmethod = classmethod(A_classmethod) - - def A_staticmethod(): - "A static method defined in A." - A_staticmethod = staticmethod(A_staticmethod) - - def _getx(self): - "A property getter function." - def _setx(self, value): - "A property setter function." - def _delx(self): - "A property deleter function." - A_property = property(fdel=_delx, fget=_getx, fset=_setx, - doc="A sample property defined in A.") - - A_int_alias = int - - - class B_new_static(A_new_static): - "A new-style static class, derived from A_new_static." - - __dynamic__ = 0 - - def AB_method(self): - "Method defined in A and B." - def ABC_method(self): - "Method defined in A, B and C." - def ABD_method(self): - "Method defined in A, B and D." - def ABCD_method(self): - "Method defined in A, B, C and D." - def B_method(self): - "Method defined in B." - def BC_method(self): - "Method defined in B and C." - def BD_method(self): - "Method defined in B and D." - def BCD_method(self): - "Method defined in B, C and D." - - class C_new_static(A_new_static): - "A new-style static class, derived from A_new_static." - - __dynamic__ = 0 - - def AC_method(self): - "Method defined in A and C." - def ABC_method(self): - "Method defined in A, B and C." - def ACD_method(self): - "Method defined in A, C and D." - def ABCD_method(self): - "Method defined in A, B, C and D." - def BC_method(self): - "Method defined in B and C." - def BCD_method(self): - "Method defined in B, C and D." - def C_method(self): - "Method defined in C." - def CD_method(self): - "Method defined in C and D." - - class D_new_static(B_new_static, C_new_static): - "A new-style static class, derived from B_new_static and C_new_static." - - __dynamic__ = 0 def AD_method(self): --- 158,164 ---- "Method defined in C and D." ! class D_new(B_new, C_new): ! """A new-style class, derived from B_new and C_new. """ def AD_method(self): From gvanrossum@users.sourceforge.net Tue Oct 16 01:47:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 15 Oct 2001 17:47:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.277,1.278 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv30043 Modified Files: NEWS Log Message: Reword the text on the demise of __dynamic__ somewhat, correcting a typo. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.277 retrieving revision 1.278 diff -C2 -d -r1.277 -r1.278 *** NEWS 2001/10/15 22:03:32 1.277 --- NEWS 2001/10/16 00:46:57 1.278 *************** *** 6,16 **** - New-style classes are now always dynamic (except for built-in and ! extension types). There was no longer a performance penalty, and I no longer see another reason to keep this baggage around. One relic ! remains: the __dict__ or a new-style class is a read-only proxy. ! You must set the class's attribute to modify. As a consequence, the __defined__ attribute of new-style types no longer exists, for lack of need: there is once again only one __dict__ (although in the ! future a __cache__ may be resurrected in its place). - C.__doc__ now works as expected for new-style classes (in 2.2a4 it --- 6,17 ---- - New-style classes are now always dynamic (except for built-in and ! extension types). There is no longer a performance penalty, and I no longer see another reason to keep this baggage around. One relic ! remains: the __dict__ of a new-style class is a read-only proxy; you ! must set the class's attribute to modify it. As a consequence, the __defined__ attribute of new-style types no longer exists, for lack of need: there is once again only one __dict__ (although in the ! future a __cache__ may be resurrected with a similar function, if I ! can prove that it actually speeds things up). - C.__doc__ now works as expected for new-style classes (in 2.2a4 it From fdrake@users.sourceforge.net Tue Oct 16 04:25:02 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 15 Oct 2001 20:25:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.150,1.151 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory usw-pr-cvs1:/tmp/cvs-serv15509 Modified Files: tut.tex Log Message: Fix thinko in a comment about seeking with a file object. Reported by Francesco Trentini. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.150 retrieving revision 1.151 diff -C2 -d -r1.150 -r1.151 *** tut.tex 2001/09/21 21:10:05 1.150 --- tut.tex 2001/10/16 03:25:00 1.151 *************** *** 2874,2878 **** >>> f=open('/tmp/workfile', 'r+') >>> f.write('0123456789abcdef') ! >>> f.seek(5) # Go to the 5th byte in the file >>> f.read(1) '5' --- 2874,2878 ---- >>> f=open('/tmp/workfile', 'r+') >>> f.write('0123456789abcdef') ! >>> f.seek(5) # Go to the 6th byte in the file >>> f.read(1) '5' From fdrake@users.sourceforge.net Tue Oct 16 15:54:24 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 16 Oct 2001 07:54:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libsys.tex,1.52,1.53 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv5859/lib Modified Files: libsys.tex Log Message: Added information about setprofile() and settrace() hooks being thread- specific, and updated some of the comments about the profile hook. This closes SF bug #471725. Index: libsys.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsys.tex,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** libsys.tex 2001/09/04 18:18:36 1.52 --- libsys.tex 2001/10/16 14:54:22 1.53 *************** *** 370,374 **** is called similarly to the system's trace function (see \function{settrace()}), but it isn't called for each executed line ! of code (only on call and return and when an exception occurs). Also, its return value is not used, so it can simply return \code{None}. --- 370,378 ---- is called similarly to the system's trace function (see \function{settrace()}), but it isn't called for each executed line ! of code (only on call and return, but the return event is reported ! even when an exception has been set). The function is ! thread-specific, but there is no way for the profiler to know about ! context switches between threads, so it does not make sense to use ! this in the presence of multiple threads. Also, its return value is not used, so it can simply return \code{None}. *************** *** 390,394 **** you to implement a Python source code debugger in Python. See section \ref{debugger-hooks}, ``How It Works,'' in the chapter on ! the Python debugger.\index{debugger} \end{funcdesc} --- 394,401 ---- you to implement a Python source code debugger in Python. See section \ref{debugger-hooks}, ``How It Works,'' in the chapter on ! the Python debugger.\index{debugger} The function is ! thread-specific; for a debugger to support multiple threads, it must ! be registered using \function{settrace()} for each thread being ! debugged. \end{funcdesc} From jhylton@users.sourceforge.net Tue Oct 16 17:51:58 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 16 Oct 2001 09:51:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python structmember.c,2.21,2.22 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv4147 Modified Files: structmember.c Log Message: Put descr name in "bad memberdescr type" error message. Index: structmember.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/structmember.c,v retrieving revision 2.21 retrieving revision 2.22 diff -C2 -d -r2.21 -r2.22 *** structmember.c 2001/09/20 20:46:19 2.21 --- structmember.c 2001/10/16 16:51:56 2.22 *************** *** 262,266 **** break; default: ! PyErr_SetString(PyExc_SystemError, "bad memberdescr type"); return -1; } --- 262,267 ---- break; default: ! PyErr_Format(PyExc_SystemError, ! "bad memberdescr type for %s", l->name); return -1; } From gvanrossum@users.sourceforge.net Tue Oct 16 18:00:50 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 10:00:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.105,2.106 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv6589 Modified Files: typeobject.c Log Message: Refactored the update_slot() code a bit to be hopefully slightly more efficient: - recurse down subclasses only once rather than for each affected slot; - short-circuit recursing down subclasses when a subclass has its own definition of the name that caused the update_slot() calls in the first place; - inline collect_ptrs(). Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.105 retrieving revision 2.106 diff -C2 -d -r2.105 -r2.106 *** typeobject.c 2001/10/15 22:03:32 2.105 --- typeobject.c 2001/10/16 17:00:48 2.106 *************** *** 3765,3816 **** } ! staticforward int recurse_down_subclasses(PyTypeObject *type, slotdef *p); static int ! update_one_slot(PyTypeObject *type, slotdef *p0) { ! slotdef *p = p0; ! PyObject *descr; ! PyWrapperDescrObject *d; ! void *generic = NULL, *specific = NULL; ! int use_generic = 0; ! int offset; ! void **ptr; ! offset = p->offset; ! ptr = slotptr(type, offset); ! if (ptr == NULL) ! return recurse_down_subclasses(type, p); ! do { ! descr = _PyType_Lookup(type, p->name_strobj); ! if (descr == NULL) continue; ! generic = p->function; ! if (descr->ob_type == &PyWrapperDescr_Type) { ! d = (PyWrapperDescrObject *)descr; ! if (d->d_base->wrapper == p->wrapper && ! PyType_IsSubtype(type, d->d_type)) { ! if (specific == NULL || ! specific == d->d_wrapped) ! specific = d->d_wrapped; ! else ! use_generic = 1; } ! } else ! use_generic = 1; ! } while ((++p)->offset == offset); ! if (specific && !use_generic) ! *ptr = specific; ! else ! *ptr = generic; ! return recurse_down_subclasses(type, p0); } static int ! recurse_down_subclasses(PyTypeObject *type, slotdef *p) { PyTypeObject *subclass; ! PyObject *ref, *subclasses; int i, n; --- 3765,3818 ---- } ! staticforward int recurse_down_subclasses(PyTypeObject *type, ! slotdef **pp, PyObject *name); static int ! update_these_slots(PyTypeObject *type, slotdef **pp0, PyObject *name) { ! slotdef **pp; ! for (pp = pp0; *pp; pp++) { ! slotdef *p = *pp; ! PyObject *descr; ! PyWrapperDescrObject *d; ! void *generic = NULL, *specific = NULL; ! int use_generic = 0; ! int offset = p->offset; ! void **ptr = slotptr(type, offset); ! if (ptr == NULL) continue; ! do { ! descr = _PyType_Lookup(type, p->name_strobj); ! if (descr == NULL) ! continue; ! generic = p->function; ! if (descr->ob_type == &PyWrapperDescr_Type) { ! d = (PyWrapperDescrObject *)descr; ! if (d->d_base->wrapper == p->wrapper && ! PyType_IsSubtype(type, d->d_type)) { ! if (specific == NULL || ! specific == d->d_wrapped) ! specific = d->d_wrapped; ! else ! use_generic = 1; ! } } ! else ! use_generic = 1; ! } while ((++p)->offset == offset); ! if (specific && !use_generic) ! *ptr = specific; else ! *ptr = generic; ! } ! return recurse_down_subclasses(type, pp0, name); } static int ! recurse_down_subclasses(PyTypeObject *type, slotdef **pp, PyObject *name) { PyTypeObject *subclass; ! PyObject *ref, *subclasses, *dict; int i, n; *************** *** 3827,3831 **** continue; assert(PyType_Check(subclass)); ! if (update_one_slot(subclass, p) < 0) return -1; } --- 3829,3838 ---- continue; assert(PyType_Check(subclass)); ! /* Avoid recursing down into unaffected classes */ ! dict = subclass->tp_dict; ! if (dict != NULL && PyDict_Check(dict) && ! PyDict_GetItem(dict, name) != NULL) ! continue; ! if (update_these_slots(subclass, pp, name) < 0) return -1; } *************** *** 3857,3877 **** Py_FatalError("XXX ouch"); } ! qsort((void *)slotdefs, (size_t)(p-slotdefs), sizeof(slotdef), slotdef_cmp); initialized = 1; } - static void - collect_ptrs(PyObject *name, slotdef *ptrs[]) - { - slotdef *p; - - init_slotdefs(); - for (p = slotdefs; p->name; p++) { - if (name == p->name_strobj) - *ptrs++ = p; - } - *ptrs = NULL; - } - static int update_slot(PyTypeObject *type, PyObject *name) --- 3864,3872 ---- Py_FatalError("XXX ouch"); } ! qsort((void *)slotdefs, (size_t)(p-slotdefs), sizeof(slotdef), ! slotdef_cmp); initialized = 1; } static int update_slot(PyTypeObject *type, PyObject *name) *************** *** 3880,3893 **** slotdef *p; slotdef **pp; ! collect_ptrs(name, ptrs); for (pp = ptrs; *pp; pp++) { p = *pp; ! while (p > slotdefs && p->offset == (p-1)->offset) --p; ! if (update_one_slot(type, p) < 0) ! return -1; } ! return 0; } --- 3875,3896 ---- slotdef *p; slotdef **pp; + int offset; ! init_slotdefs(); ! pp = ptrs; ! for (p = slotdefs; p->name; p++) { ! /* XXX assume name is interned! */ ! if (p->name_strobj == name) ! *pp++ = p; ! } ! *pp = NULL; for (pp = ptrs; *pp; pp++) { p = *pp; ! offset = p->offset; ! while (p > slotdefs && (p-1)->offset == offset) --p; ! *pp = p; } ! return update_these_slots(type, ptrs, name); } *************** *** 3922,3926 **** descr = NULL; for (i = 0; i < n; i++) { ! base = (PyTypeObject *)PyTuple_GET_ITEM(mro, i); assert(PyType_Check(base)); descr = PyDict_GetItem( --- 3925,3930 ---- descr = NULL; for (i = 0; i < n; i++) { ! base = (PyTypeObject *) ! PyTuple_GET_ITEM(mro, i); assert(PyType_Check(base)); descr = PyDict_GetItem( From jhylton@users.sourceforge.net Tue Oct 16 18:10:51 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 16 Oct 2001 10:10:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules cPickle.c,2.66,2.67 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv9024 Modified Files: cPickle.c Log Message: Must terminate the Pickler_members[] and Pickler_getsets with NULL. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.66 retrieving revision 2.67 diff -C2 -d -r2.66 -r2.67 *** cPickle.c 2001/10/15 21:37:58 2.66 --- cPickle.c 2001/10/16 17:10:49 2.67 *************** *** 2462,2465 **** --- 2462,2466 ---- {"binary", T_INT, offsetof(Picklerobject, bin)}, {"fast", T_INT, offsetof(Picklerobject, fast)}, + {NULL} }; *************** *** 2469,2473 **** {"inst_persistent_id", NULL, (setter)Pickler_set_inst_pers_func}, {"memo", (getter)Pickler_get_memo, (setter)Pickler_set_memo}, ! {"PicklingError", (getter)Pickler_get_error, NULL} }; --- 2470,2475 ---- {"inst_persistent_id", NULL, (setter)Pickler_set_inst_pers_func}, {"memo", (getter)Pickler_get_memo, (setter)Pickler_set_memo}, ! {"PicklingError", (getter)Pickler_get_error, NULL}, ! {NULL} }; From fdrake@users.sourceforge.net Tue Oct 16 20:22:53 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 16 Oct 2001 12:22:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib emailparser.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv22570/lib Modified Files: emailparser.tex Log Message: Fix a few usage and style-guide conformance issues. Index: emailparser.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailparser.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** emailparser.tex 2001/10/11 15:45:05 1.3 --- emailparser.tex 2001/10/16 19:22:51 1.4 *************** *** 14,19 **** to you the root \class{Message} instance of the object tree. For simple, non-MIME messages the payload of this root object will likely ! be a string (e.g. containing the text of the message). For MIME ! messages, the root object will return 1 from its \method{is_multipart()} method, and the subparts can be accessed via the \method{get_payload()} and \method{walk()} methods. --- 14,19 ---- to you the root \class{Message} instance of the object tree. For simple, non-MIME messages the payload of this root object will likely ! be a string containing the text of the message. For MIME ! messages, the root object will return true from its \method{is_multipart()} method, and the subparts can be accessed via the \method{get_payload()} and \method{walk()} methods. *************** *** 40,47 **** \begin{classdesc}{Parser}{\optional{_class}} The constructor for the \class{Parser} class takes a single optional ! argument \var{_class}. This must be callable factory (i.e. a function ! or a class), and it is used whenever a sub-message object needs to be ! created. It defaults to \class{Message} (see ! \refmodule{email.Message}). \var{_class} will be called with zero arguments. \end{classdesc} --- 40,47 ---- \begin{classdesc}{Parser}{\optional{_class}} The constructor for the \class{Parser} class takes a single optional ! argument \var{_class}. This must be a callable factory (such as a ! function or a class), and it is used whenever a sub-message object ! needs to be created. It defaults to \class{Message} (see ! \refmodule{email.Message}). The factory will be called without arguments. \end{classdesc} *************** *** 106,113 **** object containing non-multipart subobjects for each header block. ! \item Another exception is for \mimetype{message/*} types (i.e. more general than \mimetype{message/delivery-status}). These are ! typically \mimetype{message/rfc822} type messages, represented as a ! non-multipart object containing a singleton payload, another ! non-multipart \class{Message} instance. \end{itemize} --- 106,113 ---- object containing non-multipart subobjects for each header block. ! \item Another exception is for \mimetype{message/*} types (more general than \mimetype{message/delivery-status}). These are ! typically \mimetype{message/rfc822} messages, represented as a ! non-multipart object containing a singleton payload which is ! another non-multipart \class{Message} instance. \end{itemize} From fdrake@users.sourceforge.net Tue Oct 16 20:23:57 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 16 Oct 2001 12:23:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api init.tex,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv22855/api Modified Files: init.tex Log Message: Update the description of PyTrace_EXCEPT. Index: init.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/init.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** init.tex 2001/10/12 19:01:43 1.1 --- init.tex 2001/10/16 19:23:55 1.2 *************** *** 709,717 **** \begin{cvardesc}{int}{PyTrace_EXCEPT} The value of the \var{what} parameter to a \ctype{Py_tracefunc} ! function when an exception has been raised by Python code as the ! result of an operation. The operation may have explictly intended ! to raise the operation (as with a \keyword{raise} statement), or may ! have triggered an exception in the runtime as a result of the ! specific operation. \end{cvardesc} --- 709,720 ---- \begin{cvardesc}{int}{PyTrace_EXCEPT} The value of the \var{what} parameter to a \ctype{Py_tracefunc} ! function when an exception has been raised. The callback function ! is called with this value for \var{what} when after any bytecode is ! processed after which the exception becomes set within the frame ! being executed. The effect of this is that as exception propogation ! causes the Python stack to unwind, the callback is called upon ! return to each frame as the exception propogates. Only trace ! functions receives these events; they are not needed by the ! profiler. \end{cvardesc} From gvanrossum@users.sourceforge.net Tue Oct 16 20:45:54 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 12:45:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib ftplib.py,1.58,1.59 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv4678 Modified Files: ftplib.py Log Message: Fix SF bug #459767: ftplib fails with files > 2GB size(), parse150(): try int() first, catch OverflowError, fall back to long(). Index: ftplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ftplib.py,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -d -r1.58 -r1.59 *** ftplib.py 2001/10/07 08:53:32 1.58 --- ftplib.py 2001/10/16 19:45:52 1.59 *************** *** 344,348 **** def transfercmd(self, cmd, rest=None): ! """Like nstransfercmd() but returns only the socket.""" return self.ntransfercmd(cmd, rest)[0] --- 344,348 ---- def transfercmd(self, cmd, rest=None): ! """Like ntransfercmd() but returns only the socket.""" return self.ntransfercmd(cmd, rest)[0] *************** *** 506,510 **** resp = self.sendcmd('SIZE ' + filename) if resp[:3] == '213': ! return int(resp[3:].strip()) def mkd(self, dirname): --- 506,514 ---- resp = self.sendcmd('SIZE ' + filename) if resp[:3] == '213': ! s = resp[3:].strip() ! try: ! return int(s) ! except OverflowError: ! return long(s) def mkd(self, dirname): *************** *** 550,556 **** _150_re = re.compile("150 .* \((\d+) bytes\)", re.IGNORECASE) m = _150_re.match(resp) ! if m: ! return int(m.group(1)) ! return None --- 554,564 ---- _150_re = re.compile("150 .* \((\d+) bytes\)", re.IGNORECASE) m = _150_re.match(resp) ! if not m: ! return None ! s = m.group(1) ! try: ! return int(s) ! except OverflowError: ! return long(s) From gvanrossum@users.sourceforge.net Tue Oct 16 21:07:36 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 13:07:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python importdl.c,2.68,2.69 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv11552 Modified Files: importdl.c Log Message: SF patch #471839: Bug when extensions import extensions (Shane Hathaway) When an extension imports another extension in its initXXX() function, the variable _Py_PackageContext is prematurely reset to NULL. If the outer extension then calls Py_InitModule(), the extension is installed in sys.modules without its package name. The manifestation of this bug is a "SystemError: _PyImport_FixupExtension: module . not loaded". To fix this, importdl.c just needs to retain the old value of _Py_PackageContext and restore it after the initXXX() method is called. The attached patch does this. This patch applies to Python 2.1.1 and the current CVS. Index: importdl.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/importdl.c,v retrieving revision 2.68 retrieving revision 2.69 diff -C2 -d -r2.68 -r2.69 *** importdl.c 2000/09/01 23:29:28 2.68 --- importdl.c 2001/10/16 20:07:34 2.69 *************** *** 23,27 **** { PyObject *m, *d, *s; ! char *lastdot, *shortname, *packagecontext; dl_funcptr p; --- 23,27 ---- { PyObject *m, *d, *s; ! char *lastdot, *shortname, *packagecontext, *oldcontext; dl_funcptr p; *************** *** 49,55 **** return NULL; } _Py_PackageContext = packagecontext; (*p)(); ! _Py_PackageContext = NULL; if (PyErr_Occurred()) return NULL; --- 49,56 ---- return NULL; } + oldcontext = _Py_PackageContext; _Py_PackageContext = packagecontext; (*p)(); ! _Py_PackageContext = oldcontext; if (PyErr_Occurred()) return NULL; From gvanrossum@users.sourceforge.net Tue Oct 16 21:13:55 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 13:13:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.122,1.123 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv13072 Modified Files: ACKS Log Message: Add Shane. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.122 retrieving revision 1.123 diff -C2 -d -r1.122 -r1.123 *** ACKS 2001/10/15 19:55:12 1.122 --- ACKS 2001/10/16 20:13:53 1.123 *************** *** 169,172 **** --- 169,173 ---- Gerhard Häring Larry Hastings + Shane Hathaway Rycharde Hawkes Jochen Hayek From tim_one@users.sourceforge.net Tue Oct 16 21:18:26 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 16 Oct 2001 13:18:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.89,1.90 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv11274/python/Lib/test Modified Files: test_descr.py Log Message: SF bug [#468061] __str__ ignored in str subclass. object.c, PyObject_Str: Don't try to optimize anything except exact string objects here; in particular, let str subclasses go thru tp_str, same as non-str objects. This allows overrides of tp_str to take effect. stringobject.c: + string_print (str's tp_print): If the argument isn't an exact string object, get one from PyObject_Str. + string_str (str's tp_str): Make a genuine-string copy of the object if it's of a proper str subclass type. str() applied to a str subclass that doesn't override __str__ ends up here. test_descr.py: New str_of_str_subclass() test. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.89 retrieving revision 1.90 diff -C2 -d -r1.89 -r1.90 *** test_descr.py 2001/10/15 21:05:10 1.89 --- test_descr.py 2001/10/16 20:18:24 1.90 *************** *** 2299,2302 **** --- 2299,2332 ---- pass + def str_of_str_subclass(): + import binascii + import cStringIO + + if verbose: + print "Testing __str__ defined in subclass of str ..." + + class octetstring(str): + def __str__(self): + return binascii.b2a_hex(self) + def __repr__(self): + return self + " repr" + + o = octetstring('A') + vereq(type(o), octetstring) + vereq(type(str(o)), str) + vereq(type(repr(o)), str) + vereq(ord(o), 0x41) + vereq(str(o), '41') + vereq(repr(o), 'A repr') + vereq(o.__str__(), '41') + vereq(o.__repr__(), 'A repr') + + capture = cStringIO.StringIO() + # Calling str() or not exercises different internal paths. + print >> capture, o + print >> capture, str(o) + vereq(capture.getvalue(), '41\n41\n') + capture.close() + def test_main(): class_docstrings() *************** *** 2347,2350 **** --- 2377,2381 ---- subclasspropagation() buffer_inherit() + str_of_str_subclass() if verbose: print "All OK" From tim_one@users.sourceforge.net Tue Oct 16 21:18:26 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 16 Oct 2001 13:18:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.156,2.157 stringobject.c,2.138,2.139 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv11274/python/Objects Modified Files: object.c stringobject.c Log Message: SF bug [#468061] __str__ ignored in str subclass. object.c, PyObject_Str: Don't try to optimize anything except exact string objects here; in particular, let str subclasses go thru tp_str, same as non-str objects. This allows overrides of tp_str to take effect. stringobject.c: + string_print (str's tp_print): If the argument isn't an exact string object, get one from PyObject_Str. + string_str (str's tp_str): Make a genuine-string copy of the object if it's of a proper str subclass type. str() applied to a str subclass that doesn't override __str__ ends up here. test_descr.py: New str_of_str_subclass() test. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.156 retrieving revision 2.157 diff -C2 -d -r2.156 -r2.157 *** object.c 2001/10/07 03:54:51 2.156 --- object.c 2001/10/16 20:18:24 2.157 *************** *** 262,271 **** return v; } - if (PyString_Check(v)) { - /* For a string subtype that's not a string, return a true - string with the same string data. */ - PyStringObject *s = (PyStringObject *)v; - return PyString_FromStringAndSize(s->ob_sval, s->ob_size); - } if (v->ob_type->tp_str == NULL) return PyObject_Repr(v); --- 262,265 ---- Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.138 retrieving revision 2.139 diff -C2 -d -r2.138 -r2.139 *** stringobject.c 2001/10/13 15:57:55 2.138 --- stringobject.c 2001/10/16 20:18:24 2.139 *************** *** 567,571 **** --- 567,582 ---- char c; int quote; + /* XXX Ought to check for interrupts when writing long strings */ + if (! PyString_CheckExact(op)) { + int ret; + /* A str subclass may have its own __str__ method. */ + op = (PyStringObject *) PyObject_Str((PyObject *)op); + if (op == NULL) + return -1; + ret = string_print(op, fp, flags); + Py_DECREF(op); + return ret; + } if (flags & Py_PRINT_RAW) { fwrite(op->ob_sval, 1, (int) op->ob_size, fp); *************** *** 652,657 **** string_str(PyObject *s) { ! Py_INCREF(s); ! return s; } --- 663,676 ---- string_str(PyObject *s) { ! assert(PyString_Check(s)); ! if (PyString_CheckExact(s)) { ! Py_INCREF(s); ! return s; ! } ! else { ! /* Subtype -- return genuine string with the same value. */ ! PyStringObject *t = (PyStringObject *) s; ! return PyString_FromStringAndSize(t->ob_sval, t->ob_size); ! } } From gvanrossum@users.sourceforge.net Tue Oct 16 21:32:07 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 13:32:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ext newtypes.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ext In directory usw-pr-cvs1:/tmp/cvs-serv18927 Modified Files: newtypes.tex Log Message: Document required return values -1, 0, 1 for tp_compare handler, as suggested in SF patch #424475. Also document exception return. Index: newtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/newtypes.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** newtypes.tex 2001/09/26 22:26:45 1.3 --- newtypes.tex 2001/10/16 20:32:05 1.4 *************** *** 623,630 **** functions are used, or if \function{cmp()} is used from Python.) It is analogous to the \method{__cmp__()} method. This function ! should return a negative integer if \var{obj1} is less than ! \var{obj2}, \code{0} if they are equal, and a positive integer if \var{obj1} is greater than \var{obj2}. Here is a sample implementation: --- 623,639 ---- functions are used, or if \function{cmp()} is used from Python.) It is analogous to the \method{__cmp__()} method. This function ! should return \code{-1} if \var{obj1} is less than ! \var{obj2}, \code{0} if they are equal, and \code{1} if \var{obj1} is greater than \var{obj2}. + (It was previously allowed to return arbitrary negative or positive + integers for less than and greater than, respectively; as of Python + 2.2, this is no longer allowed. In the future, other return values + may be assigned a different meaning.) + + A \member{tp_compare} handler may raise an exception. In this case it + should return a negative value. The caller has to test for the + exception using \cfunction{PyErr_Occurred()}. + Here is a sample implementation: From jhylton@users.sourceforge.net Tue Oct 16 21:39:51 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 16 Oct 2001 13:39:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_zlib,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv21328/Lib/test/output Modified Files: test_zlib Log Message: [ #403753 ] zlib decompress; uncontrollable memory usage Mostly by Toby Dickenson and Titus Brown. Add an optional argument to a decompression object's decompress() method. The argument specifies the maximum length of the return value. If the uncompressed data exceeds this length, the excess data is stored as the unconsumed_tail attribute. (Not to be confused with unused_data, which is a separate issue.) Difference from SF patch: Default value for unconsumed_tail is "" rather than None. It's simpler if the attribute is always a string. Index: test_zlib =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_zlib,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_zlib 2001/02/21 02:17:01 1.4 --- test_zlib 2001/10/16 20:39:49 1.5 *************** *** 9,11 **** --- 9,14 ---- decompress with init options succeeded decompressobj with init options succeeded + should be '': '' + max_length decompressobj succeeded + unconsumed_tail should be '': '' Testing on 17K of random data From jhylton@users.sourceforge.net Tue Oct 16 21:39:51 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 16 Oct 2001 13:39:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_zlib.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21328/Lib/test Modified Files: test_zlib.py Log Message: [ #403753 ] zlib decompress; uncontrollable memory usage Mostly by Toby Dickenson and Titus Brown. Add an optional argument to a decompression object's decompress() method. The argument specifies the maximum length of the return value. If the uncompressed data exceeds this length, the excess data is stored as the unconsumed_tail attribute. (Not to be confused with unused_data, which is a separate issue.) Difference from SF patch: Default value for unconsumed_tail is "" rather than None. It's simpler if the attribute is always a string. Index: test_zlib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_zlib.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** test_zlib.py 2001/08/10 15:50:11 1.14 --- test_zlib.py 2001/10/16 20:39:49 1.15 *************** *** 77,80 **** --- 77,110 ---- print "decompressobj with init options succeeded" + print "should be '':", `deco.unconsumed_tail` + + # Check a decompression object with max_length specified + deco = zlib.decompressobj(-12) + cb = combuf + bufs = [] + while cb: + max_length = 1 + len(cb)/10 + chunk = deco.decompress(cb, max_length) + if len(chunk) > max_length: + print 'chunk too big (%d>%d)' % (len(chunk),max_length) + bufs.append(chunk) + cb = deco.unconsumed_tail + bufs.append(deco.flush()) + decomp2 = ''.join(buf) + if decomp2 != buf: + print "max_length decompressobj failed" + else: + print "max_length decompressobj succeeded" + + # Misc tests of max_length + deco = zlib.decompressobj(-12) + try: + deco.decompress("", -1) + except ValueError: + pass + else: + print "failed to raise value error on bad max_length" + print "unconsumed_tail should be '':", `deco.unconsumed_tail` + # Test flush() with the various options, using all the different levels # in order to provide more variations. From jhylton@users.sourceforge.net Tue Oct 16 21:39:51 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 16 Oct 2001 13:39:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libzlib.tex,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv21328/Doc/lib Modified Files: libzlib.tex Log Message: [ #403753 ] zlib decompress; uncontrollable memory usage Mostly by Toby Dickenson and Titus Brown. Add an optional argument to a decompression object's decompress() method. The argument specifies the maximum length of the return value. If the uncompressed data exceeds this length, the excess data is stored as the unconsumed_tail attribute. (Not to be confused with unused_data, which is a separate issue.) Difference from SF patch: Default value for unconsumed_tail is "" rather than None. It's simpler if the attribute is always a string. Index: libzlib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libzlib.tex,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** libzlib.tex 2001/10/15 13:45:49 1.26 --- libzlib.tex 2001/10/16 20:39:49 1.27 *************** *** 121,125 **** \end{methoddesc} ! Decompression objects support the following methods, and a single attribute: \begin{memberdesc}{unused_data} --- 121,125 ---- \end{methoddesc} ! Decompression objects support the following methods, and two attributes: \begin{memberdesc}{unused_data} *************** *** 136,140 **** \end{memberdesc} ! \begin{methoddesc}[Decompress]{decompress}{string} Decompress \var{string}, returning a string containing the uncompressed data corresponding to at least part of the data in --- 136,146 ---- \end{memberdesc} ! \begin{memberdesc}{unconsumed_tail} ! A string that contains any data that was not consumed by the last ! \method{decompress} call because it exceeded the limit for the ! uncompressed data buffer. ! \end{memberdesc} ! ! \begin{methoddesc}[Decompress]{decompress}{string}{\optional{max_length}} Decompress \var{string}, returning a string containing the uncompressed data corresponding to at least part of the data in *************** *** 143,146 **** --- 149,160 ---- \method{decompress()} method. Some of the input data may be preserved in internal buffers for later processing. + + If the optional parameter \var{max_length} is supplied then the return value + will be no longer than \var{max_length}. This may mean that not all of the + compressed input can be processed; and unconsumed data will be stored + in the attribute \member{unconsumed_tail}. This string must be passed + to a subsequent call to \method{decompress()} if decompression is to + continue. If \var{max_length} is not supplied then the whole input is + decompressed, and \member{unconsumed_tail} is an empty string. \end{methoddesc} From jhylton@users.sourceforge.net Tue Oct 16 21:39:51 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 16 Oct 2001 13:39:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules zlibmodule.c,2.43,2.44 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv21328/Modules Modified Files: zlibmodule.c Log Message: [ #403753 ] zlib decompress; uncontrollable memory usage Mostly by Toby Dickenson and Titus Brown. Add an optional argument to a decompression object's decompress() method. The argument specifies the maximum length of the return value. If the uncompressed data exceeds this length, the excess data is stored as the unconsumed_tail attribute. (Not to be confused with unused_data, which is a separate issue.) Difference from SF patch: Default value for unconsumed_tail is "" rather than None. It's simpler if the attribute is always a string. Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.43 retrieving revision 2.44 diff -C2 -d -r2.43 -r2.44 *** zlibmodule.c 2001/10/09 10:54:31 2.43 --- zlibmodule.c 2001/10/16 20:39:49 2.44 *************** *** 79,82 **** --- 79,83 ---- z_stream zst; PyObject *unused_data; + PyObject *unconsumed_tail; int is_initialised; } compobject; *************** *** 101,104 **** --- 102,114 ---- self->is_initialised = 0; self->unused_data = PyString_FromString(""); + if (self->unused_data == NULL) { + Py_DECREF(self); + return NULL; + } + self->unconsumed_tail = PyString_FromString(""); + if (self->unconsumed_tail == NULL) { + Py_DECREF(self); + return NULL; + } return self; } *************** *** 486,489 **** --- 496,500 ---- deflateEnd(&self->zst); Py_XDECREF(self->unused_data); + Py_XDECREF(self->unconsumed_tail); PyObject_Del(self); *************** *** 499,502 **** --- 510,514 ---- inflateEnd(&self->zst); Py_XDECREF(self->unused_data); + Py_XDECREF(self->unconsumed_tail); PyObject_Del(self); *************** *** 596,603 **** static char decomp_decompress__doc__[] = ! "decompress(data) -- Return a string containing the decompressed version of the data.\n\n" "After calling this function, some of the input data may still\n" "be stored in internal buffers for later processing.\n" ! "Call the flush() method to clear these buffers." ; --- 608,619 ---- static char decomp_decompress__doc__[] = ! "decompress(data, max_length) -- Return a string containing\n" ! "the decompressed version of the data.\n\n" "After calling this function, some of the input data may still\n" "be stored in internal buffers for later processing.\n" ! "Call the flush() method to clear these buffers.\n" ! "If the max_length parameter is specified then the return value will be\n" ! "no longer than max_length. Unconsumed input data will be stored in\n" ! "the unconsumed_tail attribute." ; *************** *** 605,609 **** PyZlib_objdecompress(compobject *self, PyObject *args) { ! int err, inplen, length = DEFAULTALLOC; PyObject *RetVal; Byte *input; --- 621,626 ---- PyZlib_objdecompress(compobject *self, PyObject *args) { ! int err, inplen, old_length, length = DEFAULTALLOC; ! int max_length = 0; PyObject *RetVal; Byte *input; *************** *** 612,620 **** PyObject * inputString; ! if (!PyArg_ParseTuple(args, "S:decompress", &inputString)) return NULL; if (PyString_AsStringAndSize(inputString, (char**)&input, &inplen) == -1) return NULL; if (!(RetVal = PyString_FromStringAndSize(NULL, length))) { PyErr_SetString(PyExc_MemoryError, --- 629,646 ---- PyObject * inputString; ! if (!PyArg_ParseTuple(args, "S|i:decompress", &inputString, &max_length)) ! return NULL; ! if (max_length < 0) { ! PyErr_SetString(PyExc_ValueError, ! "max_length must be greater than zero"); return NULL; + } + if (PyString_AsStringAndSize(inputString, (char**)&input, &inplen) == -1) return NULL; + /* limit amount of data allocated to max_length */ + if (max_length && length > max_length) + length = max_length; if (!(RetVal = PyString_FromStringAndSize(NULL, length))) { PyErr_SetString(PyExc_MemoryError, *************** *** 638,645 **** Py_END_ALLOW_THREADS ! /* while Z_OK and the output buffer is full, there might be more output, ! so extend the output buffer and try again */ while (err == Z_OK && self->zst.avail_out == 0) { ! if (_PyString_Resize(&RetVal, length << 1) == -1) { PyErr_SetString(PyExc_MemoryError, "Can't allocate memory to compress data"); --- 664,684 ---- Py_END_ALLOW_THREADS ! /* While Z_OK and the output buffer is full, there might be more output. ! So extend the output buffer and try again. ! */ while (err == Z_OK && self->zst.avail_out == 0) { ! /* If max_length set, don't continue decompressing if we've already ! reached the limit. ! */ ! if (max_length && length >= max_length) ! break; ! ! /* otherwise, ... */ ! old_length = length; ! length = length << 1; ! if (max_length && length > max_length) ! length = max_length; ! ! if (_PyString_Resize(&RetVal, length) == -1) { PyErr_SetString(PyExc_MemoryError, "Can't allocate memory to compress data"); *************** *** 647,653 **** break; } ! self->zst.next_out = (unsigned char *)PyString_AsString(RetVal) + length; ! self->zst.avail_out = length; ! length = length << 1; Py_BEGIN_ALLOW_THREADS err = inflate(&(self->zst), Z_SYNC_FLUSH); --- 686,692 ---- break; } ! self->zst.next_out = (unsigned char *)PyString_AsString(RetVal)+old_length; ! self->zst.avail_out = length - old_length; ! Py_BEGIN_ALLOW_THREADS err = inflate(&(self->zst), Z_SYNC_FLUSH); *************** *** 655,658 **** --- 694,707 ---- } + /* Not all of the compressed data could be accomodated in the output buffer + of specified size. Return the unconsumed tail in an attribute.*/ + if(max_length) { + Py_DECREF(self->unconsumed_tail); + self->unconsumed_tail = PyString_FromStringAndSize(self->zst.next_in, + self->zst.avail_in); + if(!self->unconsumed_tail) + return_error = 1; + } + /* The end of the compressed data has been reached, so set the unused_data attribute to a string containing the remainder of the data in the string. *************** *** 885,888 **** --- 934,942 ---- Py_INCREF(self->unused_data); retval = self->unused_data; + } + else if (strcmp(name, "unconsumed_tail") == 0) + { + Py_INCREF(self->unconsumed_tail); + retval = self->unconsumed_tail; } else From jhylton@users.sourceforge.net Tue Oct 16 21:42:55 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 16 Oct 2001 13:42:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.278,1.279 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv22570 Modified Files: NEWS Log Message: Add note about new zlib feature. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.278 retrieving revision 1.279 diff -C2 -d -r1.278 -r1.279 *** NEWS 2001/10/16 00:46:57 1.278 --- NEWS 2001/10/16 20:42:52 1.279 *************** *** 71,75 **** - quopri's encode and decode methods take an optional header parameter, ! which indicates whether output is intended for the header 'Q' encoding. Tools/Demos --- 71,80 ---- - quopri's encode and decode methods take an optional header parameter, ! which indicates whether output is intended for the header 'Q' ! encoding. ! ! - Decompression objects in the zlib module now accept an optional ! second parameter to decompress() that specifies the maximum amount ! of memory to use for the uncompressed data. Tools/Demos From gvanrossum@users.sourceforge.net Tue Oct 16 22:13:51 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 14:13:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libthread.tex,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv29764/Doc/lib Modified Files: libthread.tex Log Message: Partial patch from SF #452266, by Jason Petrone. This changes Pythread_start_thread() to return the thread ID, or -1 for an error. (It's technically an incompatible API change, but I doubt anyone calls it.) Index: libthread.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libthread.tex,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** libthread.tex 2000/04/05 15:00:38 1.22 --- libthread.tex 2001/10/16 21:13:49 1.23 *************** *** 33,41 **** \begin{funcdesc}{start_new_thread}{function, args\optional{, kwargs}} ! Start a new thread. The thread executes the function \var{function} ! with the argument list \var{args} (which must be a tuple). The ! optional \var{kwargs} argument specifies a dictionary of keyword ! arguments. When the ! function returns, the thread silently exits. When the function terminates with an unhandled exception, a stack trace is printed and then the thread exits (but other threads continue to run). --- 33,40 ---- \begin{funcdesc}{start_new_thread}{function, args\optional{, kwargs}} ! Start a new thread and return its identifier. The thread executes the function ! \var{function} with the argument list \var{args} (which must be a tuple). The ! optional \var{kwargs} argument specifies a dictionary of keyword arguments. ! When the function returns, the thread silently exits. When the function terminates with an unhandled exception, a stack trace is printed and then the thread exits (but other threads continue to run). From gvanrossum@users.sourceforge.net Tue Oct 16 22:13:51 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 14:13:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.279,1.280 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv29764/Misc Modified Files: NEWS Log Message: Partial patch from SF #452266, by Jason Petrone. This changes Pythread_start_thread() to return the thread ID, or -1 for an error. (It's technically an incompatible API change, but I doubt anyone calls it.) Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.279 retrieving revision 1.280 diff -C2 -d -r1.279 -r1.280 *** NEWS 2001/10/16 20:42:52 1.279 --- NEWS 2001/10/16 21:13:49 1.280 *************** *** 40,43 **** --- 40,45 ---- Library + - thread.start_new_thread() now returns the thread ID (previously None). + - doctest now excludes functions and classes not defined by the module being tested, thanks to Tim Hochberg. *************** *** 91,94 **** --- 93,103 ---- Consequently, PyArg_ParseTuple's 'L' code also accepts int (as well as long) arguments. + + - PyThread_start_new_thread() now returns a long int giving the thread + ID, if one can be calculated; it returns -1 for error, 0 if no + thread ID is calculated (this is an incompatible change, but only + the thread module used this API). This code has only really been + tested on Linux and Windows; other platforms please beware (and + report any bugs or strange behavior). New platforms From gvanrossum@users.sourceforge.net Tue Oct 16 22:13:51 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 14:13:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include pythread.h,2.17,2.18 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv29764/Include Modified Files: pythread.h Log Message: Partial patch from SF #452266, by Jason Petrone. This changes Pythread_start_thread() to return the thread ID, or -1 for an error. (It's technically an incompatible API change, but I doubt anyone calls it.) Index: pythread.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pythread.h,v retrieving revision 2.17 retrieving revision 2.18 diff -C2 -d -r2.17 -r2.18 *** pythread.h 2000/09/01 23:29:26 2.17 --- pythread.h 2001/10/16 21:13:49 2.18 *************** *** 14,18 **** DL_IMPORT(void) PyThread_init_thread(void); ! DL_IMPORT(int) PyThread_start_new_thread(void (*)(void *), void *); DL_IMPORT(void) PyThread_exit_thread(void); DL_IMPORT(void) PyThread__PyThread_exit_thread(void); --- 14,18 ---- DL_IMPORT(void) PyThread_init_thread(void); ! DL_IMPORT(long) PyThread_start_new_thread(void (*)(void *), void *); DL_IMPORT(void) PyThread_exit_thread(void); DL_IMPORT(void) PyThread__PyThread_exit_thread(void); From gvanrossum@users.sourceforge.net Tue Oct 16 22:13:51 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 14:13:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules threadmodule.c,2.42,2.43 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv29764/Modules Modified Files: threadmodule.c Log Message: Partial patch from SF #452266, by Jason Petrone. This changes Pythread_start_thread() to return the thread ID, or -1 for an error. (It's technically an incompatible API change, but I doubt anyone calls it.) Index: threadmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/threadmodule.c,v retrieving revision 2.42 retrieving revision 2.43 diff -C2 -d -r2.42 -r2.43 *** threadmodule.c 2001/10/05 12:24:15 2.42 --- threadmodule.c 2001/10/16 21:13:49 2.43 *************** *** 214,217 **** --- 214,218 ---- PyObject *func, *args, *keyw = NULL; struct bootstate *boot; + long ident; if (!PyArg_ParseTuple(fargs, "OO|O:start_new_thread", &func, &args, &keyw)) *************** *** 243,247 **** Py_XINCREF(keyw); PyEval_InitThreads(); /* Start the interpreter's thread-awareness */ ! if (!PyThread_start_new_thread(t_bootstrap, (void*) boot)) { PyErr_SetString(ThreadError, "can't start new thread\n"); Py_DECREF(func); --- 244,249 ---- Py_XINCREF(keyw); PyEval_InitThreads(); /* Start the interpreter's thread-awareness */ ! ident = PyThread_start_new_thread(t_bootstrap, (void*) boot); ! if (ident == -1) { PyErr_SetString(ThreadError, "can't start new thread\n"); Py_DECREF(func); *************** *** 251,256 **** return NULL; } ! Py_INCREF(Py_None); ! return Py_None; } --- 253,257 ---- return NULL; } ! return PyInt_FromLong(ident); } *************** *** 259,268 **** (start_new() is an obsolete synonym)\n\ \n\ ! Start a new thread. The thread will call the function with positional\n\ ! arguments from the tuple args and keyword arguments taken from the optional\n\ ! dictionary kwargs. The thread exits when the function returns; the return\n\ ! value is ignored. The thread will also exit when the function raises an\n\ ! unhandled exception; a stack trace will be printed unless the exception is\n\ ! SystemExit."; static PyObject * --- 260,269 ---- (start_new() is an obsolete synonym)\n\ \n\ ! Start a new thread and return its identifier. The thread will call the\n\ ! function with positional arguments from the tuple args and keyword arguments\n\ ! taken from the optional dictionary kwargs. The thread exits when the\n\ ! function returns; the return value is ignored. The thread will also exit\n\ ! when the function raises an unhandled exception; a stack trace will be\n\ ! printed unless the exception is SystemExit.\n"; static PyObject * From gvanrossum@users.sourceforge.net Tue Oct 16 22:13:51 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 14:13:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python thread.c,2.38,2.39 thread_beos.h,2.6,2.7 thread_cthread.h,2.14,2.15 thread_foobar.h,2.11,2.12 thread_lwp.h,2.14,2.15 thread_nt.h,2.18,2.19 thread_os2.h,2.10,2.11 thread_pth.h,2.7,2.8 thread_pthread.h,2.34,2.35 thread_sgi.h,2.14,2.15 thread_solaris.h,2.15,2.16 thread_wince.h,2.6,2.7 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv29764/Python Modified Files: thread.c thread_beos.h thread_cthread.h thread_foobar.h thread_lwp.h thread_nt.h thread_os2.h thread_pth.h thread_pthread.h thread_sgi.h thread_solaris.h thread_wince.h Log Message: Partial patch from SF #452266, by Jason Petrone. This changes Pythread_start_thread() to return the thread ID, or -1 for an error. (It's technically an incompatible API change, but I doubt anyone calls it.) Index: thread.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread.c,v retrieving revision 2.38 retrieving revision 2.39 diff -C2 -d -r2.38 -r2.39 *** thread.c 2001/07/26 21:34:59 2.38 --- thread.c 2001/10/16 21:13:49 2.39 *************** *** 112,116 **** #ifdef HAVE_PTH #include "thread_pth.h" - #undef _POSIX_THREADS #endif --- 112,115 ---- Index: thread_beos.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_beos.h,v retrieving revision 2.6 retrieving revision 2.7 diff -C2 -d -r2.6 -r2.7 *** thread_beos.h 2000/09/01 23:29:28 2.6 --- thread_beos.h 2001/10/16 21:13:49 2.7 *************** *** 113,117 **** static int32 thread_count = 0; ! int PyThread_start_new_thread( void (*func)(void *), void *arg ) { status_t success = 0; --- 113,117 ---- static int32 thread_count = 0; ! long PyThread_start_new_thread( void (*func)(void *), void *arg ) { status_t success = 0; *************** *** 132,136 **** } ! return ( success == B_NO_ERROR ? 1 : 0 ); } --- 132,136 ---- } ! return ( success == B_NO_ERROR ? tid : -1 ); } Index: thread_cthread.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_cthread.h,v retrieving revision 2.14 retrieving revision 2.15 diff -C2 -d -r2.14 -r2.15 *** thread_cthread.h 2000/11/13 19:45:45 2.14 --- thread_cthread.h 2001/10/16 21:13:49 2.15 *************** *** 15,19 **** * Thread support. */ ! int PyThread_start_new_thread(void (*func)(void *), void *arg) { --- 15,19 ---- * Thread support. */ ! long PyThread_start_new_thread(void (*func)(void *), void *arg) { *************** *** 28,32 **** */ cthread_detach(cthread_fork((cthread_fn_t) func, arg)); ! return success < 0 ? 0 : 1; } --- 28,32 ---- */ cthread_detach(cthread_fork((cthread_fn_t) func, arg)); ! return success < 0 ? -1 : 0; } Index: thread_foobar.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_foobar.h,v retrieving revision 2.11 retrieving revision 2.12 diff -C2 -d -r2.11 -r2.12 *** thread_foobar.h 2000/09/01 23:29:28 2.11 --- thread_foobar.h 2001/10/16 21:13:49 2.12 *************** *** 11,15 **** * Thread support. */ ! int PyThread_start_new_thread(void (*func)(void *), void *arg) { --- 11,15 ---- * Thread support. */ ! long PyThread_start_new_thread(void (*func)(void *), void *arg) { *************** *** 20,24 **** if (!initialized) PyThread_init_thread(); ! return success < 0 ? 0 : 1; } --- 20,24 ---- if (!initialized) PyThread_init_thread(); ! return success < 0 ? -1 : 0; } Index: thread_lwp.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_lwp.h,v retrieving revision 2.14 retrieving revision 2.15 diff -C2 -d -r2.14 -r2.15 *** thread_lwp.h 2000/09/01 23:29:28 2.14 --- thread_lwp.h 2001/10/16 21:13:49 2.15 *************** *** 27,31 **** ! int PyThread_start_new_thread(void (*func)(void *), void *arg) { thread_t tid; --- 27,31 ---- ! long PyThread_start_new_thread(void (*func)(void *), void *arg) { thread_t tid; *************** *** 35,39 **** PyThread_init_thread(); success = lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg); ! return success < 0 ? 0 : 1; } --- 35,39 ---- PyThread_init_thread(); success = lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg); ! return success < 0 ? -1 : 0; } Index: thread_nt.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_nt.h,v retrieving revision 2.18 retrieving revision 2.19 diff -C2 -d -r2.18 -r2.19 *** thread_nt.h 2001/08/29 21:37:10 2.18 --- thread_nt.h 2001/10/16 21:13:49 2.19 *************** *** 6,9 **** --- 6,10 ---- #include #include + #include typedef struct NRMUTEX { *************** *** 13,16 **** --- 14,19 ---- } NRMUTEX, *PNRMUTEX ; + /* dictionary to correlate thread ids with the handle needed to terminate them*/ + static PyObject *threads = NULL; typedef PVOID WINAPI interlocked_cmp_xchg_t(PVOID *dest, PVOID exc, PVOID comperand) ; *************** *** 146,149 **** --- 149,153 ---- static void PyThread__init_thread(void) { + threads = PyDict_New(); } *************** *** 151,158 **** * Thread support. */ ! int PyThread_start_new_thread(void (*func)(void *), void *arg) { unsigned long rv; int success = 0; dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident())); --- 155,187 ---- * Thread support. */ ! ! typedef struct { ! void (*func)(void*); ! void *arg; ! long id; ! HANDLE done; ! } callobj; ! ! static int ! bootstrap(void *call) ! { ! callobj *obj = (callobj*)call; ! /* copy callobj since other thread might free it before we're done */ ! void (*func)(void*) = obj->func; ! void *arg = obj->arg; ! ! obj->id = PyThread_get_thread_ident(); ! ReleaseSemaphore(obj->done, 1, NULL); ! func(arg); ! return 0; ! } ! ! long PyThread_start_new_thread(void (*func)(void *), void *arg) { unsigned long rv; int success = 0; + callobj *obj; + int id; + PyObject *key, *val; dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident())); *************** *** 160,164 **** PyThread_init_thread(); ! rv = _beginthread(func, 0, arg); /* use default stack size */ if (rv != (unsigned long)-1) { --- 189,198 ---- PyThread_init_thread(); ! obj = malloc(sizeof(callobj)); ! obj->func = func; ! obj->arg = arg; ! obj->done = CreateSemaphore(NULL, 0, 1, NULL); ! ! rv = _beginthread(func, 0, obj); /* use default stack size */ if (rv != (unsigned long)-1) { *************** *** 167,171 **** } ! return success; } --- 201,213 ---- } ! /* wait for thread to initialize and retrieve id */ ! WaitForSingleObject(obj->done, 5000); /* maybe INFINITE instead of 5000? */ ! CloseHandle((HANDLE)obj->done); ! key = PyLong_FromLong(obj->id); ! val = PyLong_FromLong((long)rv); ! PyDict_SetItem(threads, key, val); ! id = obj->id; ! free(obj); ! return id; } Index: thread_os2.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_os2.h,v retrieving revision 2.10 retrieving revision 2.11 diff -C2 -d -r2.10 -r2.11 *** thread_os2.h 2000/09/01 23:29:28 2.10 --- thread_os2.h 2001/10/16 21:13:49 2.11 *************** *** 22,35 **** * Thread support. */ ! int PyThread_start_new_thread(void (*func)(void *), void *arg) { int aThread; ! int success = 1; aThread = _beginthread(func,NULL,65536,arg); if( aThread == -1 ) { ! success = 0; fprintf(stderr,"aThread failed == %d",aThread); dprintf(("_beginthread failed. return %ld\n", errno)); --- 22,35 ---- * Thread support. */ ! long PyThread_start_new_thread(void (*func)(void *), void *arg) { int aThread; ! int success = 0; aThread = _beginthread(func,NULL,65536,arg); if( aThread == -1 ) { ! success = -1; fprintf(stderr,"aThread failed == %d",aThread); dprintf(("_beginthread failed. return %ld\n", errno)); Index: thread_pth.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_pth.h,v retrieving revision 2.7 retrieving revision 2.8 diff -C2 -d -r2.7 -r2.8 *** thread_pth.h 2000/10/12 20:58:32 2.7 --- thread_pth.h 2001/10/16 21:13:49 2.8 *************** *** 45,49 **** ! int PyThread_start_new_thread(void (*func)(void *), void *arg) { pth_t th; --- 45,49 ---- ! long PyThread_start_new_thread(void (*func)(void *), void *arg) { pth_t th; *************** *** 57,61 **** ); ! return th == NULL ? 0 : 1; } --- 57,61 ---- ); ! return th; } Index: thread_pthread.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_pthread.h,v retrieving revision 2.34 retrieving revision 2.35 diff -C2 -d -r2.34 -r2.35 *** thread_pthread.h 2001/10/15 14:34:42 2.34 --- thread_pthread.h 2001/10/16 21:13:49 2.35 *************** *** 144,148 **** ! int PyThread_start_new_thread(void (*func)(void *), void *arg) { --- 144,148 ---- ! long PyThread_start_new_thread(void (*func)(void *), void *arg) { *************** *** 211,215 **** #endif } ! return success != 0 ? 0 : 1; } --- 211,219 ---- #endif } ! #if SIZEOF_PTHREAD_T <= SIZEOF_LONG ! return (long) th; ! #else ! return (long) *(long *) &th; ! #endif } Index: thread_sgi.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_sgi.h,v retrieving revision 2.14 retrieving revision 2.15 diff -C2 -d -r2.14 -r2.15 *** thread_sgi.h 2000/09/01 23:29:29 2.14 --- thread_sgi.h 2001/10/16 21:13:49 2.15 *************** *** 169,173 **** } ! int PyThread_start_new_thread(void (*func)(void *), void *arg) { #ifdef USE_DL --- 169,173 ---- } ! long PyThread_start_new_thread(void (*func)(void *), void *arg) { #ifdef USE_DL *************** *** 224,228 **** if (usunsetlock(count_lock) < 0) perror("usunsetlock (count_lock)"); ! return success < 0 ? 0 : 1; } --- 224,228 ---- if (usunsetlock(count_lock) < 0) perror("usunsetlock (count_lock)"); ! return success; } Index: thread_solaris.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_solaris.h,v retrieving revision 2.15 retrieving revision 2.16 diff -C2 -d -r2.15 -r2.16 *** thread_solaris.h 2000/09/01 23:29:29 2.15 --- thread_solaris.h 2001/10/16 21:13:49 2.16 *************** *** 37,43 **** ! int PyThread_start_new_thread(void (*func)(void *), void *arg) { struct func_arg *funcarg; int success = 0; /* init not needed when SOLARIS_THREADS and */ --- 37,44 ---- ! long PyThread_start_new_thread(void (*func)(void *), void *arg) { + thread_t tid; struct func_arg *funcarg; int success = 0; /* init not needed when SOLARIS_THREADS and */ *************** *** 51,60 **** funcarg->arg = arg; if (thr_create(0, 0, new_func, funcarg, ! THR_DETACHED | THR_NEW_LWP, 0)) { perror("thr_create"); free((void *) funcarg); success = -1; } ! return success < 0 ? 0 : 1; } --- 52,61 ---- funcarg->arg = arg; if (thr_create(0, 0, new_func, funcarg, ! THR_DETACHED | THR_NEW_LWP, &tid)) { perror("thr_create"); free((void *) funcarg); success = -1; } ! return tid; } Index: thread_wince.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_wince.h,v retrieving revision 2.6 retrieving revision 2.7 diff -C2 -d -r2.6 -r2.7 *** thread_wince.h 2000/09/01 23:29:29 2.6 --- thread_wince.h 2001/10/16 21:13:49 2.7 *************** *** 23,30 **** * Thread support. */ ! int PyThread_start_new_thread(void (*func)(void *), void *arg) { long rv; ! int success = 0; dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident())); --- 23,30 ---- * Thread support. */ ! long PyThread_start_new_thread(void (*func)(void *), void *arg) { long rv; ! int success = -1; dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident())); *************** *** 35,39 **** if (rv != -1) { ! success = 1; dprintf(("%ld: PyThread_start_new_thread succeeded:\n", PyThread_get_thread_ident())); } --- 35,39 ---- if (rv != -1) { ! success = 0; dprintf(("%ld: PyThread_start_new_thread succeeded:\n", PyThread_get_thread_ident())); } From jhylton@users.sourceforge.net Tue Oct 16 22:19:47 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 16 Oct 2001 14:19:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules zlibmodule.c,2.44,2.45 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv311 Modified Files: zlibmodule.c Log Message: Reformat! Consistently indent 4 spaces. Use whitespace around operators. Put braces in the right places. Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.44 retrieving revision 2.45 diff -C2 -d -r2.44 -r2.45 *** zlibmodule.c 2001/10/16 20:39:49 2.44 --- zlibmodule.c 2001/10/16 21:19:45 2.45 *************** *** 76,84 **** typedef struct { ! PyObject_HEAD ! z_stream zst; ! PyObject *unused_data; ! PyObject *unconsumed_tail; ! int is_initialised; } compobject; --- 76,84 ---- [...1558 lines suppressed...] ! PyModule_AddIntConstant(m, "Z_DEFAULT_COMPRESSION", Z_DEFAULT_COMPRESSION); ! PyModule_AddIntConstant(m, "Z_FILTERED", Z_FILTERED); ! PyModule_AddIntConstant(m, "Z_HUFFMAN_ONLY", Z_HUFFMAN_ONLY); ! PyModule_AddIntConstant(m, "Z_DEFAULT_STRATEGY", Z_DEFAULT_STRATEGY); ! ! PyModule_AddIntConstant(m, "Z_FINISH", Z_FINISH); ! PyModule_AddIntConstant(m, "Z_NO_FLUSH", Z_NO_FLUSH); ! PyModule_AddIntConstant(m, "Z_SYNC_FLUSH", Z_SYNC_FLUSH); ! PyModule_AddIntConstant(m, "Z_FULL_FLUSH", Z_FULL_FLUSH); ! ! ver = PyString_FromString(ZLIB_VERSION); ! if (ver != NULL) { ! PyDict_SetItemString(d, "ZLIB_VERSION", ver); ! Py_DECREF(ver); ! } #ifdef WITH_THREAD ! zlib_lock = PyThread_allocate_lock(); #endif // WITH_THREAD } From jhylton@users.sourceforge.net Tue Oct 16 22:24:00 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 16 Oct 2001 14:24:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules zlibmodule.c,2.45,2.46 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv1353 Modified Files: zlibmodule.c Log Message: Remove many calls to set MemoryError exceptions. When PyString_FromStringAndSize() and _PyString_Resize() fail, they set an exception. There's no need to set a new exception. Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.45 retrieving revision 2.46 diff -C2 -d -r2.45 -r2.46 *** zlibmodule.c 2001/10/16 21:19:45 2.45 --- zlibmodule.c 2001/10/16 21:23:58 2.46 *************** *** 146,151 **** PyErr_SetString(PyExc_MemoryError, "Can't allocate memory to compress data"); - free(output); - return NULL; } --- 146,149 ---- *************** *** 267,275 **** zst.avail_out = r_strlen; ! if (!(result_str = PyString_FromStringAndSize(NULL, r_strlen))) { ! PyErr_SetString(PyExc_MemoryError, ! "Can't allocate memory to decompress data"); return NULL; - } /* Past the point of no return. From here on out, we need to make sure --- 265,270 ---- zst.avail_out = r_strlen; ! if (!(result_str = PyString_FromStringAndSize(NULL, r_strlen))) return NULL; /* Past the point of no return. From here on out, we need to make sure *************** *** 335,340 **** /* need more memory */ if (_PyString_Resize(&result_str, r_strlen << 1) == -1) { - PyErr_SetString(PyExc_MemoryError, - "Out of memory while decompressing data"); inflateEnd(&zst); result_str = NULL; --- 330,333 ---- *************** *** 529,537 **** return NULL; ! if (!(RetVal = PyString_FromStringAndSize(NULL, length))) { ! PyErr_SetString(PyExc_MemoryError, ! "Can't allocate memory to compress data"); return NULL; - } ENTER_ZLIB --- 522,527 ---- return NULL; ! if (!(RetVal = PyString_FromStringAndSize(NULL, length))) return NULL; ENTER_ZLIB *************** *** 555,560 **** while (err == Z_OK && self->zst.avail_out == 0) { if (_PyString_Resize(&RetVal, length << 1) == -1) { - PyErr_SetString(PyExc_MemoryError, - "Can't allocate memory to compress data"); return_error = 1; break; --- 545,548 ---- *************** *** 636,644 **** if (max_length && length > max_length) length = max_length; ! if (!(RetVal = PyString_FromStringAndSize(NULL, length))) { ! PyErr_SetString(PyExc_MemoryError, ! "Can't allocate memory to compress data"); return NULL; - } ENTER_ZLIB --- 624,629 ---- if (max_length && length > max_length) length = max_length; ! if (!(RetVal = PyString_FromStringAndSize(NULL, length))) return NULL; ENTER_ZLIB *************** *** 674,679 **** if (_PyString_Resize(&RetVal, length) == -1) { - PyErr_SetString(PyExc_MemoryError, - "Can't allocate memory to compress data"); return_error = 1; break; --- 659,662 ---- *************** *** 710,715 **** (char *)self->zst.next_in, self->zst.avail_in); if (self->unused_data == NULL) { - PyErr_SetString(PyExc_MemoryError, - "Can't allocate memory to unused_data"); Py_DECREF(RetVal); return_error = 1; --- 693,696 ---- *************** *** 770,778 **** } ! if (!(RetVal = PyString_FromStringAndSize(NULL, length))) { ! PyErr_SetString(PyExc_MemoryError, ! "Can't allocate memory to compress data"); return NULL; - } ENTER_ZLIB --- 751,756 ---- } ! if (!(RetVal = PyString_FromStringAndSize(NULL, length))) return NULL; ENTER_ZLIB *************** *** 793,798 **** while (err == Z_OK && self->zst.avail_out == 0) { if (_PyString_Resize(&RetVal, length << 1) == -1) { - PyErr_SetString(PyExc_MemoryError, - "Can't allocate memory to compress data"); return_error = 1; break; --- 771,774 ---- From gvanrossum@users.sourceforge.net Tue Oct 16 22:31:34 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 14:31:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.240,2.241 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv3352 Modified Files: bltinmodule.c Log Message: SF patch #471852 (anonymous) notes that getattr(obj, name, default) masks any exception, not just AttributeError. Fix this. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.240 retrieving revision 2.241 diff -C2 -d -r2.240 -r2.241 *** bltinmodule.c 2001/10/07 20:54:12 2.240 --- bltinmodule.c 2001/10/16 21:31:32 2.241 *************** *** 620,624 **** } result = PyObject_GetAttr(v, name); ! if (result == NULL && dflt != NULL) { PyErr_Clear(); Py_INCREF(dflt); --- 620,626 ---- } result = PyObject_GetAttr(v, name); ! if (result == NULL && dflt != NULL && ! PyErr_ExceptionMatches(PyExc_AttributeError)) ! { PyErr_Clear(); Py_INCREF(dflt); From gvanrossum@users.sourceforge.net Tue Oct 16 22:34:51 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 14:34:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.280,1.281 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv4132 Modified Files: NEWS Log Message: Add fix for getattr(obj, name, default). Rearrange a few things. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.280 retrieving revision 1.281 diff -C2 -d -r1.280 -r1.281 *** NEWS 2001/10/16 21:13:49 1.280 --- NEWS 2001/10/16 21:34:49 1.281 *************** *** 21,25 **** class methods, static methods, and properties. ! Core - A very subtle syntactical pitfall in list comprehensions was fixed. --- 21,25 ---- class methods, static methods, and properties. ! Core and builtins - A very subtle syntactical pitfall in list comprehensions was fixed. *************** *** 32,35 **** --- 32,44 ---- [] anyway, so it's not like any expressiveness is lost. + - getattr(obj, name, default) now only catches AttributeError, as + documented, rather than returning the default value for all + exceptions (which could mask bugs in a __getattr__ hook, for + example). + + Extension modules + + - thread.start_new_thread() now returns the thread ID (previously None). + - binascii has now two quopri support functions, a2b_qp and b2a_qp. *************** *** 38,44 **** - posix supports chroot where available. ! Library ! - thread.start_new_thread() now returns the thread ID (previously None). - doctest now excludes functions and classes not defined by the module --- 47,55 ---- - posix supports chroot where available. ! - Decompression objects in the zlib module now accept an optional ! second parameter to decompress() that specifies the maximum amount ! of memory to use for the uncompressed data. ! Library - doctest now excludes functions and classes not defined by the module *************** *** 75,82 **** which indicates whether output is intended for the header 'Q' encoding. - - - Decompression objects in the zlib module now accept an optional - second parameter to decompress() that specifies the maximum amount - of memory to use for the uncompressed data. Tools/Demos --- 86,89 ---- From gvanrossum@users.sourceforge.net Tue Oct 16 22:50:06 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 14:50:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python thread_nt.h,2.19,2.20 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv7928 Modified Files: thread_nt.h Log Message: Fix a bug in the previous checkin. The wrong bootstrap function was passed to _beginthread(). Index: thread_nt.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_nt.h,v retrieving revision 2.19 retrieving revision 2.20 diff -C2 -d -r2.19 -r2.20 *** thread_nt.h 2001/10/16 21:13:49 2.19 --- thread_nt.h 2001/10/16 21:50:04 2.20 *************** *** 194,198 **** obj->done = CreateSemaphore(NULL, 0, 1, NULL); ! rv = _beginthread(func, 0, obj); /* use default stack size */ if (rv != (unsigned long)-1) { --- 194,198 ---- obj->done = CreateSemaphore(NULL, 0, 1, NULL); ! rv = _beginthread(bootstrap, 0, obj); /* use default stack size */ if (rv != (unsigned long)-1) { From jhylton@users.sourceforge.net Tue Oct 16 22:56:11 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 16 Oct 2001 14:56:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules zlibmodule.c,2.46,2.47 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv9643 Modified Files: zlibmodule.c Log Message: Add zlib_error() helper. It sets a ZlibError exception, using the msg from the z_stream pointer if one is available. Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.46 retrieving revision 2.47 diff -C2 -d -r2.46 -r2.47 *** zlibmodule.c 2001/10/16 21:23:58 2.46 --- zlibmodule.c 2001/10/16 21:56:09 2.47 *************** *** 83,86 **** --- 83,95 ---- } compobject; + static void + zlib_error(z_stream zst, int err, char *msg) + { + if (zst.msg == Z_NULL) + PyErr_Format(ZlibError, "Error %d %s", err, msg); + else + PyErr_Format(ZlibError, "Error %d %s: %.200s", err, msg, zst.msg); + } + static char compressobj__doc__[] = "compressobj() -- Return a compressor object.\n" *************** *** 176,213 **** return_error = 1; break; ! default: { ! if (zst.msg == Z_NULL) ! PyErr_Format(ZlibError, "Error %i while compressing data", ! err); ! else ! PyErr_Format(ZlibError, "Error %i while compressing data: %.200s", ! err, zst.msg); deflateEnd(&zst); return_error = 1; - } } if (!return_error) { Py_BEGIN_ALLOW_THREADS; ! err=deflate(&zst, Z_FINISH); Py_END_ALLOW_THREADS; ! switch(err) ! { ! case(Z_STREAM_END): ! break; ! /* Are there other errors to be trapped here? */ ! default: { ! if (zst.msg == Z_NULL) ! PyErr_Format(ZlibError, "Error %i while compressing data", ! err); ! else ! PyErr_Format(ZlibError, "Error %i while compressing data: %.200s", ! err, zst.msg); ! deflateEnd(&zst); - return_error = 1; - } } --- 185,203 ---- return_error = 1; break; ! default: deflateEnd(&zst); + zlib_error(zst, err, "while compressing data"); return_error = 1; } if (!return_error) { Py_BEGIN_ALLOW_THREADS; ! err = deflate(&zst, Z_FINISH); Py_END_ALLOW_THREADS; ! if (err != Z_STREAM_END) { ! zlib_error(zst, err, "while compressing data"); deflateEnd(&zst); return_error = 1; } *************** *** 217,230 **** ReturnVal = PyString_FromStringAndSize((char *)output, zst.total_out); ! else { ! if (zst.msg == Z_NULL) ! PyErr_Format(ZlibError, ! "Error %i while finishing compression", ! err); ! else ! PyErr_Format(ZlibError, ! "Error %i while finishing compression: %.200s", ! err, zst.msg); ! } } } --- 207,212 ---- ReturnVal = PyString_FromStringAndSize((char *)output, zst.total_out); ! else ! zlib_error(zst, err, "while finishing compression"); } } *************** *** 287,302 **** "Out of memory while decompressing data"); return_error = 1; ! default: { ! if (zst.msg == Z_NULL) ! PyErr_Format(ZlibError, "Error %i preparing to decompress data", ! err); ! else ! PyErr_Format(ZlibError, ! "Error %i while preparing to decompress data: %.200s", ! err, zst.msg); inflateEnd(&zst); ! return_error = 1; - } } --- 269,276 ---- "Out of memory while decompressing data"); return_error = 1; ! default: inflateEnd(&zst); ! zlib_error(zst, err, "while preparing to decompress data"); return_error = 1; } *************** *** 318,323 **** * process the inflate call() due to an error in the data. */ ! if (zst.avail_out > 0) ! { PyErr_Format(ZlibError, "Error %i while decompressing data", err); --- 292,296 ---- * process the inflate call() due to an error in the data. */ ! if (zst.avail_out > 0) { PyErr_Format(ZlibError, "Error %i while decompressing data", err); *************** *** 339,353 **** r_strlen = r_strlen << 1; break; ! default: { ! if (zst.msg == Z_NULL) ! PyErr_Format(ZlibError, "Error %i while decompressing data", ! err); ! else ! PyErr_Format(ZlibError, ! "Error %i while decompressing data: %.200s", ! err, zst.msg); inflateEnd(&zst); return_error = 1; - } } } while (err != Z_STREAM_END); --- 312,319 ---- r_strlen = r_strlen << 1; break; ! default: inflateEnd(&zst); + zlib_error(zst, err, "while decompressing data"); return_error = 1; } } while (err != Z_STREAM_END); *************** *** 356,369 **** err = inflateEnd(&zst); if (err != Z_OK) { ! if (zst.msg == Z_NULL) ! PyErr_Format(ZlibError, ! "Error %i while finishing data decompression", ! err); ! else ! PyErr_Format(ZlibError, ! "Error %i while finishing data decompression: %.200s", ! err, zst.msg); ! ! return_error = 1; return NULL; } --- 322,326 ---- err = inflateEnd(&zst); if (err != Z_OK) { ! zlib_error(zst, err, "while finishing data decompression"); return NULL; } *************** *** 411,426 **** return NULL; default: ! { ! if (self->zst.msg == Z_NULL) ! PyErr_Format(ZlibError, ! "Error %i while creating compression object", ! err); ! else ! PyErr_Format(ZlibError, ! "Error %i while creating compression object: %.200s", ! err, self->zst.msg); Py_DECREF(self); return NULL; - } } } --- 368,374 ---- return NULL; default: ! zlib_error(self->zst, err, "while creating compression object"); Py_DECREF(self); return NULL; } } *************** *** 456,471 **** return NULL; default: ! { ! if (self->zst.msg == Z_NULL) ! PyErr_Format(ZlibError, ! "Error %i while creating decompression object", ! err); ! else ! PyErr_Format(ZlibError, ! "Error %i while creating decompression object: %.200s", ! err, self->zst.msg); Py_DECREF(self); return NULL; - } } } --- 404,410 ---- return NULL; default: ! zlib_error(self->zst, err, "while creating decompression object"); Py_DECREF(self); return NULL; } } *************** *** 852,862 **** err = inflateEnd(&(self->zst)); if (err != Z_OK) { ! if (self->zst.msg == Z_NULL) ! PyErr_Format(ZlibError, "Error %i from inflateEnd()", ! err); ! else ! PyErr_Format(ZlibError, "Error %i from inflateEnd(): %.200s", ! err, self->zst.msg); ! retval = NULL; } else { --- 791,795 ---- err = inflateEnd(&(self->zst)); if (err != Z_OK) { ! zlib_error(self->zst, err, "from inflateEnd()"); retval = NULL; } else { From jhylton@users.sourceforge.net Tue Oct 16 22:59:37 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 16 Oct 2001 14:59:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules zlibmodule.c,2.47,2.48 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv10519 Modified Files: zlibmodule.c Log Message: More reformatting. Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.47 retrieving revision 2.48 diff -C2 -d -r2.47 -r2.48 *** zlibmodule.c 2001/10/16 21:56:09 2.47 --- zlibmodule.c 2001/10/16 21:59:35 2.48 *************** *** 339,370 **** PyZlib_compressobj(PyObject *selfptr, PyObject *args) { ! compobject *self; ! int level=Z_DEFAULT_COMPRESSION, method=DEFLATED; ! int wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL, strategy=0, err; ! if (!PyArg_ParseTuple(args, "|iiiii:compressobj", &level, &method, &wbits, ! &memLevel, &strategy)) ! return NULL; ! self = newcompobject(&Comptype); ! if (self==NULL) return(NULL); ! self->zst.zalloc = (alloc_func)NULL; ! self->zst.zfree = (free_func)Z_NULL; ! err = deflateInit2(&self->zst, level, method, wbits, memLevel, strategy); ! switch(err) ! { case (Z_OK): ! self->is_initialised = 1; ! return (PyObject*)self; case (Z_MEM_ERROR): ! Py_DECREF(self); ! PyErr_SetString(PyExc_MemoryError, ! "Can't allocate memory for compression object"); ! return NULL; case(Z_STREAM_ERROR): ! Py_DECREF(self); ! PyErr_SetString(PyExc_ValueError, ! "Invalid initialization option"); ! return NULL; default: zlib_error(self->zst, err, "while creating compression object"); --- 339,370 ---- PyZlib_compressobj(PyObject *selfptr, PyObject *args) { ! compobject *self; ! int level=Z_DEFAULT_COMPRESSION, method=DEFLATED; ! int wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL, strategy=0, err; ! if (!PyArg_ParseTuple(args, "|iiiii:compressobj", &level, &method, &wbits, ! &memLevel, &strategy)) ! return NULL; ! self = newcompobject(&Comptype); ! if (self==NULL) ! return(NULL); ! self->zst.zalloc = (alloc_func)NULL; ! self->zst.zfree = (free_func)Z_NULL; ! err = deflateInit2(&self->zst, level, method, wbits, memLevel, strategy); ! switch(err) { case (Z_OK): ! self->is_initialised = 1; ! return (PyObject*)self; case (Z_MEM_ERROR): ! Py_DECREF(self); ! PyErr_SetString(PyExc_MemoryError, ! "Can't allocate memory for compression object"); ! return NULL; case(Z_STREAM_ERROR): ! Py_DECREF(self); ! PyErr_SetString(PyExc_ValueError, ! "Invalid initialization option"); ! return NULL; default: zlib_error(self->zst, err, "while creating compression object"); *************** *** 377,411 **** PyZlib_decompressobj(PyObject *selfptr, PyObject *args) { ! int wbits=DEF_WBITS, err; ! compobject *self; ! if (!PyArg_ParseTuple(args, "|i:decompressobj", &wbits)) ! { ! return NULL; ! } ! self=newcompobject(&Decomptype); ! if (self==NULL) return(NULL); ! self->zst.zalloc=(alloc_func)NULL; ! self->zst.zfree=(free_func)Z_NULL; ! err=inflateInit2(&self->zst, wbits); ! switch(err) ! { case (Z_OK): ! self->is_initialised = 1; ! return (PyObject*)self; case(Z_STREAM_ERROR): ! Py_DECREF(self); ! PyErr_SetString(PyExc_ValueError, ! "Invalid initialization option"); ! return NULL; case (Z_MEM_ERROR): ! Py_DECREF(self); ! PyErr_SetString(PyExc_MemoryError, ! "Can't allocate memory for decompression object"); ! return NULL; default: zlib_error(self->zst, err, "while creating decompression object"); Py_DECREF(self); return NULL; ! } } --- 377,410 ---- PyZlib_decompressobj(PyObject *selfptr, PyObject *args) { ! int wbits=DEF_WBITS, err; ! compobject *self; ! if (!PyArg_ParseTuple(args, "|i:decompressobj", &wbits)) ! return NULL; ! ! self = newcompobject(&Decomptype); ! if (self==NULL) ! return(NULL); ! self->zst.zalloc = (alloc_func)NULL; ! self->zst.zfree = (free_func)Z_NULL; ! err = inflateInit2(&self->zst, wbits); ! switch(err) { case (Z_OK): ! self->is_initialised = 1; ! return (PyObject*)self; case(Z_STREAM_ERROR): ! Py_DECREF(self); ! PyErr_SetString(PyExc_ValueError, ! "Invalid initialization option"); ! return NULL; case (Z_MEM_ERROR): ! Py_DECREF(self); ! PyErr_SetString(PyExc_MemoryError, ! "Can't allocate memory for decompression object"); ! return NULL; default: zlib_error(self->zst, err, "while creating decompression object"); Py_DECREF(self); return NULL; ! } } *************** *** 416,420 **** if (self->is_initialised) ! deflateEnd(&self->zst); Py_XDECREF(self->unused_data); Py_XDECREF(self->unconsumed_tail); --- 415,419 ---- if (self->is_initialised) ! deflateEnd(&self->zst); Py_XDECREF(self->unused_data); Py_XDECREF(self->unconsumed_tail); *************** *** 430,434 **** if (self->is_initialised) ! inflateEnd(&self->zst); Py_XDECREF(self->unused_data); Py_XDECREF(self->unconsumed_tail); --- 429,433 ---- if (self->is_initialised) ! inflateEnd(&self->zst); Py_XDECREF(self->unused_data); Py_XDECREF(self->unconsumed_tail); From tim_one@users.sourceforge.net Wed Oct 17 00:01:08 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 16 Oct 2001 16:01:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libinspect.tex,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv28057/python/Doc/lib Modified Files: libinspect.tex Log Message: SF bug [#471111] inspect.getframeinfo() needs docs. TeX-ified its docstring. Index: libinspect.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libinspect.tex,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** libinspect.tex 2001/09/22 06:10:55 1.5 --- libinspect.tex 2001/10/16 23:01:06 1.6 *************** *** 283,286 **** --- 283,292 ---- which occurs. + \begin{funcdesc}{getframeinfo}{frame\optional{, context}} + Get information about a frame or traceback object. A 5-tuple + is returned, the last five elements of the frame's frame record. + The optional second argument specifies the number of lines of context + to return, which are centered around the current line. + \begin{funcdesc}{getouterframes}{frame\optional{, context}} Get a list of frame records for a frame and all higher (calling) From jhylton@users.sourceforge.net Wed Oct 17 00:02:34 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 16 Oct 2001 16:02:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules zlibmodule.c,2.48,2.49 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv28392 Modified Files: zlibmodule.c Log Message: Simplify and fix error handling for most cases. Many functions used a local variable called return_error, which was initialized to zero. If an error occurred, it was set to true. Most of the code paths checked were only executed if return_error was false. goto is clearer. The code also seemed to be written under the curious assumption that calling Py_DECREF() on a local variable would assign the variable to NULL. As a result, more of the error-exit code paths returned an object that had a reference count of zero instead of just returning NULL. Fixed the code to explicitly assign NULL after the DECREF. A bit more reformatting, but not much. XXX Need a much better test suite for zlib, since it the current tests don't exercise any of this broken code. Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.48 retrieving revision 2.49 diff -C2 -d -r2.48 -r2.49 *** zlibmodule.c 2001/10/16 21:59:35 2.48 --- zlibmodule.c 2001/10/16 23:02:32 2.49 *************** *** 137,141 **** int length, level=Z_DEFAULT_COMPRESSION, err; z_stream zst; - int return_error; PyObject * inputString; --- 137,140 ---- *************** *** 150,156 **** zst.avail_out = length + length/1000 + 12 + 1; ! output=(Byte*)malloc(zst.avail_out); ! if (output==NULL) ! { PyErr_SetString(PyExc_MemoryError, "Can't allocate memory to compress data"); --- 149,154 ---- zst.avail_out = length + length/1000 + 12 + 1; ! output = (Byte*)malloc(zst.avail_out); ! if (output == NULL) { PyErr_SetString(PyExc_MemoryError, "Can't allocate memory to compress data"); *************** *** 163,176 **** Py_INCREF(inputString); /* increment so that we hold ref */ ! zst.zalloc=(alloc_func)NULL; ! zst.zfree=(free_func)Z_NULL; ! zst.next_out=(Byte *)output; ! zst.next_in =(Byte *)input; ! zst.avail_in=length; ! err=deflateInit(&zst, level); ! return_error = 0; ! switch(err) ! { case(Z_OK): break; --- 161,172 ---- Py_INCREF(inputString); /* increment so that we hold ref */ ! zst.zalloc = (alloc_func)NULL; ! zst.zfree = (free_func)Z_NULL; ! zst.next_out = (Byte *)output; ! zst.next_in = (Byte *)input; ! zst.avail_in = length; ! err = deflateInit(&zst, level); ! switch(err) { case(Z_OK): break; *************** *** 178,215 **** PyErr_SetString(PyExc_MemoryError, "Out of memory while compressing data"); ! return_error = 1; ! break; case(Z_STREAM_ERROR): PyErr_SetString(ZlibError, "Bad compression level"); ! return_error = 1; ! break; default: deflateEnd(&zst); zlib_error(zst, err, "while compressing data"); ! return_error = 1; } ! if (!return_error) { ! Py_BEGIN_ALLOW_THREADS; ! err = deflate(&zst, Z_FINISH); ! Py_END_ALLOW_THREADS; ! if (err != Z_STREAM_END) { ! zlib_error(zst, err, "while compressing data"); ! deflateEnd(&zst); ! return_error = 1; ! } ! ! if (!return_error) { ! err=deflateEnd(&zst); ! if (err == Z_OK) ! ReturnVal = PyString_FromStringAndSize((char *)output, ! zst.total_out); ! else ! zlib_error(zst, err, "while finishing compression"); ! } } free(output); Py_DECREF(inputString); --- 174,206 ---- PyErr_SetString(PyExc_MemoryError, "Out of memory while compressing data"); ! goto error; case(Z_STREAM_ERROR): PyErr_SetString(ZlibError, "Bad compression level"); ! goto error; default: deflateEnd(&zst); zlib_error(zst, err, "while compressing data"); ! goto error; } ! Py_BEGIN_ALLOW_THREADS; ! err = deflate(&zst, Z_FINISH); ! Py_END_ALLOW_THREADS; ! if (err != Z_STREAM_END) { ! zlib_error(zst, err, "while compressing data"); ! deflateEnd(&zst); ! goto error; } + + err=deflateEnd(&zst); + if (err == Z_OK) + ReturnVal = PyString_FromStringAndSize((char *)output, + zst.total_out); + else + zlib_error(zst, err, "while finishing compression"); + error: free(output); Py_DECREF(inputString); *************** *** 232,236 **** int wsize=DEF_WBITS, r_strlen=DEFAULTALLOC; z_stream zst; - int return_error; PyObject * inputString; --- 223,226 ---- *************** *** 261,265 **** err = inflateInit2(&zst, wsize); - return_error = 0; switch(err) { case(Z_OK): --- 251,254 ---- *************** *** 268,282 **** PyErr_SetString(PyExc_MemoryError, "Out of memory while decompressing data"); ! return_error = 1; default: inflateEnd(&zst); zlib_error(zst, err, "while preparing to decompress data"); ! return_error = 1; } do { - if (return_error) - break; - Py_BEGIN_ALLOW_THREADS err=inflate(&zst, Z_FINISH); --- 257,268 ---- PyErr_SetString(PyExc_MemoryError, "Out of memory while decompressing data"); ! goto error; default: inflateEnd(&zst); zlib_error(zst, err, "while preparing to decompress data"); ! goto error; } do { Py_BEGIN_ALLOW_THREADS err=inflate(&zst, Z_FINISH); *************** *** 296,301 **** err); inflateEnd(&zst); ! return_error = 1; ! break; } /* fall through */ --- 282,286 ---- err); inflateEnd(&zst); ! goto error; } /* fall through */ *************** *** 305,309 **** inflateEnd(&zst); result_str = NULL; ! return_error = 1; } zst.next_out = (unsigned char *)PyString_AsString(result_str) \ --- 290,294 ---- inflateEnd(&zst); result_str = NULL; ! goto error; } zst.next_out = (unsigned char *)PyString_AsString(result_str) \ *************** *** 315,337 **** inflateEnd(&zst); zlib_error(zst, err, "while decompressing data"); ! return_error = 1; } } while (err != Z_STREAM_END); ! if (!return_error) { ! err = inflateEnd(&zst); ! if (err != Z_OK) { ! zlib_error(zst, err, "while finishing data decompression"); ! return NULL; ! } } ! if (!return_error) ! _PyString_Resize(&result_str, zst.total_out); ! else ! Py_XDECREF(result_str); /* sets result_str == NULL, if not already */ Py_DECREF(inputString); - return result_str; } --- 300,321 ---- inflateEnd(&zst); zlib_error(zst, err, "while decompressing data"); ! goto error; } } while (err != Z_STREAM_END); ! err = inflateEnd(&zst); ! if (err != Z_OK) { ! zlib_error(zst, err, "while finishing data decompression"); ! return NULL; } ! _PyString_Resize(&result_str, zst.total_out); Py_DECREF(inputString); return result_str; + + error: + Py_DECREF(inputString); + Py_XDECREF(result_str); + return NULL; } *************** *** 364,369 **** case(Z_STREAM_ERROR): Py_DECREF(self); ! PyErr_SetString(PyExc_ValueError, ! "Invalid initialization option"); return NULL; default: --- 348,352 ---- case(Z_STREAM_ERROR): Py_DECREF(self); ! PyErr_SetString(PyExc_ValueError, "Invalid initialization option"); return NULL; default: *************** *** 383,387 **** self = newcompobject(&Decomptype); ! if (self==NULL) return(NULL); self->zst.zalloc = (alloc_func)NULL; --- 366,370 ---- self = newcompobject(&Decomptype); ! if (self == NULL) return(NULL); self->zst.zalloc = (alloc_func)NULL; *************** *** 394,399 **** case(Z_STREAM_ERROR): Py_DECREF(self); ! PyErr_SetString(PyExc_ValueError, ! "Invalid initialization option"); return NULL; case (Z_MEM_ERROR): --- 377,381 ---- case(Z_STREAM_ERROR): Py_DECREF(self); ! PyErr_SetString(PyExc_ValueError, "Invalid initialization option"); return NULL; case (Z_MEM_ERROR): *************** *** 452,460 **** Byte *input; unsigned long start_total_out; ! int return_error; ! PyObject * inputString; if (!PyArg_ParseTuple(args, "S:compress", &inputString)) return NULL; if (PyString_AsStringAndSize(inputString, (char**)&input, &inplen) == -1) return NULL; --- 434,442 ---- Byte *input; unsigned long start_total_out; ! PyObject *inputString; if (!PyArg_ParseTuple(args, "S:compress", &inputString)) return NULL; + if (PyString_AsStringAndSize(inputString, (char**)&input, &inplen) == -1) return NULL; *************** *** 477,488 **** Py_END_ALLOW_THREADS - return_error = 0; - /* while Z_OK and the output buffer is full, there might be more output, so extend the output buffer and try again */ while (err == Z_OK && self->zst.avail_out == 0) { ! if (_PyString_Resize(&RetVal, length << 1) == -1) { ! return_error = 1; ! break; } self->zst.next_out = (unsigned char *)PyString_AsString(RetVal) \ --- 459,468 ---- Py_END_ALLOW_THREADS /* while Z_OK and the output buffer is full, there might be more output, so extend the output buffer and try again */ while (err == Z_OK && self->zst.avail_out == 0) { ! if (_PyString_Resize(&RetVal, length << 1) == -1) { ! RetVal = NULL; ! goto error; } self->zst.next_out = (unsigned char *)PyString_AsString(RetVal) \ *************** *** 499,526 **** condition. */ - - if (!return_error) { - if (err != Z_OK && err != Z_BUF_ERROR) { - if (self->zst.msg == Z_NULL) - PyErr_Format(ZlibError, "Error %i while compressing", - err); - else - PyErr_Format(ZlibError, "Error %i while compressing: %.200s", - err, self->zst.msg); ! return_error = 1; ! Py_DECREF(RetVal); ! } } ! ! if (return_error) ! RetVal = NULL; /* should have been handled by DECREF */ ! else ! _PyString_Resize(&RetVal, self->zst.total_out - start_total_out); Py_DECREF(inputString); - LEAVE_ZLIB - return RetVal; } --- 479,496 ---- condition. */ ! if (err != Z_OK && err != Z_BUF_ERROR) { ! zlib_error(self->zst, err, "while compressing"); ! Py_DECREF(RetVal); ! RetVal = NULL; ! goto error; } ! if (_PyString_Resize(&RetVal, ! self->zst.total_out - start_total_out) < 0) ! RetVal = NULL; + error: Py_DECREF(inputString); LEAVE_ZLIB return RetVal; } *************** *** 545,549 **** Byte *input; unsigned long start_total_out; - int return_error; PyObject * inputString; --- 515,518 ---- *************** *** 566,570 **** ENTER_ZLIB - return_error = 0; Py_INCREF(inputString); --- 535,538 ---- *************** *** 597,602 **** if (_PyString_Resize(&RetVal, length) == -1) { ! return_error = 1; ! break; } self->zst.next_out = (unsigned char *)PyString_AsString(RetVal) \ --- 565,570 ---- if (_PyString_Resize(&RetVal, length) == -1) { ! RetVal = NULL; ! goto error; } self->zst.next_out = (unsigned char *)PyString_AsString(RetVal) \ *************** *** 615,620 **** self->unconsumed_tail = PyString_FromStringAndSize(self->zst.next_in, self->zst.avail_in); ! if(!self->unconsumed_tail) ! return_error = 1; } --- 583,591 ---- self->unconsumed_tail = PyString_FromStringAndSize(self->zst.next_in, self->zst.avail_in); ! if(!self->unconsumed_tail) { ! Py_DECREF(RetVal); ! RetVal = NULL; ! goto error; ! } } *************** *** 625,659 **** preserved. */ ! if (!return_error) { ! if (err == Z_STREAM_END) { ! Py_XDECREF(self->unused_data); /* Free original empty string */ ! self->unused_data = PyString_FromStringAndSize( ! (char *)self->zst.next_in, self->zst.avail_in); ! if (self->unused_data == NULL) { ! Py_DECREF(RetVal); ! return_error = 1; ! } ! /* We will only get Z_BUF_ERROR if the output buffer was full ! but there wasn't more output when we tried again, so it is ! not an error condition. ! */ ! } else if (err != Z_OK && err != Z_BUF_ERROR) { ! if (self->zst.msg == Z_NULL) ! PyErr_Format(ZlibError, "Error %i while decompressing", ! err); ! else ! PyErr_Format(ZlibError, "Error %i while decompressing: %.200s", ! err, self->zst.msg); Py_DECREF(RetVal); ! return_error = 1; } } ! if (!return_error) { ! _PyString_Resize(&RetVal, self->zst.total_out - start_total_out); ! } ! else ! RetVal = NULL; /* should be handled by DECREF */ Py_DECREF(inputString); --- 596,622 ---- preserved. */ ! if (err == Z_STREAM_END) { ! Py_XDECREF(self->unused_data); /* Free original empty string */ ! self->unused_data = PyString_FromStringAndSize( ! (char *)self->zst.next_in, self->zst.avail_in); ! if (self->unused_data == NULL) { Py_DECREF(RetVal); ! goto error; } + /* We will only get Z_BUF_ERROR if the output buffer was full + but there wasn't more output when we tried again, so it is + not an error condition. + */ + } else if (err != Z_OK && err != Z_BUF_ERROR) { + zlib_error(self->zst, err, "while decompressing"); + Py_DECREF(RetVal); + RetVal = NULL; + goto error; } ! if (_PyString_Resize(&RetVal, self->zst.total_out - start_total_out) < 0) ! RetVal = NULL; + error: Py_DECREF(inputString); *************** *** 678,682 **** int flushmode = Z_FINISH; unsigned long start_total_out; - int return_error; if (!PyArg_ParseTuple(args, "|i:flush", &flushmode)) --- 641,644 ---- *************** *** 703,714 **** Py_END_ALLOW_THREADS - return_error = 0; - /* while Z_OK and the output buffer is full, there might be more output, so extend the output buffer and try again */ while (err == Z_OK && self->zst.avail_out == 0) { if (_PyString_Resize(&RetVal, length << 1) == -1) { ! return_error = 1; ! break; } self->zst.next_out = (unsigned char *)PyString_AsString(RetVal) \ --- 665,674 ---- Py_END_ALLOW_THREADS /* while Z_OK and the output buffer is full, there might be more output, so extend the output buffer and try again */ while (err == Z_OK && self->zst.avail_out == 0) { if (_PyString_Resize(&RetVal, length << 1) == -1) { ! RetVal = NULL; ! goto error; } self->zst.next_out = (unsigned char *)PyString_AsString(RetVal) \ *************** *** 725,769 **** various data structures. Note we should only get Z_STREAM_END when flushmode is Z_FINISH, but checking both for safety*/ ! if (!return_error) { ! if (err == Z_STREAM_END && flushmode == Z_FINISH) { ! err = deflateEnd(&(self->zst)); ! if (err != Z_OK) { ! if (self->zst.msg == Z_NULL) ! PyErr_Format(ZlibError, "Error %i from deflateEnd()", ! err); ! else ! PyErr_Format(ZlibError, ! "Error %i from deflateEnd(): %.200s", ! err, self->zst.msg); ! ! Py_DECREF(RetVal); ! return_error = 1; ! } else ! self->is_initialised = 0; ! ! /* We will only get Z_BUF_ERROR if the output buffer was full ! but there wasn't more output when we tried again, so it is ! not an error condition. ! */ ! } else if (err!=Z_OK && err!=Z_BUF_ERROR) { ! if (self->zst.msg == Z_NULL) ! PyErr_Format(ZlibError, "Error %i while flushing", ! err); ! else ! PyErr_Format(ZlibError, "Error %i while flushing: %.200s", ! err, self->zst.msg); Py_DECREF(RetVal); ! return_error = 1; } } - - if (!return_error) - _PyString_Resize(&RetVal, self->zst.total_out - start_total_out); - else - RetVal = NULL; /* should have been handled by DECREF */ ! LEAVE_ZLIB ! return RetVal; } --- 685,716 ---- various data structures. Note we should only get Z_STREAM_END when flushmode is Z_FINISH, but checking both for safety*/ ! if (err == Z_STREAM_END && flushmode == Z_FINISH) { ! err = deflateEnd(&(self->zst)); ! if (err != Z_OK) { ! zlib_error(self->zst, err, "from deflateEnd()"); Py_DECREF(RetVal); ! RetVal = NULL; ! goto error; } + else + self->is_initialised = 0; + + /* We will only get Z_BUF_ERROR if the output buffer was full + but there wasn't more output when we tried again, so it is + not an error condition. + */ + } else if (err!=Z_OK && err!=Z_BUF_ERROR) { + zlib_error(self->zst, err, "while flushing"); + Py_DECREF(RetVal); + RetVal = NULL; } ! if (_PyString_Resize(&RetVal, self->zst.total_out - start_total_out) < 0) ! RetVal = NULL; ! error: ! LEAVE_ZLIB; ! ! return RetVal; } *************** *** 781,785 **** { int err; ! PyObject * retval; if (!PyArg_ParseTuple(args, "")) --- 728,732 ---- { int err; ! PyObject * retval = NULL; if (!PyArg_ParseTuple(args, "")) *************** *** 789,796 **** err = inflateEnd(&(self->zst)); ! if (err != Z_OK) { zlib_error(self->zst, err, "from inflateEnd()"); ! retval = NULL; ! } else { self->is_initialised = 0; retval = PyString_FromStringAndSize(NULL, 0); --- 736,742 ---- err = inflateEnd(&(self->zst)); ! if (err != Z_OK) zlib_error(self->zst, err, "from inflateEnd()"); ! else { self->is_initialised = 0; retval = PyString_FromStringAndSize(NULL, 0); From jhylton@users.sourceforge.net Wed Oct 17 00:26:11 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 16 Oct 2001 16:26:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules zlibmodule.c,2.49,2.50 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv672 Modified Files: zlibmodule.c Log Message: Undo needless INCREF chicanery introduced by SF patch #450702. Apparently this patch (rev 2.41) replaced all the good old "s#" formats in PyArg_ParseTuple() with "S". Then it did PyString_FromStringAndSize() to get back the values setup by the "s#" format. It also incref'd and decref'd the string obtained by "S" even though the argument tuple had a reference to it. Replace PyString_AsString() calls with PyString_AS_STRING(). A good rule of thumb -- if you never check the return value of PyString_AsString() to see if it's NULL, you ought to be using the macro . Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.49 retrieving revision 2.50 diff -C2 -d -r2.49 -r2.50 *** zlibmodule.c 2001/10/16 23:02:32 2.49 --- zlibmodule.c 2001/10/16 23:26:08 2.50 *************** *** 137,148 **** int length, level=Z_DEFAULT_COMPRESSION, err; z_stream zst; - PyObject * inputString; /* require Python string object, optional 'level' arg */ ! if (!PyArg_ParseTuple(args, "S|i:compress", &inputString, &level)) ! return NULL; ! ! /* now get a pointer to the internal string */ ! if (PyString_AsStringAndSize(inputString, (char**)&input, &length) == -1) return NULL; --- 137,143 ---- int length, level=Z_DEFAULT_COMPRESSION, err; z_stream zst; /* require Python string object, optional 'level' arg */ ! if (!PyArg_ParseTuple(args, "s#|i:compress", &input, &length, &level)) return NULL; *************** *** 159,164 **** we clean up mallocs & INCREFs. */ - Py_INCREF(inputString); /* increment so that we hold ref */ - zst.zalloc = (alloc_func)NULL; zst.zfree = (free_func)Z_NULL; --- 154,157 ---- *************** *** 204,208 **** error: free(output); - Py_DECREF(inputString); return ReturnVal; --- 197,200 ---- *************** *** 223,232 **** int wsize=DEF_WBITS, r_strlen=DEFAULTALLOC; z_stream zst; - PyObject * inputString; ! if (!PyArg_ParseTuple(args, "S|ii:decompress", ! &inputString, &wsize, &r_strlen)) ! return NULL; ! if (PyString_AsStringAndSize(inputString, (char**)&input, &length) == -1) return NULL; --- 215,221 ---- int wsize=DEF_WBITS, r_strlen=DEFAULTALLOC; z_stream zst; ! if (!PyArg_ParseTuple(args, "s#|ii:decompress", ! &input, &length, &wsize, &r_strlen)) return NULL; *************** *** 240,251 **** return NULL; - /* Past the point of no return. From here on out, we need to make sure - we clean up mallocs & INCREFs. */ - - Py_INCREF(inputString); /* increment so that we hold ref */ - zst.zalloc = (alloc_func)NULL; zst.zfree = (free_func)Z_NULL; ! zst.next_out = (Byte *)PyString_AsString(result_str); zst.next_in = (Byte *)input; err = inflateInit2(&zst, wsize); --- 229,235 ---- return NULL; zst.zalloc = (alloc_func)NULL; zst.zfree = (free_func)Z_NULL; ! zst.next_out = (Byte *)PyString_AS_STRING(result_str); zst.next_in = (Byte *)input; err = inflateInit2(&zst, wsize); *************** *** 292,296 **** goto error; } ! zst.next_out = (unsigned char *)PyString_AsString(result_str) \ + r_strlen; zst.avail_out = r_strlen; --- 276,280 ---- goto error; } ! zst.next_out = (unsigned char *)PyString_AS_STRING(result_str) \ + r_strlen; zst.avail_out = r_strlen; *************** *** 307,319 **** if (err != Z_OK) { zlib_error(zst, err, "while finishing data decompression"); ! return NULL; } _PyString_Resize(&result_str, zst.total_out); - Py_DECREF(inputString); return result_str; error: - Py_DECREF(inputString); Py_XDECREF(result_str); return NULL; --- 291,301 ---- if (err != Z_OK) { zlib_error(zst, err, "while finishing data decompression"); ! goto error; } _PyString_Resize(&result_str, zst.total_out); return result_str; error: Py_XDECREF(result_str); return NULL; *************** *** 434,443 **** Byte *input; unsigned long start_total_out; - PyObject *inputString; ! if (!PyArg_ParseTuple(args, "S:compress", &inputString)) ! return NULL; ! ! if (PyString_AsStringAndSize(inputString, (char**)&input, &inplen) == -1) return NULL; --- 416,421 ---- Byte *input; unsigned long start_total_out; ! if (!PyArg_ParseTuple(args, "s#:compress", &input, &inplen)) return NULL; *************** *** 447,457 **** ENTER_ZLIB - Py_INCREF(inputString); - start_total_out = self->zst.total_out; self->zst.avail_in = inplen; self->zst.next_in = input; self->zst.avail_out = length; ! self->zst.next_out = (unsigned char *)PyString_AsString(RetVal); Py_BEGIN_ALLOW_THREADS --- 425,433 ---- ENTER_ZLIB start_total_out = self->zst.total_out; self->zst.avail_in = inplen; self->zst.next_in = input; self->zst.avail_out = length; ! self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal); Py_BEGIN_ALLOW_THREADS *************** *** 466,470 **** goto error; } ! self->zst.next_out = (unsigned char *)PyString_AsString(RetVal) \ + length; self->zst.avail_out = length; --- 442,446 ---- goto error; } ! self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \ + length; self->zst.avail_out = length; *************** *** 491,495 **** error: - Py_DECREF(inputString); LEAVE_ZLIB return RetVal; --- 467,470 ---- *************** *** 515,521 **** Byte *input; unsigned long start_total_out; - PyObject * inputString; ! if (!PyArg_ParseTuple(args, "S|i:decompress", &inputString, &max_length)) return NULL; if (max_length < 0) { --- 490,496 ---- Byte *input; unsigned long start_total_out; ! if (!PyArg_ParseTuple(args, "s#|i:decompress", &input, ! &inplen, &max_length)) return NULL; if (max_length < 0) { *************** *** 525,531 **** } - if (PyString_AsStringAndSize(inputString, (char**)&input, &inplen) == -1) - return NULL; - /* limit amount of data allocated to max_length */ if (max_length && length > max_length) --- 500,503 ---- *************** *** 536,546 **** ENTER_ZLIB - Py_INCREF(inputString); - start_total_out = self->zst.total_out; self->zst.avail_in = inplen; self->zst.next_in = input; self->zst.avail_out = length; ! self->zst.next_out = (unsigned char *)PyString_AsString(RetVal); Py_BEGIN_ALLOW_THREADS --- 508,516 ---- ENTER_ZLIB start_total_out = self->zst.total_out; self->zst.avail_in = inplen; self->zst.next_in = input; self->zst.avail_out = length; ! self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal); Py_BEGIN_ALLOW_THREADS *************** *** 568,572 **** goto error; } ! self->zst.next_out = (unsigned char *)PyString_AsString(RetVal) \ + old_length; self->zst.avail_out = length - old_length; --- 538,542 ---- goto error; } ! self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \ + old_length; self->zst.avail_out = length - old_length; *************** *** 619,624 **** error: - Py_DECREF(inputString); - LEAVE_ZLIB --- 589,592 ---- *************** *** 659,663 **** self->zst.avail_in = 0; self->zst.avail_out = length; ! self->zst.next_out = (unsigned char *)PyString_AsString(RetVal); Py_BEGIN_ALLOW_THREADS --- 627,631 ---- self->zst.avail_in = 0; self->zst.avail_out = length; ! self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal); Py_BEGIN_ALLOW_THREADS *************** *** 672,676 **** goto error; } ! self->zst.next_out = (unsigned char *)PyString_AsString(RetVal) \ + length; self->zst.avail_out = length; --- 640,644 ---- goto error; } ! self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \ + length; self->zst.avail_out = length; From gvanrossum@users.sourceforge.net Wed Oct 17 01:17:55 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 17:17:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.123,1.124 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv11446 Modified Files: ACKS Log Message: YAPC. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.123 retrieving revision 1.124 diff -C2 -d -r1.123 -r1.124 *** ACKS 2001/10/16 20:13:53 1.123 --- ACKS 2001/10/17 00:17:52 1.124 *************** *** 108,111 **** --- 108,112 ---- John DuBois Paul Dubois + Quinn Dunkan Robin Dunn Andy Dustman From fdrake@users.sourceforge.net Wed Oct 17 02:49:52 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 16 Oct 2001 18:49:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv27618 Modified Files: profile.py Log Message: Minor code cleanups based on comments from Neal Norwitz. Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** profile.py 2001/10/09 21:01:31 1.42 --- profile.py 2001/10/17 01:49:50 1.43 *************** *** 354,359 **** pframe = None frame = self.fake_frame(code, pframe) ! a = self.dispatch['call'](self, frame, 0) ! return # collect stats from pending stack, including getting final --- 354,358 ---- pframe = None frame = self.fake_frame(code, pframe) ! self.dispatch['call'](self, frame, 0) # collect stats from pending stack, including getting final *************** *** 366,370 **** # We *can* cause assertion errors here if # dispatch_trace_return checks for a frame match! ! a = self.dispatch['return'](self, self.cur[-2], t) t = 0 self.t = get_time() - t --- 365,369 ---- # We *can* cause assertion errors here if # dispatch_trace_return checks for a frame match! ! self.dispatch['return'](self, self.cur[-2], t) t = 0 self.t = get_time() - t From fdrake@users.sourceforge.net Wed Oct 17 02:51:06 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 16 Oct 2001 18:51:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv27830 Modified Files: xmlrpclib.py Log Message: Remove unused import; reported by Neal Norwitz. Index: xmlrpclib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xmlrpclib.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** xmlrpclib.py 2001/10/10 15:56:34 1.12 --- xmlrpclib.py 2001/10/17 01:51:04 1.13 *************** *** 125,129 **** """ ! import re, string, sys, time, operator from types import * --- 125,129 ---- """ ! import re, string, time, operator from types import * From tim_one@users.sourceforge.net Wed Oct 17 04:43:56 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 16 Oct 2001 20:43:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules zlibmodule.c,2.50,2.51 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv14366/python/Modules Modified Files: zlibmodule.c Log Message: Removed obsolete comments about confused string refcount tricks (Jeremy removed the tricks). Changed the ENTER/LEAVE_ZLIB macros so as not to create a new block (a new block is neither necessary nor helpful). Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.50 retrieving revision 2.51 diff -C2 -d -r2.50 -r2.51 *** zlibmodule.c 2001/10/16 23:26:08 2.50 --- zlibmodule.c 2001/10/17 03:43:54 2.51 *************** *** 24,32 **** other Python threads. - We don't need to worry about the string inputs being modified out - from underneath us, because string objects are immutable. However, - we do need to make sure we take on ownership, so that the strings - are not deleted out from under us during a thread swap. - N.B. --- 24,27 ---- *************** *** 37,41 **** moment the ENTER_ZLIB and LEAVE_ZLIB calls are global for ALL de/compress objects. - */ --- 32,35 ---- *************** *** 43,51 **** #define ENTER_ZLIB \ ! { Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(zlib_lock, 1); \ ! Py_END_ALLOW_THREADS #define LEAVE_ZLIB \ ! PyThread_release_lock(zlib_lock); } #else --- 37,46 ---- #define ENTER_ZLIB \ ! Py_BEGIN_ALLOW_THREADS \ ! PyThread_acquire_lock(zlib_lock, 1); \ ! Py_END_ALLOW_THREADS #define LEAVE_ZLIB \ ! PyThread_release_lock(zlib_lock); #else From tim_one@users.sourceforge.net Wed Oct 17 04:56:47 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 16 Oct 2001 20:56:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules zlibmodule.c,2.51,2.52 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv16756/python/Modules Modified Files: zlibmodule.c Log Message: Removed more comments that didn't make much sense. Made the presence/absence of a semicolon after macros consistent. Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.51 retrieving revision 2.52 diff -C2 -d -r2.51 -r2.52 *** zlibmodule.c 2001/10/17 03:43:54 2.51 --- zlibmodule.c 2001/10/17 03:56:45 2.52 *************** *** 16,27 **** about re-entering zlib functions. - What we _do_ have to worry about is releasing the global lock _in - general_ in the zlibmodule functions, because of all the calls to - Python functions, which assume that the global lock is held. So - only two types of calls are wrapped in Py_BEGIN/END_ALLOW_THREADS: - those that grab the zlib lock, and those that involve other - time-consuming functions where we need to worry about holding up - other Python threads. - N.B. --- 16,19 ---- *************** *** 371,376 **** Comp_dealloc(compobject *self) { - ENTER_ZLIB - if (self->is_initialised) deflateEnd(&self->zst); --- 363,366 ---- *************** *** 378,383 **** Py_XDECREF(self->unconsumed_tail); PyObject_Del(self); - - LEAVE_ZLIB } --- 368,371 ---- *************** *** 385,390 **** Decomp_dealloc(compobject *self) { - ENTER_ZLIB - if (self->is_initialised) inflateEnd(&self->zst); --- 373,376 ---- *************** *** 392,397 **** Py_XDECREF(self->unconsumed_tail); PyObject_Del(self); - - LEAVE_ZLIB } --- 378,381 ---- *************** *** 673,677 **** error: ! LEAVE_ZLIB; return RetVal; --- 657,661 ---- error: ! LEAVE_ZLIB return RetVal; From tim_one@users.sourceforge.net Wed Oct 17 04:57:22 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 16 Oct 2001 20:57:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules zlibmodule.c,2.52,2.53 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv16986/python/Modules Modified Files: zlibmodule.c Log Message: Trimmed trailing whitespace. Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.52 retrieving revision 2.53 diff -C2 -d -r2.52 -r2.53 *** zlibmodule.c 2001/10/17 03:56:45 2.52 --- zlibmodule.c 2001/10/17 03:57:20 2.53 *************** *** 61,65 **** static PyObject *ZlibError; ! typedef struct { PyObject_HEAD --- 61,65 ---- static PyObject *ZlibError; ! typedef struct { PyObject_HEAD *************** *** 79,88 **** } ! static char compressobj__doc__[] = "compressobj() -- Return a compressor object.\n" "compressobj(level) -- Return a compressor object, using the given compression level.\n" ; ! static char decompressobj__doc__[] = "decompressobj() -- Return a decompressor object.\n" "decompressobj(wbits) -- Return a decompressor object, setting the window buffer size to wbits.\n" --- 79,88 ---- } ! static char compressobj__doc__[] = "compressobj() -- Return a compressor object.\n" "compressobj(level) -- Return a compressor object, using the given compression level.\n" ; ! static char decompressobj__doc__[] = "decompressobj() -- Return a decompressor object.\n" "decompressobj(wbits) -- Return a decompressor object, setting the window buffer size to wbits.\n" *************** *** 92,96 **** newcompobject(PyTypeObject *type) { ! compobject *self; self = PyObject_New(compobject, type); if (self == NULL) --- 92,96 ---- newcompobject(PyTypeObject *type) { ! compobject *self; self = PyObject_New(compobject, type); if (self == NULL) *************** *** 110,114 **** } ! static char compress__doc__[] = "compress(string) -- Compress string using the default compression level, " "returning a string containing compressed data.\n" --- 110,114 ---- } ! static char compress__doc__[] = "compress(string) -- Compress string using the default compression level, " "returning a string containing compressed data.\n" *************** *** 124,128 **** int length, level=Z_DEFAULT_COMPRESSION, err; z_stream zst; ! /* require Python string object, optional 'level' arg */ if (!PyArg_ParseTuple(args, "s#|i:compress", &input, &length, &level)) --- 124,128 ---- int length, level=Z_DEFAULT_COMPRESSION, err; z_stream zst; ! /* require Python string object, optional 'level' arg */ if (!PyArg_ParseTuple(args, "s#|i:compress", &input, &length, &level)) *************** *** 174,183 **** goto error; } ! err=deflateEnd(&zst); if (err == Z_OK) ! ReturnVal = PyString_FromStringAndSize((char *)output, zst.total_out); ! else zlib_error(zst, err, "while finishing compression"); --- 174,183 ---- goto error; } ! err=deflateEnd(&zst); if (err == Z_OK) ! ReturnVal = PyString_FromStringAndSize((char *)output, zst.total_out); ! else zlib_error(zst, err, "while finishing compression"); *************** *** 188,192 **** } ! static char decompress__doc__[] = "decompress(string) -- Decompress the data in string, returning a string containing the decompressed data.\n" "decompress(string, wbits) -- Decompress the data in string with a window buffer size of wbits.\n" --- 188,192 ---- } ! static char decompress__doc__[] = "decompress(string) -- Decompress the data in string, returning a string containing the decompressed data.\n" "decompress(string, wbits) -- Decompress the data in string with a window buffer size of wbits.\n" *************** *** 203,207 **** z_stream zst; ! if (!PyArg_ParseTuple(args, "s#|ii:decompress", &input, &length, &wsize, &r_strlen)) return NULL; --- 203,207 ---- z_stream zst; ! if (!PyArg_ParseTuple(args, "s#|ii:decompress", &input, &length, &wsize, &r_strlen)) return NULL; *************** *** 225,229 **** case(Z_OK): break; ! case(Z_MEM_ERROR): PyErr_SetString(PyExc_MemoryError, "Out of memory while decompressing data"); --- 225,229 ---- case(Z_OK): break; ! case(Z_MEM_ERROR): PyErr_SetString(PyExc_MemoryError, "Out of memory while decompressing data"); *************** *** 301,305 **** self = newcompobject(&Comptype); ! if (self==NULL) return(NULL); self->zst.zalloc = (alloc_func)NULL; --- 301,305 ---- self = newcompobject(&Comptype); ! if (self==NULL) return(NULL); self->zst.zalloc = (alloc_func)NULL; *************** *** 335,339 **** self = newcompobject(&Decomptype); ! if (self == NULL) return(NULL); self->zst.zalloc = (alloc_func)NULL; --- 335,339 ---- self = newcompobject(&Decomptype); ! if (self == NULL) return(NULL); self->zst.zalloc = (alloc_func)NULL; *************** *** 395,399 **** Byte *input; unsigned long start_total_out; ! if (!PyArg_ParseTuple(args, "s#:compress", &input, &inplen)) return NULL; --- 395,399 ---- Byte *input; unsigned long start_total_out; ! if (!PyArg_ParseTuple(args, "s#:compress", &input, &inplen)) return NULL; *************** *** 425,437 **** self->zst.avail_out = length; length = length << 1; ! Py_BEGIN_ALLOW_THREADS err = deflate(&(self->zst), Z_NO_FLUSH); Py_END_ALLOW_THREADS } ! /* We will only get Z_BUF_ERROR if the output buffer was full but there wasn't more output when we tried again, so it is not an error ! condition. ! */ if (err != Z_OK && err != Z_BUF_ERROR) { --- 425,437 ---- self->zst.avail_out = length; length = length << 1; ! Py_BEGIN_ALLOW_THREADS err = deflate(&(self->zst), Z_NO_FLUSH); Py_END_ALLOW_THREADS } ! /* We will only get Z_BUF_ERROR if the output buffer was full but there wasn't more output when we tried again, so it is not an error ! condition. ! */ if (err != Z_OK && err != Z_BUF_ERROR) { *************** *** 441,445 **** goto error; } ! if (_PyString_Resize(&RetVal, self->zst.total_out - start_total_out) < 0) RetVal = NULL; --- 441,445 ---- goto error; } ! if (_PyString_Resize(&RetVal, self->zst.total_out - start_total_out) < 0) RetVal = NULL; *************** *** 470,474 **** unsigned long start_total_out; ! if (!PyArg_ParseTuple(args, "s#|i:decompress", &input, &inplen, &max_length)) return NULL; --- 470,474 ---- unsigned long start_total_out; ! if (!PyArg_ParseTuple(args, "s#|i:decompress", &input, &inplen, &max_length)) return NULL; *************** *** 480,484 **** /* limit amount of data allocated to max_length */ ! if (max_length && length > max_length) length = max_length; if (!(RetVal = PyString_FromStringAndSize(NULL, length))) --- 480,484 ---- /* limit amount of data allocated to max_length */ ! if (max_length && length > max_length) length = max_length; if (!(RetVal = PyString_FromStringAndSize(NULL, length))) *************** *** 500,504 **** So extend the output buffer and try again. */ ! while (err == Z_OK && self->zst.avail_out == 0) { /* If max_length set, don't continue decompressing if we've already reached the limit. --- 500,504 ---- So extend the output buffer and try again. */ ! while (err == Z_OK && self->zst.avail_out == 0) { /* If max_length set, don't continue decompressing if we've already reached the limit. *************** *** 510,514 **** old_length = length; length = length << 1; ! if (max_length && length > max_length) length = max_length; --- 510,514 ---- old_length = length; length = length << 1; ! if (max_length && length > max_length) length = max_length; *************** *** 530,534 **** if(max_length) { Py_DECREF(self->unconsumed_tail); ! self->unconsumed_tail = PyString_FromStringAndSize(self->zst.next_in, self->zst.avail_in); if(!self->unconsumed_tail) { --- 530,534 ---- if(max_length) { Py_DECREF(self->unconsumed_tail); ! self->unconsumed_tail = PyString_FromStringAndSize(self->zst.next_in, self->zst.avail_in); if(!self->unconsumed_tail) { *************** *** 539,545 **** } ! /* The end of the compressed data has been reached, so set the ! unused_data attribute to a string containing the remainder of the ! data in the string. Note that this is also a logical place to call inflateEnd, but the old behaviour of only calling it on flush() is preserved. --- 539,545 ---- } ! /* The end of the compressed data has been reached, so set the ! unused_data attribute to a string containing the remainder of the ! data in the string. Note that this is also a logical place to call inflateEnd, but the old behaviour of only calling it on flush() is preserved. *************** *** 553,557 **** goto error; } ! /* We will only get Z_BUF_ERROR if the output buffer was full but there wasn't more output when we tried again, so it is not an error condition. --- 553,557 ---- goto error; } ! /* We will only get Z_BUF_ERROR if the output buffer was full but there wasn't more output when we tried again, so it is not an error condition. *************** *** 602,606 **** ENTER_ZLIB ! start_total_out = self->zst.total_out; self->zst.avail_in = 0; --- 602,606 ---- ENTER_ZLIB ! start_total_out = self->zst.total_out; self->zst.avail_in = 0; *************** *** 630,634 **** /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free ! various data structures. Note we should only get Z_STREAM_END when flushmode is Z_FINISH, but checking both for safety*/ if (err == Z_STREAM_END && flushmode == Z_FINISH) { --- 630,634 ---- /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free ! various data structures. Note we should only get Z_STREAM_END when flushmode is Z_FINISH, but checking both for safety*/ if (err == Z_STREAM_END && flushmode == Z_FINISH) { *************** *** 642,648 **** else self->is_initialised = 0; ! ! /* We will only get Z_BUF_ERROR if the output buffer was full ! but there wasn't more output when we tried again, so it is not an error condition. */ --- 642,648 ---- else self->is_initialised = 0; ! ! /* We will only get Z_BUF_ERROR if the output buffer was full ! but there wasn't more output when we tried again, so it is not an error condition. */ *************** *** 652,660 **** RetVal = NULL; } ! if (_PyString_Resize(&RetVal, self->zst.total_out - start_total_out) < 0) RetVal = NULL; ! error: LEAVE_ZLIB --- 652,660 ---- RetVal = NULL; } ! if (_PyString_Resize(&RetVal, self->zst.total_out - start_total_out) < 0) RetVal = NULL; ! error: LEAVE_ZLIB *************** *** 669,680 **** static PyObject * PyZlib_unflush(compobject *self, PyObject *args) ! /*decompressor flush is a no-op because all pending data would have been flushed by the decompress method. However, this routine previously called ! inflateEnd, causing any further decompress or flush calls to raise exceptions. This behaviour has been preserved.*/ { int err; PyObject * retval = NULL; ! if (!PyArg_ParseTuple(args, "")) return NULL; --- 669,680 ---- static PyObject * PyZlib_unflush(compobject *self, PyObject *args) ! /*decompressor flush is a no-op because all pending data would have been flushed by the decompress method. However, this routine previously called ! inflateEnd, causing any further decompress or flush calls to raise exceptions. This behaviour has been preserved.*/ { int err; PyObject * retval = NULL; ! if (!PyArg_ParseTuple(args, "")) return NULL; *************** *** 697,703 **** static PyMethodDef comp_methods[] = { ! {"compress", (binaryfunc)PyZlib_objcompress, METH_VARARGS, comp_compress__doc__}, ! {"flush", (binaryfunc)PyZlib_flush, METH_VARARGS, comp_flush__doc__}, {NULL, NULL} --- 697,703 ---- static PyMethodDef comp_methods[] = { ! {"compress", (binaryfunc)PyZlib_objcompress, METH_VARARGS, comp_compress__doc__}, ! {"flush", (binaryfunc)PyZlib_flush, METH_VARARGS, comp_flush__doc__}, {NULL, NULL} *************** *** 706,712 **** static PyMethodDef Decomp_methods[] = { ! {"decompress", (binaryfunc)PyZlib_objdecompress, METH_VARARGS, decomp_decompress__doc__}, ! {"flush", (binaryfunc)PyZlib_unflush, METH_VARARGS, decomp_flush__doc__}, {NULL, NULL} --- 706,712 ---- static PyMethodDef Decomp_methods[] = { ! {"decompress", (binaryfunc)PyZlib_objdecompress, METH_VARARGS, decomp_decompress__doc__}, ! {"flush", (binaryfunc)PyZlib_unflush, METH_VARARGS, decomp_flush__doc__}, {NULL, NULL} *************** *** 729,739 **** ENTER_ZLIB ! if (strcmp(name, "unused_data") == 0) { Py_INCREF(self->unused_data); retval = self->unused_data; ! } else if (strcmp(name, "unconsumed_tail") == 0) { Py_INCREF(self->unconsumed_tail); retval = self->unconsumed_tail; ! } else retval = Py_FindMethod(Decomp_methods, (PyObject *)self, name); --- 729,739 ---- ENTER_ZLIB ! if (strcmp(name, "unused_data") == 0) { Py_INCREF(self->unused_data); retval = self->unused_data; ! } else if (strcmp(name, "unconsumed_tail") == 0) { Py_INCREF(self->unconsumed_tail); retval = self->unconsumed_tail; ! } else retval = Py_FindMethod(Decomp_methods, (PyObject *)self, name); *************** *** 743,747 **** } ! static char adler32__doc__[] = "adler32(string) -- Compute an Adler-32 checksum of string, using " "a default starting value, and returning an integer value.\n" --- 743,747 ---- } ! static char adler32__doc__[] = "adler32(string) -- Compute an Adler-32 checksum of string, using " "a default starting value, and returning an integer value.\n" *************** *** 756,760 **** Byte *buf; int len; ! if (!PyArg_ParseTuple(args, "s#|l:adler32", &buf, &len, &adler32val)) return NULL; --- 756,760 ---- Byte *buf; int len; ! if (!PyArg_ParseTuple(args, "s#|l:adler32", &buf, &len, &adler32val)) return NULL; *************** *** 762,767 **** return PyInt_FromLong(adler32val); } ! ! static char crc32__doc__[] = "crc32(string) -- Compute a CRC-32 checksum of string, using " "a default starting value, and returning an integer value.\n" --- 762,767 ---- return PyInt_FromLong(adler32val); } ! ! static char crc32__doc__[] = "crc32(string) -- Compute a CRC-32 checksum of string, using " "a default starting value, and returning an integer value.\n" *************** *** 781,799 **** return PyInt_FromLong(crc32val); } - static PyMethodDef zlib_methods[] = { ! {"adler32", (PyCFunction)PyZlib_adler32, METH_VARARGS, adler32__doc__}, ! {"compress", (PyCFunction)PyZlib_compress, METH_VARARGS, compress__doc__}, ! {"compressobj", (PyCFunction)PyZlib_compressobj, METH_VARARGS, compressobj__doc__}, ! {"crc32", (PyCFunction)PyZlib_crc32, METH_VARARGS, ! crc32__doc__}, ! {"decompress", (PyCFunction)PyZlib_decompress, METH_VARARGS, decompress__doc__}, ! {"decompressobj", (PyCFunction)PyZlib_decompressobj, METH_VARARGS, decompressobj__doc__}, {NULL, NULL} --- 781,799 ---- return PyInt_FromLong(crc32val); } + static PyMethodDef zlib_methods[] = { ! {"adler32", (PyCFunction)PyZlib_adler32, METH_VARARGS, adler32__doc__}, ! {"compress", (PyCFunction)PyZlib_compress, METH_VARARGS, compress__doc__}, ! {"compressobj", (PyCFunction)PyZlib_compressobj, METH_VARARGS, compressobj__doc__}, ! {"crc32", (PyCFunction)PyZlib_crc32, METH_VARARGS, ! crc32__doc__}, ! {"decompress", (PyCFunction)PyZlib_decompress, METH_VARARGS, decompress__doc__}, ! {"decompressobj", (PyCFunction)PyZlib_decompressobj, METH_VARARGS, decompressobj__doc__}, {NULL, NULL} *************** *** 834,839 **** }; ! /* The following insint() routine was blatantly ripped off from ! socketmodule.c */ /* Convenience routine to export an integer value. --- 834,839 ---- }; ! /* The following insint() routine was blatantly ripped off from ! socketmodule.c */ /* Convenience routine to export an integer value. *************** *** 892,901 **** PyModule_AddIntConstant(m, "Z_HUFFMAN_ONLY", Z_HUFFMAN_ONLY); PyModule_AddIntConstant(m, "Z_DEFAULT_STRATEGY", Z_DEFAULT_STRATEGY); ! PyModule_AddIntConstant(m, "Z_FINISH", Z_FINISH); PyModule_AddIntConstant(m, "Z_NO_FLUSH", Z_NO_FLUSH); PyModule_AddIntConstant(m, "Z_SYNC_FLUSH", Z_SYNC_FLUSH); PyModule_AddIntConstant(m, "Z_FULL_FLUSH", Z_FULL_FLUSH); ! ver = PyString_FromString(ZLIB_VERSION); if (ver != NULL) { --- 892,901 ---- PyModule_AddIntConstant(m, "Z_HUFFMAN_ONLY", Z_HUFFMAN_ONLY); PyModule_AddIntConstant(m, "Z_DEFAULT_STRATEGY", Z_DEFAULT_STRATEGY); ! PyModule_AddIntConstant(m, "Z_FINISH", Z_FINISH); PyModule_AddIntConstant(m, "Z_NO_FLUSH", Z_NO_FLUSH); PyModule_AddIntConstant(m, "Z_SYNC_FLUSH", Z_SYNC_FLUSH); PyModule_AddIntConstant(m, "Z_FULL_FLUSH", Z_FULL_FLUSH); ! ver = PyString_FromString(ZLIB_VERSION); if (ver != NULL) { From tim_one@users.sourceforge.net Wed Oct 17 05:16:17 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 16 Oct 2001 21:16:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules zlibmodule.c,2.53,2.54 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv19867/python/Modules Modified Files: zlibmodule.c Log Message: Simplify and regularize docstrings. Also reformat so that each docstring line fits in reasonable screen width. Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.53 retrieving revision 2.54 diff -C2 -d -r2.53 -r2.54 *** zlibmodule.c 2001/10/17 03:57:20 2.53 --- zlibmodule.c 2001/10/17 04:16:15 2.54 *************** *** 80,91 **** static char compressobj__doc__[] = ! "compressobj() -- Return a compressor object.\n" ! "compressobj(level) -- Return a compressor object, using the given compression level.\n" ! ; static char decompressobj__doc__[] = ! "decompressobj() -- Return a decompressor object.\n" ! "decompressobj(wbits) -- Return a decompressor object, setting the window buffer size to wbits.\n" ! ; static compobject * --- 80,91 ---- static char compressobj__doc__[] = ! "compressobj([level]) -- Return a compressor object.\n" ! "\n" ! "Optional arg level is the compression level, in 1-9."; static char decompressobj__doc__[] = ! "decompressobj([wbits]) -- Return a decompressor object.\n" ! "\n" ! "Optional arg wbits is the window buffer size."; static compobject * *************** *** 111,119 **** static char compress__doc__[] = ! "compress(string) -- Compress string using the default compression level, " ! "returning a string containing compressed data.\n" ! "compress(string, level) -- Compress string, using the chosen compression " ! "level (from 1 to 9). Return a string containing the compressed data.\n" ! ; static PyObject * --- 111,117 ---- static char compress__doc__[] = ! "compress(string[, level]) -- Returned compressed string.\n" ! "\n" ! "Optional arg level is the compression level, in 1-9."; static PyObject * *************** *** 189,196 **** static char decompress__doc__[] = ! "decompress(string) -- Decompress the data in string, returning a string containing the decompressed data.\n" ! "decompress(string, wbits) -- Decompress the data in string with a window buffer size of wbits.\n" ! "decompress(string, wbits, bufsize) -- Decompress the data in string with a window buffer size of wbits and an initial output buffer size of bufsize.\n" ! ; static PyObject * --- 187,194 ---- static char decompress__doc__[] = ! "decompress(string[, wbits[, bufsize]]) -- Return decompressed string.\n" ! "\n" ! "Optional arg wbits is the window buffer size. Optional arg bufsize is\n" ! "the initial output buffer size."; static PyObject * *************** *** 381,389 **** static char comp_compress__doc__[] = ! "compress(data) -- Return a string containing a compressed version of the data.\n\n" "After calling this function, some of the input data may still\n" "be stored in internal buffers for later processing.\n" ! "Call the flush() method to clear these buffers." ! ; --- 379,387 ---- static char comp_compress__doc__[] = ! "compress(data) -- Return a string containing data compressed.\n" ! "\n" "After calling this function, some of the input data may still\n" "be stored in internal buffers for later processing.\n" ! "Call the flush() method to clear these buffers."; *************** *** 451,463 **** static char decomp_decompress__doc__[] = ! "decompress(data, max_length) -- Return a string containing\n" ! "the decompressed version of the data.\n\n" ! "After calling this function, some of the input data may still\n" ! "be stored in internal buffers for later processing.\n" "Call the flush() method to clear these buffers.\n" "If the max_length parameter is specified then the return value will be\n" "no longer than max_length. Unconsumed input data will be stored in\n" ! "the unconsumed_tail attribute." ! ; static PyObject * --- 449,461 ---- static char decomp_decompress__doc__[] = ! "decompress(data, max_length) -- Return a string containing the decompressed\n" ! "version of the data.\n" ! "\n" ! "After calling this function, some of the input data may still be stored in\n" ! "internal buffers for later processing.\n" "Call the flush() method to clear these buffers.\n" "If the max_length parameter is specified then the return value will be\n" "no longer than max_length. Unconsumed input data will be stored in\n" ! "the unconsumed_tail attribute."; static PyObject * *************** *** 575,583 **** static char comp_flush__doc__[] = "flush( [mode] ) -- Return a string containing any remaining compressed data.\n" ! "mode can be one of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH; the \n" "default value used when mode is not specified is Z_FINISH.\n" "If mode == Z_FINISH, the compressor object can no longer be used after\n" ! "calling the flush() method. Otherwise, more data can still be compressed.\n" ! ; static PyObject * --- 573,581 ---- static char comp_flush__doc__[] = "flush( [mode] ) -- Return a string containing any remaining compressed data.\n" ! "\n" ! "mode can be one of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH; the\n" "default value used when mode is not specified is Z_FINISH.\n" "If mode == Z_FINISH, the compressor object can no longer be used after\n" ! "calling the flush() method. Otherwise, more data can still be compressed.\n"; static PyObject * *************** *** 663,669 **** static char decomp_flush__doc__[] = ! "flush() -- Return a string containing any remaining decompressed data. " ! "The decompressor object can no longer be used after this call." ! ; static PyObject * --- 661,667 ---- static char decomp_flush__doc__[] = ! "flush() -- Return a string containing any remaining decompressed data.\n" ! "\n" ! "The decompressor object can no longer be used after this call."; static PyObject * *************** *** 744,752 **** static char adler32__doc__[] = ! "adler32(string) -- Compute an Adler-32 checksum of string, using " ! "a default starting value, and returning an integer value.\n" ! "adler32(string, value) -- Compute an Adler-32 checksum of string, using " ! "the starting value provided, and returning an integer value\n" ! ; static PyObject * --- 742,749 ---- static char adler32__doc__[] = ! "adler32(string[, start]) -- Compute an Adler-32 checksum of string.\n" ! "\n" ! "An optional starting value can be specified. The returned checksum is\n" ! "an integer."; static PyObject * *************** *** 764,772 **** static char crc32__doc__[] = ! "crc32(string) -- Compute a CRC-32 checksum of string, using " ! "a default starting value, and returning an integer value.\n" ! "crc32(string, value) -- Compute a CRC-32 checksum of string, using " ! "the starting value provided, and returning an integer value.\n" ! ; static PyObject * --- 761,768 ---- static char crc32__doc__[] = ! "crc32(string[, start]) -- Compute a CRC-32 checksum of string.\n" ! "\n" ! "An optional starting value can be specified. The returned checksum is\n" ! "an integer."; static PyObject * *************** *** 854,871 **** static char zlib_module_documentation[]= ! "The functions in this module allow compression and decompression " ! "using the zlib library, which is based on GNU zip. \n\n" ! "adler32(string) -- Compute an Adler-32 checksum.\n" ! "adler32(string, start) -- Compute an Adler-32 checksum using a given starting value.\n" ! "compress(string) -- Compress a string.\n" ! "compress(string, level) -- Compress a string with the given level of compression (1--9).\n" "compressobj([level]) -- Return a compressor object.\n" ! "crc32(string) -- Compute a CRC-32 checksum.\n" ! "crc32(string, start) -- Compute a CRC-32 checksum using a given starting value.\n" "decompress(string,[wbits],[bufsize]) -- Decompresses a compressed string.\n" ! "decompressobj([wbits]) -- Return a decompressor object (wbits=window buffer size).\n\n" ! "Compressor objects support compress() and flush() methods; decompressor \n" ! "objects support decompress() and flush()." ! ; DL_EXPORT(void) --- 850,866 ---- static char zlib_module_documentation[]= ! "The functions in this module allow compression and decompression using the\n" ! "zlib library, which is based on GNU zip.\n" ! "\n" ! "adler32(string[, start]) -- Compute an Adler-32 checksum.\n" ! "compress(string[, level]) -- Compress string, with compression level in 1-9.\n" "compressobj([level]) -- Return a compressor object.\n" ! "crc32(string[, start]) -- Compute a CRC-32 checksum.\n" "decompress(string,[wbits],[bufsize]) -- Decompresses a compressed string.\n" ! "decompressobj([wbits]) -- Return a decompressor object.\n" ! "\n" ! "'wbits' is window buffer size.\n" ! "Compressor objects support compress() and flush() methods; decompressor\n" ! "objects support decompress() and flush()."; DL_EXPORT(void) From gvanrossum@users.sourceforge.net Wed Oct 17 06:59:28 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 22:59:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib mhlib.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv3181 Modified Files: mhlib.py Log Message: Folder.getlast(): avoid PyChecker warning. Index: mhlib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mhlib.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** mhlib.py 2001/07/04 07:01:29 1.27 --- mhlib.py 2001/10/17 05:59:26 1.28 *************** *** 649,653 **** """Return the last message number.""" if not hasattr(self, 'last'): ! messages = self.listmessages() return self.last --- 649,653 ---- """Return the last message number.""" if not hasattr(self, 'last'): ! self.listmessages() # Set self.last return self.last From gvanrossum@users.sourceforge.net Wed Oct 17 07:26:55 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 23:26:55 -0700 Subject: [Python-checkins] CVS: python/dist/src Makefile.pre.in,1.62,1.63 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv7049 Modified Files: Makefile.pre.in Log Message: SF patch #471894: Makefile installs pydoc incorrectly Add --install-scripts=$(BINDIR) argument to "setup.py install" invocation. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** Makefile.pre.in 2001/10/05 21:56:02 1.62 --- Makefile.pre.in 2001/10/17 06:26:53 1.63 *************** *** 732,735 **** --- 732,736 ---- sharedinstall: ./$(PYTHON) -E $(srcdir)/setup.py install \ + --install-scripts=$(BINDIR) \ --install-platlib=$(DESTSHARED) From gvanrossum@users.sourceforge.net Wed Oct 17 07:45:01 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 23:45:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib CGIHTTPServer.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv9671 Modified Files: CGIHTTPServer.py Log Message: SF patch #467430. - replace some log_error() calls with log_message() - flush self.rfile before forking too (hope this works on Windows) Index: CGIHTTPServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/CGIHTTPServer.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** CGIHTTPServer.py 2001/08/07 19:55:10 1.18 --- CGIHTTPServer.py 2001/10/17 06:44:58 1.19 *************** *** 193,196 **** --- 193,197 ---- args.append(decoded_query) nobody = nobody_uid() + self.rfile.flush() # Always flush before forking self.wfile.flush() # Always flush before forking pid = os.fork() *************** *** 227,231 **** if '=' not in query and '"' not in query: cmdline = '%s "%s"' % (cmdline, query) ! self.log_error("command: %s", cmdline) try: nbytes = int(length) --- 228,232 ---- if '=' not in query and '"' not in query: cmdline = '%s "%s"' % (cmdline, query) ! self.log_message("command: %s", cmdline) try: nbytes = int(length) *************** *** 242,246 **** self.log_error("CGI script exit status %#x", sts) else: ! self.log_error("CGI script exited OK") else: --- 243,247 ---- self.log_error("CGI script exit status %#x", sts) else: ! self.log_message("CGI script exited OK") else: *************** *** 267,271 **** self.log_error("CGI script exit status %s", str(sts)) else: ! self.log_error("CGI script exited OK") --- 268,272 ---- self.log_error("CGI script exit status %s", str(sts)) else: ! self.log_message("CGI script exited OK") From gvanrossum@users.sourceforge.net Wed Oct 17 07:45:59 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 16 Oct 2001 23:45:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.124,1.125 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv9874 Modified Files: ACKS Log Message: SF patch #467430. - replace some log_error() calls with log_message() - flush self.rfile before forking too (hope this works on Windows) Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.124 retrieving revision 1.125 diff -C2 -d -r1.124 -r1.125 *** ACKS 2001/10/17 00:17:52 1.124 --- ACKS 2001/10/17 06:45:56 1.125 *************** *** 302,305 **** --- 302,306 ---- Bill Noon Stefan Norberg + Joe Norton Neal Norwitz Jeffrey Ollie From gvanrossum@users.sourceforge.net Wed Oct 17 08:15:46 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 17 Oct 2001 00:15:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.106,2.107 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv16609 Modified Files: typeobject.c Log Message: slot_sq_item(): ensure that self is an instance of the wrapper's d_type before calling the wrapped function. fixup_slot_dispatchers(): fix indentation. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.106 retrieving revision 2.107 diff -C2 -d -r2.106 -r2.107 *** typeobject.c 2001/10/16 17:00:48 2.106 --- typeobject.c 2001/10/17 07:15:43 2.107 *************** *** 2909,2913 **** PyWrapperDescrObject *wrapper = (PyWrapperDescrObject *)func; ! if (wrapper->d_base->wrapper == wrap_sq_item) { intargfunc f; f = (intargfunc)(wrapper->d_wrapped); --- 2909,2914 ---- PyWrapperDescrObject *wrapper = (PyWrapperDescrObject *)func; ! if (wrapper->d_base->wrapper == wrap_sq_item && ! PyType_IsSubtype(self->ob_type, wrapper->d_type)) { intargfunc f; f = (intargfunc)(wrapper->d_wrapped); *************** *** 3939,3945 **** d = (PyWrapperDescrObject *)descr; if (d->d_base->wrapper == p->wrapper && ! PyType_IsSubtype(type, d->d_type)) { if (specific == NULL || ! specific == d->d_wrapped) specific = d->d_wrapped; else --- 3940,3947 ---- d = (PyWrapperDescrObject *)descr; if (d->d_base->wrapper == p->wrapper && ! PyType_IsSubtype(type, d->d_type)) ! { if (specific == NULL || ! specific == d->d_wrapped) specific = d->d_wrapped; else From jhylton@users.sourceforge.net Wed Oct 17 14:13:06 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 17 Oct 2001 06:13:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib symbol.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11011/Lib Modified Files: symbol.py Log Message: track addition of testlist_safe to Grammar Index: symbol.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/symbol.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** symbol.py 2001/07/13 18:05:46 1.13 --- symbol.py 2001/10/17 13:13:04 1.14 *************** *** 69,79 **** exprlist = 312 testlist = 313 ! dictmaker = 314 ! classdef = 315 ! arglist = 316 ! argument = 317 ! list_iter = 318 ! list_for = 319 ! list_if = 320 #--end constants-- --- 69,80 ---- exprlist = 312 testlist = 313 ! testlist_safe = 314 ! dictmaker = 315 ! classdef = 316 ! arglist = 317 ! argument = 318 ! list_iter = 319 ! list_for = 320 ! list_if = 321 #--end constants-- From jhylton@users.sourceforge.net Wed Oct 17 14:22:25 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 17 Oct 2001 06:22:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python compile.c,2.225,2.226 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv13722/Python Modified Files: compile.c Log Message: Fix computation of stack depth for classdef and closures. Also minor tweaks to internal routines. Use PyCF_MASK instead of explicit list of flags. For the MAKE_CLOSURE opcode, the number of items popped off the stack depends on both the oparg and the number of free variables for the code object. Fix the code so it accounts for the free variables. In com_classdef(), record an extra pop to account for the STORE call after the BUILD_CLASS. Get rid of some commented out debugging code in com_push() and com_pop(). Factor string resize logic into helper routine com_check_size(). In com_addbyte(), remove redudant if statement after assert. (They test the same condition.) In several routines, use string macros instead of string functions. Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.225 retrieving revision 2.226 diff -C2 -d -r2.225 -r2.226 *** compile.c 2001/10/15 15:44:05 2.225 --- compile.c 2001/10/17 13:22:22 2.226 *************** *** 669,674 **** { c->c_stacklevel += n; ! if (c->c_stacklevel > c->c_maxstacklevel) c->c_maxstacklevel = c->c_stacklevel; } --- 669,680 ---- { c->c_stacklevel += n; ! if (c->c_stacklevel > c->c_maxstacklevel) { c->c_maxstacklevel = c->c_stacklevel; + /* + fprintf(stderr, "%s:%s:%d max stack nexti=%d level=%d n=%d\n", + c->c_filename, c->c_name, c->c_lineno, + c->c_nexti, c->c_stacklevel, n); + */ + } } *************** *** 676,686 **** com_pop(struct compiling *c, int n) { ! if (c->c_stacklevel < n) { ! /* fprintf(stderr, ! "%s:%d: underflow! nexti=%d, level=%d, n=%d\n", ! c->c_filename, c->c_lineno, ! c->c_nexti, c->c_stacklevel, n); */ c->c_stacklevel = 0; - } else c->c_stacklevel -= n; --- 682,687 ---- com_pop(struct compiling *c, int n) { ! if (c->c_stacklevel < n) c->c_stacklevel = 0; else c->c_stacklevel -= n; *************** *** 696,719 **** } static void com_addbyte(struct compiling *c, int byte) { - int len; /*fprintf(stderr, "%3d: %3d\n", c->c_nexti, byte);*/ assert(byte >= 0 && byte <= 255); ! if (byte < 0 || byte > 255) { ! com_error(c, PyExc_SystemError, ! "com_addbyte: byte out of range"); ! } ! if (c->c_code == NULL) return; - len = PyString_Size(c->c_code); - if (c->c_nexti >= len) { - if (_PyString_Resize(&c->c_code, len+1000) != 0) { - c->c_errors++; - return; - } } ! PyString_AsString(c->c_code)[c->c_nexti++] = byte; } --- 697,720 ---- } + static int + com_check_size(PyObject **s, int offset) + { + int len = PyString_GET_SIZE(*s); + if (offset >= len) + return _PyString_Resize(s, len * 2); + return 0; + } + static void com_addbyte(struct compiling *c, int byte) { /*fprintf(stderr, "%3d: %3d\n", c->c_nexti, byte);*/ assert(byte >= 0 && byte <= 255); ! assert(c->c_code); ! if (com_check_size(&c->c_code, c->c_nexti)) { ! c->c_errors++; return; } ! PyString_AS_STRING(c->c_code)[c->c_nexti++] = byte; } *************** *** 728,743 **** com_add_lnotab(struct compiling *c, int addr, int line) { - int size; char *p; if (c->c_lnotab == NULL) return; ! size = PyString_Size(c->c_lnotab); ! if (c->c_lnotab_next+2 > size) { ! if (_PyString_Resize(&c->c_lnotab, size + 1000) < 0) { ! c->c_errors++; ! return; ! } } ! p = PyString_AsString(c->c_lnotab) + c->c_lnotab_next; *p++ = addr; *p++ = line; --- 729,740 ---- com_add_lnotab(struct compiling *c, int addr, int line) { char *p; if (c->c_lnotab == NULL) return; ! if (com_check_size(&c->c_lnotab, c->c_lnotab_next + 2)) { ! c->c_errors++; ! return; } ! p = PyString_AS_STRING(c->c_lnotab) + c->c_lnotab_next; *p++ = addr; *p++ = line; *************** *** 805,809 **** com_backpatch(struct compiling *c, int anchor) { ! unsigned char *code = (unsigned char *) PyString_AsString(c->c_code); int target = c->c_nexti; int dist; --- 802,806 ---- com_backpatch(struct compiling *c, int anchor) { ! unsigned char *code = (unsigned char *) PyString_AS_STRING(c->c_code); int target = c->c_nexti; int dist; *************** *** 2327,2336 **** REQ(n, test); /* and_test ('or' and_test)* | lambdef */ if (NCH(n) == 1 && TYPE(CHILD(n, 0)) == lambdef) { ! PyObject *co; int i, closure; int ndefs = com_argdefs(c, CHILD(n, 0)); symtable_enter_scope(c->c_symtable, "lambda", lambdef, n->n_lineno); ! co = (PyObject *) icompile(CHILD(n, 0), c); if (co == NULL) { c->c_errors++; --- 2324,2333 ---- REQ(n, test); /* and_test ('or' and_test)* | lambdef */ if (NCH(n) == 1 && TYPE(CHILD(n, 0)) == lambdef) { ! PyCodeObject *co; int i, closure; int ndefs = com_argdefs(c, CHILD(n, 0)); symtable_enter_scope(c->c_symtable, "lambda", lambdef, n->n_lineno); ! co = icompile(CHILD(n, 0), c); if (co == NULL) { c->c_errors++; *************** *** 2338,2350 **** } symtable_exit_scope(c->c_symtable); ! i = com_addconst(c, co); ! closure = com_make_closure(c, (PyCodeObject *)co); ! Py_DECREF(co); com_addoparg(c, LOAD_CONST, i); com_push(c, 1); ! if (closure) com_addoparg(c, MAKE_CLOSURE, ndefs); ! else com_addoparg(c, MAKE_FUNCTION, ndefs); com_pop(c, ndefs); } --- 2335,2348 ---- } symtable_exit_scope(c->c_symtable); ! i = com_addconst(c, (PyObject *)co); ! closure = com_make_closure(c, co); com_addoparg(c, LOAD_CONST, i); com_push(c, 1); ! if (closure) { com_addoparg(c, MAKE_CLOSURE, ndefs); ! com_pop(c, PyTuple_GET_SIZE(co->co_freevars)); ! } else com_addoparg(c, MAKE_FUNCTION, ndefs); + Py_DECREF(co); com_pop(c, ndefs); } *************** *** 3565,3569 **** { int i; ! PyObject *co, *v; char *name; --- 3563,3568 ---- { int i; ! PyObject *v; ! PyCodeObject *co; char *name; *************** *** 3588,3603 **** name = STR(CHILD(n, 1)); symtable_enter_scope(c->c_symtable, name, TYPE(n), n->n_lineno); ! co = (PyObject *)icompile(n, c); symtable_exit_scope(c->c_symtable); if (co == NULL) c->c_errors++; else { ! int closure = com_make_closure(c, (PyCodeObject *)co); ! i = com_addconst(c, co); com_addoparg(c, LOAD_CONST, i); com_push(c, 1); ! if (closure) com_addoparg(c, MAKE_CLOSURE, 0); ! else com_addoparg(c, MAKE_FUNCTION, 0); com_addoparg(c, CALL_FUNCTION, 0); --- 3587,3603 ---- name = STR(CHILD(n, 1)); symtable_enter_scope(c->c_symtable, name, TYPE(n), n->n_lineno); ! co = icompile(n, c); symtable_exit_scope(c->c_symtable); if (co == NULL) c->c_errors++; else { ! int closure = com_make_closure(c, co); ! i = com_addconst(c, (PyObject *)co); com_addoparg(c, LOAD_CONST, i); com_push(c, 1); ! if (closure) { com_addoparg(c, MAKE_CLOSURE, 0); ! com_pop(c, PyTuple_GET_SIZE(co->co_freevars)); ! } else com_addoparg(c, MAKE_FUNCTION, 0); com_addoparg(c, CALL_FUNCTION, 0); *************** *** 3605,3608 **** --- 3605,3609 ---- com_pop(c, 2); com_addop_varname(c, VAR_STORE, STR(CHILD(n, 1))); + com_pop(c, 1); Py_DECREF(co); } *************** *** 4083,4088 **** || (sc.c_symtable->st_cur->ste_type == TYPE_FUNCTION)) sc.c_nested = 1; ! sc.c_flags |= base->c_flags & (CO_GENERATOR_ALLOWED | ! CO_FUTURE_DIVISION); } else { sc.c_private = NULL; --- 4084,4088 ---- || (sc.c_symtable->st_cur->ste_type == TYPE_FUNCTION)) sc.c_nested = 1; ! sc.c_flags |= base->c_flags & PyCF_MASK; } else { sc.c_private = NULL; From jhylton@users.sourceforge.net Wed Oct 17 14:29:32 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 17 Oct 2001 06:29:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.285,2.286 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv16146 Modified Files: ceval.c Log Message: For debug build, check that the stack pointer never exceeds the stack size. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.285 retrieving revision 2.286 diff -C2 -d -r2.285 -r2.286 *** ceval.c 2001/10/15 20:51:38 2.285 --- ceval.c 2001/10/17 13:29:30 2.286 *************** *** 543,547 **** #ifdef LLTRACE ! #define PUSH(v) (void)(BASIC_PUSH(v), lltrace && prtrace(TOP(), "push")) #define POP() ((void)(lltrace && prtrace(TOP(), "pop")), BASIC_POP()) #else --- 543,549 ---- #ifdef LLTRACE ! #define PUSH(v) { (void)(BASIC_PUSH(v), \ ! lltrace && prtrace(TOP(), "push")); \ ! assert(STACK_LEVEL() <= f->f_stacksize); } #define POP() ((void)(lltrace && prtrace(TOP(), "pop")), BASIC_POP()) #else From jhylton@users.sourceforge.net Wed Oct 17 14:32:04 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 17 Oct 2001 06:32:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules zlibmodule.c,2.54,2.55 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv16891/Modules Modified Files: zlibmodule.c Log Message: Remove unused convenience routine. Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.54 retrieving revision 2.55 diff -C2 -d -r2.54 -r2.55 *** zlibmodule.c 2001/10/17 04:16:15 2.54 --- zlibmodule.c 2001/10/17 13:32:02 2.55 *************** *** 830,852 **** }; - /* The following insint() routine was blatantly ripped off from - socketmodule.c */ - - /* Convenience routine to export an integer value. - For simplicity, errors (which are unlikely anyway) are ignored. */ - static void - insint(PyObject *d, char *name, int value) - { - PyObject *v = PyInt_FromLong((long) value); - if (v == NULL) { - /* Don't bother reporting this error */ - PyErr_Clear(); - } - else { - PyDict_SetItemString(d, name, v); - Py_DECREF(v); - } - } - static char zlib_module_documentation[]= "The functions in this module allow compression and decompression using the\n" --- 830,833 ---- From jhylton@users.sourceforge.net Wed Oct 17 14:32:54 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 17 Oct 2001 06:32:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/compiler transformer.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/compiler In directory usw-pr-cvs1:/tmp/cvs-serv17058/Lib/compiler Modified Files: transformer.py Log Message: Handle testlist_safe as if it were testlist. Index: transformer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/transformer.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** transformer.py 2001/09/17 21:02:51 1.28 --- transformer.py 2001/10/17 13:32:52 1.29 *************** *** 516,522 **** --- 516,524 ---- def testlist(self, nodelist): # testlist: expr (',' expr)* [','] + # testlist_safe: test [(',' test)+ [',']] # exprlist: expr (',' expr)* [','] return self.com_binary(Tuple, nodelist) + testlist_safe = testlist # XXX exprlist = testlist *************** *** 1255,1258 **** --- 1257,1261 ---- symbol.expr_stmt, symbol.testlist, + symbol.testlist_safe, symbol.test, symbol.and_test, *************** *** 1307,1310 **** --- 1310,1314 ---- symbol.suite, symbol.testlist, + symbol.testlist_safe, symbol.test, symbol.and_test, From jhylton@users.sourceforge.net Wed Oct 17 14:37:31 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 17 Oct 2001 06:37:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/compiler pyassem.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/compiler In directory usw-pr-cvs1:/tmp/cvs-serv18531/Lib/compiler Modified Files: pyassem.py Log Message: Vastly improved stacksize calculation. There are now no known cases where the compiler package computes a stack depth lower than the one computed by the builtin compiler. (To achieve this state, we had to fix bugs in both compilers :-). The chief change is to do the depth calculations with respect to basic blocks. The stack effect of block is calculated. Then the flow graph is traversed using breadth-first search to find the max weight path through the graph. Had to fix the StackDepthTracker to calculate the right info for several opcodes: LOAD_ATTR, CALL_FUNCTION (and friends), MAKE_CLOSURE, and DUP_TOPX. XXX Still need to handle free variables in MAKE_CLOSURE. XXX There are still a lot of places where the computed stack depth is larger than for the builtin compiler. These won't cause the interpreter to overflow the frame, but they waste space. Index: pyassem.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/pyassem.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** pyassem.py 2001/09/14 22:49:08 1.27 --- pyassem.py 2001/10/17 13:37:29 1.28 *************** *** 197,201 **** chains.insert(goes_before, c) - del blocks[:] for c in chains: --- 197,200 ---- *************** *** 375,378 **** --- 374,378 ---- """Get a Python code object""" if self.stage == RAW: + self.computeStackDepth() self.flattenGraph() if self.stage == FLAT: *************** *** 402,405 **** --- 402,435 ---- sys.stdout = save + def computeStackDepth(self): + """Compute the max stack depth. + + Approach is to compute the stack effect of each basic block. + Then find the path through the code with the largest total + effect. + """ + depth = {} + exit = None + for b in self.getBlocks(): + depth[b] = findDepth(b.getInstructions()) + + seen = {} + + def max_depth(b, d): + if seen.has_key(b): + return d + seen[b] = 1 + d = d + depth[b] + children = b.get_children() + if children: + return max([max_depth(c, d) for c in children]) + else: + if not b.label == "exit": + return max_depth(self.exit, d) + else: + return d + + self.stacksize = max_depth(self.entry, 0) + def flattenGraph(self): """Arrange the blocks in order and resolve jumps""" *************** *** 433,437 **** elif self.hasjabs.has_elt(opname): insts[i] = opname, begin[inst[1]] - self.stacksize = findDepth(self.insts) self.stage = FLAT --- 463,466 ---- *************** *** 694,712 **** # XXX 2. at least partly as a result, this code is broken ! def findDepth(self, insts): depth = 0 maxDepth = 0 for i in insts: opname = i[0] ! delta = self.effect.get(opname, 0) ! if delta > 1: ! depth = depth + delta ! elif delta < 0: ! if depth > maxDepth: ! maxDepth = depth depth = depth + delta else: - if depth > maxDepth: - maxDepth = depth # now check patterns for pat, pat_delta in self.patterns: --- 723,737 ---- # XXX 2. at least partly as a result, this code is broken ! def findDepth(self, insts, debug=0): depth = 0 maxDepth = 0 for i in insts: opname = i[0] ! if debug: ! print i, ! delta = self.effect.get(opname, None) ! if delta is not None: depth = depth + delta else: # now check patterns for pat, pat_delta in self.patterns: *************** *** 716,725 **** break # if we still haven't found a match ! if delta == 0: meth = getattr(self, opname, None) if meth is not None: depth = depth + meth(i[1]) ! if depth < 0: ! depth = 0 return maxDepth --- 741,752 ---- break # if we still haven't found a match ! if delta is None: meth = getattr(self, opname, None) if meth is not None: depth = depth + meth(i[1]) ! if depth > maxDepth: ! maxDepth = depth ! if debug: ! print depth, maxDepth return maxDepth *************** *** 755,758 **** --- 782,786 ---- 'IMPORT_NAME': 0, 'IMPORT_FROM': 1, + 'LOAD_ATTR': 0, # unlike other loads # close enough... 'SETUP_EXCEPT': 3, *************** *** 774,786 **** def CALL_FUNCTION(self, argc): hi, lo = divmod(argc, 256) ! return lo + hi * 2 def CALL_FUNCTION_VAR(self, argc): ! return self.CALL_FUNCTION(argc)+1 def CALL_FUNCTION_KW(self, argc): ! return self.CALL_FUNCTION(argc)+1 def CALL_FUNCTION_VAR_KW(self, argc): ! return self.CALL_FUNCTION(argc)+2 def MAKE_FUNCTION(self, argc): return -argc def BUILD_SLICE(self, argc): if argc == 2: --- 802,817 ---- def CALL_FUNCTION(self, argc): hi, lo = divmod(argc, 256) ! return -(lo + hi * 2) def CALL_FUNCTION_VAR(self, argc): ! return self.CALL_FUNCTION(argc)-1 def CALL_FUNCTION_KW(self, argc): ! return self.CALL_FUNCTION(argc)-1 def CALL_FUNCTION_VAR_KW(self, argc): ! return self.CALL_FUNCTION(argc)-2 def MAKE_FUNCTION(self, argc): return -argc + def MAKE_CLOSURE(self, argc): + # XXX need to account for free variables too! + return -argc def BUILD_SLICE(self, argc): if argc == 2: *************** *** 788,791 **** --- 819,824 ---- elif argc == 3: return -2 + def DUP_TOPX(self, argc): + return argc findDepth = StackDepthTracker().findDepth From jhylton@users.sourceforge.net Wed Oct 17 14:39:08 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 17 Oct 2001 06:39:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/compiler stacktest.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/compiler In directory usw-pr-cvs1:/tmp/cvs-serv19055/Tools/compiler Added Files: stacktest.py Log Message: Test utility to look for bad stacksize calculations. --- NEW FILE: stacktest.py --- import compiler import dis import types def extract_code_objects(co): l = [co] for const in co.co_consts: if type(const) == types.CodeType: l.append(const) return l def compare(a, b): if not (a.co_name == "?" or a.co_name.startswith(' b.co_stacksize: print "good code" dis.dis(a) print "bad code" dis.dis(b) assert 0 def main(files): for file in files: print file buf = open(file).read() try: co1 = compile(buf, file, "exec") except SyntaxError: print "skipped" continue co2 = compiler.compile(buf, file, "exec") co1l = extract_code_objects(co1) co2l = extract_code_objects(co2) for a, b in zip(co1l, co2l): compare(a, b) if __name__ == "__main__": import sys main(sys.argv[1:]) From jhylton@users.sourceforge.net Wed Oct 17 14:45:30 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 17 Oct 2001 06:45:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test regrtest.py,1.59,1.60 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21120/Lib/test Modified Files: regrtest.py Log Message: Make sure the output lists are sorted, even if run with -r. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -d -r1.59 -r1.60 *** regrtest.py 2001/09/28 20:16:30 1.59 --- regrtest.py 2001/10/17 13:45:28 1.60 *************** *** 195,198 **** --- 195,204 ---- if module not in save_modules and module.startswith("test."): test_support.unload(module) + + # The lists won't be sorted if running with -r + good.sort() + bad.sort() + skipped.sort() + if good and not quiet: if not bad and not skipped and len(good) > 1: From jhylton@users.sourceforge.net Wed Oct 17 14:46:31 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 17 Oct 2001 06:46:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules Setup.dist,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv21436/Modules Modified Files: Setup.dist Log Message: The Python symtable module depends on .h files that setup.py doesn't track. Index: Setup.dist =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Setup.dist,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** Setup.dist 2001/08/22 19:24:42 1.23 --- Setup.dist 2001/10/17 13:46:28 1.24 *************** *** 111,114 **** --- 111,117 ---- # ====================================================================== + # The Python symtable module depends on .h files that setup.py doesn't track + _symtable symtablemodule.c + # The SGI specific GL module: From jhylton@users.sourceforge.net Wed Oct 17 14:46:46 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 17 Oct 2001 06:46:46 -0700 Subject: [Python-checkins] CVS: python/dist/src setup.py,1.60,1.61 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv21515 Modified Files: setup.py Log Message: The Python symtable module depends on .h files that setup.py doesn't track. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -d -r1.60 -r1.61 *** setup.py 2001/10/12 21:00:48 1.60 --- setup.py 2001/10/17 13:46:44 1.61 *************** *** 215,219 **** exts.append( Extension('_hotshot', ['_hotshot.c']) ) exts.append( Extension('_weakref', ['_weakref.c']) ) - exts.append( Extension('_symtable', ['symtablemodule.c']) ) exts.append( Extension('xreadlines', ['xreadlinesmodule.c']) ) --- 215,218 ---- From gvanrossum@users.sourceforge.net Wed Oct 17 14:59:11 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 17 Oct 2001 06:59:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.107,2.108 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv25388 Modified Files: typeobject.c Log Message: Remove a bunch of stuff that's no longer needed now that update_slot() and fixup_slot_dispatchers() always select the proper slot dispatcher. This affects slot_sq_item(), slot_tp_getattro(), and slot_tp_getattr_hook(). Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.107 retrieving revision 2.108 diff -C2 -d -r2.107 -r2.108 *** typeobject.c 2001/10/17 07:15:43 2.107 --- typeobject.c 2001/10/17 13:59:09 2.108 *************** *** 2906,2919 **** func = _PyType_Lookup(self->ob_type, getitem_str); if (func != NULL) { - if (func->ob_type == &PyWrapperDescr_Type) { - PyWrapperDescrObject *wrapper = - (PyWrapperDescrObject *)func; - if (wrapper->d_base->wrapper == wrap_sq_item && - PyType_IsSubtype(self->ob_type, wrapper->d_type)) { - intargfunc f; - f = (intargfunc)(wrapper->d_wrapped); - return f(self, i); - } - } if ((f = func->ob_type->tp_descr_get) == NULL) Py_INCREF(func); --- 2906,2909 ---- *************** *** 3314,3337 **** } static PyObject * slot_tp_getattro(PyObject *self, PyObject *name) { ! PyTypeObject *tp = self->ob_type; ! PyObject *getattr; ! static PyObject *getattr_str = NULL; ! ! if (getattr_str == NULL) { ! getattr_str = PyString_InternFromString("__getattribute__"); ! if (getattr_str == NULL) ! return NULL; ! } ! getattr = _PyType_Lookup(tp, getattr_str); ! if (getattr == NULL) { ! /* Avoid further slowdowns */ ! if (tp->tp_getattro == slot_tp_getattro) ! tp->tp_getattro = PyObject_GenericGetAttr; ! return PyObject_GenericGetAttr(self, name); ! } ! return PyObject_CallFunction(getattr, "OO", self, name); } --- 3304,3324 ---- } + /* There are two slot dispatch functions for tp_getattro. + + - slot_tp_getattro() is used when __getattribute__ is overridden + but no __getattr__ hook is present; + + - slot_tp_getattr_hook() is used when a __getattr__ hook is present. + + The code in update_slot() and fixup_slot_dispatchers() always installs + slot_tp_getattr_hook(); this detects the absence of __getattr__ and then + installs the simpler slot if necessary. */ + static PyObject * slot_tp_getattro(PyObject *self, PyObject *name) { ! static PyObject *getattribute_str = NULL; ! return call_method(self, "__getattribute__", &getattribute_str, ! "(O)", name); } *************** *** 3356,3360 **** } getattr = _PyType_Lookup(tp, getattr_str); ! if (getattr == NULL && tp->tp_getattro == slot_tp_getattr_hook) { /* No __getattr__ hook: use a simpler dispatcher */ tp->tp_getattro = slot_tp_getattro; --- 3343,3347 ---- } getattr = _PyType_Lookup(tp, getattr_str); ! if (getattr == NULL) { /* No __getattr__ hook: use a simpler dispatcher */ tp->tp_getattro = slot_tp_getattro; *************** *** 3362,3382 **** } getattribute = _PyType_Lookup(tp, getattribute_str); ! if (getattribute != NULL && ! getattribute->ob_type == &PyWrapperDescr_Type && ! ((PyWrapperDescrObject *)getattribute)->d_wrapped == ! (void *)PyObject_GenericGetAttr) ! getattribute = NULL; ! if (getattr == NULL && getattribute == NULL) { ! /* Use the default dispatcher */ ! if (tp->tp_getattro == slot_tp_getattr_hook) ! tp->tp_getattro = PyObject_GenericGetAttr; ! return PyObject_GenericGetAttr(self, name); ! } ! if (getattribute == NULL) res = PyObject_GenericGetAttr(self, name); else res = PyObject_CallFunction(getattribute, "OO", self, name); ! if (getattr != NULL && ! res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); res = PyObject_CallFunction(getattr, "OO", self, name); --- 3349,3360 ---- } getattribute = _PyType_Lookup(tp, getattribute_str); ! if (getattribute == NULL || ! (getattribute->ob_type == &PyWrapperDescr_Type && ! ((PyWrapperDescrObject *)getattribute)->d_wrapped == ! (void *)PyObject_GenericGetAttr)) res = PyObject_GenericGetAttr(self, name); else res = PyObject_CallFunction(getattribute, "OO", self, name); ! if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); res = PyObject_CallFunction(getattr, "OO", self, name); From gvanrossum@users.sourceforge.net Wed Oct 17 18:21:49 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 17 Oct 2001 10:21:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib ftplib.py,1.59,1.60 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv25317 Modified Files: ftplib.py Log Message: Oops. Catching OverflowError from int() doesn't help, since it raises ValueError on too-large inputs. Index: ftplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ftplib.py,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -d -r1.59 -r1.60 *** ftplib.py 2001/10/16 19:45:52 1.59 --- ftplib.py 2001/10/17 17:21:47 1.60 *************** *** 509,513 **** try: return int(s) ! except OverflowError: return long(s) --- 509,513 ---- try: return int(s) ! except (OverflowError, ValueError): return long(s) *************** *** 559,563 **** try: return int(s) ! except OverflowError: return long(s) --- 559,563 ---- try: return int(s) ! except (OverflowError, ValueError): return long(s) From gvanrossum@users.sourceforge.net Wed Oct 17 21:26:40 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 17 Oct 2001 13:26:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects classobject.c,2.151,2.152 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv10990 Modified Files: classobject.c Log Message: Protect references to tp_descr_get and tp_dict with the appropriate test: PyType_HasFeature(t, Py_TPFLAGS_HAVE_CLASS). Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.151 retrieving revision 2.152 diff -C2 -d -r2.151 -r2.152 *** classobject.c 2001/09/30 05:58:41 2.151 --- classobject.c 2001/10/17 20:26:38 2.152 *************** *** 5,8 **** --- 5,11 ---- #include "structmember.h" + #define TP_DESCR_GET(t) \ + (PyType_HasFeature(t, Py_TPFLAGS_HAVE_CLASS) ? (t)->tp_descr_get : NULL) + /* Forward */ *************** *** 233,237 **** return NULL; } ! f = v->ob_type->tp_descr_get; if (f == NULL) Py_INCREF(v); --- 236,240 ---- return NULL; } ! f = TP_DESCR_GET(v->ob_type); if (f == NULL) Py_INCREF(v); *************** *** 694,698 **** if (v != NULL) { Py_INCREF(v); ! f = v->ob_type->tp_descr_get; if (f != NULL) { PyObject *w = f(v, (PyObject *)inst, --- 697,701 ---- if (v != NULL) { Py_INCREF(v); ! f = TP_DESCR_GET(v->ob_type); if (f != NULL) { PyObject *w = f(v, (PyObject *)inst, *************** *** 2055,2070 **** PyMethodObject *im = (PyMethodObject *)obj; PyTypeObject *tp = obj->ob_type; ! PyObject *descr, *res; ! descrgetfunc f; ! if (tp->tp_dict == NULL) { ! if (PyType_Ready(tp) < 0) ! return NULL; } - descr = _PyType_Lookup(tp, name); f = NULL; if (descr != NULL) { ! f = descr->ob_type->tp_descr_get; if (f != NULL && PyDescr_IsData(descr)) return f(descr, obj, (PyObject *)obj->ob_type); --- 2058,2075 ---- PyMethodObject *im = (PyMethodObject *)obj; PyTypeObject *tp = obj->ob_type; ! PyObject *descr = NULL, *res; ! descrgetfunc f = NULL; ! if (PyType_HasFeature(tp, Py_TPFLAGS_HAVE_CLASS)) { ! if (tp->tp_dict == NULL) { ! if (PyType_Ready(tp) < 0) ! return NULL; ! } ! descr = _PyType_Lookup(tp, name); } f = NULL; if (descr != NULL) { ! f = TP_DESCR_GET(descr->ob_type); if (f != NULL && PyDescr_IsData(descr)) return f(descr, obj, (PyObject *)obj->ob_type); From bwarsaw@users.sourceforge.net Wed Oct 17 21:51:44 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Wed, 17 Oct 2001 13:51:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email Generator.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv18469 Modified Files: Generator.py Log Message: Two merges from the mimelib project: _split_header(): Split on folding whitespace if the attempt to split on semi-colons failed. _split_header(): Patch by Matthew Cowles for fixing SF bug # 471918, Generator splitting long headers. Index: Generator.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Generator.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Generator.py 2001/10/04 17:05:11 1.4 --- Generator.py 2001/10/17 20:51:42 1.5 *************** *** 16,23 **** --- 16,25 ---- import Errors + EMPTYSTRING = '' SEMISPACE = '; ' BAR = '|' UNDERSCORE = '_' NL = '\n' + NLTAB = '\n\t' SEMINLTAB = ';\n\t' SPACE8 = ' ' * 8 *************** *** 172,187 **** if len(line.replace('\t', SPACE8)) <= maxheaderlen: rtn.append(line) else: # Try to break the line on semicolons, but if that doesn't ! # work, then just leave it alone. while len(text) > maxheaderlen: i = text.rfind(';', 0, maxheaderlen) if i < 0: - rtn.append(text) break rtn.append(text[:i]) text = text[i+1:].lstrip() ! rtn.append(text) ! return SEMINLTAB.join(rtn) # --- 174,218 ---- if len(line.replace('\t', SPACE8)) <= maxheaderlen: rtn.append(line) + SEMINLTAB.join(rtn) else: + oldlen = len(text) # Try to break the line on semicolons, but if that doesn't ! # work, try to split on folding whitespace. while len(text) > maxheaderlen: i = text.rfind(';', 0, maxheaderlen) if i < 0: break rtn.append(text[:i]) text = text[i+1:].lstrip() ! if len(text) <> oldlen: ! # Splitting on semis worked ! rtn.append(text) ! return SEMINLTAB.join(rtn) ! # Splitting on semis didn't help, so try to split on ! # whitespace. ! parts = re.split(r'(\s+)', text) ! # Watch out though for "Header: longnonsplittableline" ! if parts[0].endswith(':') and len(parts) == 3: ! return text ! first = parts.pop(0) ! sublines = [first] ! acc = len(first) ! while parts: ! len0 = len(parts[0]) ! len1 = len(parts[1]) ! if acc + len0 + len1 < maxheaderlen: ! sublines.append(parts.pop(0)) ! sublines.append(parts.pop(0)) ! acc += len0 + len1 ! else: ! # Split it here, but don't forget to ignore the ! # next whitespace-only part ! rtn.append(EMPTYSTRING.join(sublines)) ! del parts[0] ! first = parts.pop(0) ! sublines = [first] ! acc = len(first) ! rtn.append(EMPTYSTRING.join(sublines)) ! return NLTAB.join(rtn) # From bwarsaw@users.sourceforge.net Wed Oct 17 21:52:29 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Wed, 17 Oct 2001 13:52:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_email.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv18649 Modified Files: test_email.py Log Message: Two merges from the mimelib project: test_no_semis_header_splitter(): This actually should still split. test_no_split_long_header(): An example of an unsplittable line. test_no_semis_header_splitter(): Test for SF bug # 471918, Generator splitting long headers. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_email.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** test_email.py 2001/10/15 04:39:02 1.10 --- test_email.py 2001/10/17 20:52:26 1.11 *************** *** 29,32 **** --- 29,33 ---- NL = '\n' EMPTYSTRING = '' + SPACE = ' ' *************** *** 276,279 **** --- 277,313 ---- g(msg) self.assertEqual(sfp.getvalue(), openfile('msg_18.txt').read()) + + def test_no_semis_header_splitter(self): + msg = Message() + msg['From'] = 'test@dom.ain' + refparts = [] + for i in range(10): + refparts.append('<%d@dom.ain>' % i) + msg['References'] = SPACE.join(refparts) + msg.set_payload('Test') + sfp = StringIO() + g = Generator(sfp) + g(msg) + self.assertEqual(sfp.getvalue(), """\ + From: test@dom.ain + References: <0@dom.ain> <1@dom.ain> <2@dom.ain> <3@dom.ain> <4@dom.ain> + <5@dom.ain> <6@dom.ain> <7@dom.ain> <8@dom.ain> <9@dom.ain> + + Test""") + + def test_no_split_long_header(self): + msg = Message() + msg['From'] = 'test@dom.ain' + refparts = [] + msg['References'] = 'x' * 80 + msg.set_payload('Test') + sfp = StringIO() + g = Generator(sfp) + g(msg) + self.assertEqual(sfp.getvalue(), """\ + From: test@dom.ain + References: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + + Test""") From montanaro@users.sourceforge.net Wed Oct 17 23:53:35 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Wed, 17 Oct 2001 15:53:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv24483 Modified Files: xmlrpclib.py Log Message: test for int and long int overflow (allows operation on 64-bit platforms) closes patch 470254 Index: xmlrpclib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xmlrpclib.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** xmlrpclib.py 2001/10/17 01:51:04 1.13 --- xmlrpclib.py 2001/10/17 22:53:33 1.14 *************** *** 35,38 **** --- 35,39 ---- # 2001-10-01 fl Use faster escape method (80% dumps speedup) # 2001-10-10 sm Allow long ints to be passed as ints if they don't overflow + # 2001-10-17 sm test for int and long overflow (allows use on 64-bit systems) # # Copyright (c) 1999-2001 by Secret Labs AB. *************** *** 145,148 **** --- 146,152 ---- return replace(s, ">", ">",) + MAXINT = 2L**31-1 + MININT = -2L**31 + if unicode: def _stringify(string): *************** *** 463,472 **** def dump_int(self, value): self.write("%s\n" % value) dispatch[IntType] = dump_int def dump_long(self, value): ! val = int(value) ! self.write("%s\n" % val) dispatch[LongType] = dump_long --- 467,481 ---- def dump_int(self, value): + # in case ints are > 32 bits + if value > MAXINT or value < MININT: + raise OverflowError, "int exceeds XML-RPC limits" self.write("%s\n" % value) dispatch[IntType] = dump_int def dump_long(self, value): ! # in case ints are > 32 bits ! if value > MAXINT or value < MININT: ! raise OverflowError, "long int exceeds XML-RPC limits" ! self.write("%s\n" % int(value)) dispatch[LongType] = dump_long From jhylton@users.sourceforge.net Thu Oct 18 01:28:52 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 17 Oct 2001 17:28:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.181,1.182 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv12731/Modules Modified Files: socketmodule.c Log Message: Expose three OpenSSL API calls for dealing with the PRNG. Quoth the OpenSSL RAND_add man page: OpenSSL makes sure that the PRNG state is unique for each thread. On systems that provide /dev/urandom, the randomness device is used to seed the PRNG transparently. However, on all other systems, the application is responsible for seeding the PRNG by calling RAND_add(), RAND_egd(3) or RAND_load_file(3). I decided to expose RAND_add() because it's general and RAND_egd() because it's a useful special case. RAND_load_file() didn't seem to offer much over RAND_add(), so I skipped it. Also supplied RAND_status() which returns true if the PRNG is seeded and false if not. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.181 retrieving revision 1.182 diff -C2 -d -r1.181 -r1.182 *** socketmodule.c 2001/10/15 21:12:54 1.181 --- socketmodule.c 2001/10/18 00:28:50 1.182 *************** *** 212,215 **** --- 212,216 ---- #include "openssl/ssl.h" #include "openssl/err.h" + #include "openssl/rand.h" #endif /* USE_SSL */ *************** *** 2763,2766 **** --- 2764,2827 ---- }; + /* helper routines for seeding the SSL PRNG */ + static PyObject * + PySSL_RAND_add(PyObject *self, PyObject *args) + { + char *buf; + int len; + double entropy; + + if (!PyArg_ParseTuple(args, "s#d:RAND_add", &buf, &len, &entropy)) + return NULL; + RAND_add(buf, len, entropy); + Py_INCREF(Py_None); + return Py_None; + } + + static char PySSL_RAND_add_doc[] = + "RAND_add(string, entropy)\n\ + \n\ + Mix string into the OpenSSL PRNG state. entropy (a float) is a lower\n\ + bound on the entropy contained in string."; + + static PyObject * + PySSL_RAND_status(PyObject *self) + { + return PyInt_FromLong(RAND_status()); + } + + static char PySSL_RAND_status_doc[] = + "RAND_status() -> 0 or 1\n\ + \n\ + Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n\ + It is necessary to seed the PRNG with RAND_add() on some platforms before\n\ + using the ssl() function."; + + static PyObject * + PySSL_RAND_egd(PyObject *self, PyObject *arg) + { + int bytes; + + if (!PyString_Check(arg)) + return PyErr_Format(PyExc_TypeError, + "RAND_egd() expected string, found %s", + arg->ob_type->tp_name); + bytes = RAND_egd(PyString_AS_STRING(arg)); + if (bytes == -1) { + PyErr_SetString(PySSLErrorObject, + "EGD connection failed or EGD did not return " + "enough data to seed the PRNG"); + return NULL; + } + return PyInt_FromLong(bytes); + } + + static char PySSL_RAND_egd_doc[] = + "RAND_egd(path) -> bytes + \n\ + Queries the entropy gather daemon (EGD) on socket path. Returns number\n\ + of bytes read. Raises socket.sslerror if connection to EGD fails or\n\ + if it does provide enough data to seed PRNG."; + #endif /* USE_SSL */ *************** *** 2806,2809 **** --- 2867,2876 ---- {"ssl", PySocket_ssl, METH_VARARGS, ssl_doc}, + {"RAND_add", PySSL_RAND_add, METH_VARARGS, + PySSL_RAND_add_doc}, + {"RAND_egd", PySSL_RAND_egd, METH_O, + PySSL_RAND_egd_doc}, + {"RAND_status", (PyCFunction)PySSL_RAND_status, METH_NOARGS, + PySSL_RAND_status_doc}, #endif /* USE_SSL */ {NULL, NULL} /* Sentinel */ From jhylton@users.sourceforge.net Thu Oct 18 01:30:16 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 17 Oct 2001 17:30:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_socket_ssl.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv13012/Lib/test Modified Files: test_socket_ssl.py Log Message: Add trivial test cases for RAND_add() and RAND_status(). (The rest of the test cases are trivial, so I don't feel too bad.) Index: test_socket_ssl.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_socket_ssl.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_socket_ssl.py 2001/09/06 09:54:47 1.2 --- test_socket_ssl.py 2001/10/18 00:30:14 1.3 *************** *** 14,16 **** import urllib ! urllib.urlopen('https://sf.net') --- 14,30 ---- import urllib ! socket.RAND_status() ! try: ! socket.RAND_egd(1) ! except TypeError: ! pass ! else: ! print "didn't raise TypeError" ! socket.RAND_add("this is a random string", 75.0) ! ! f = urllib.urlopen('https://sf.net') ! buf = f.read() ! f.close() ! ! ! From nascheme@users.sourceforge.net Thu Oct 18 04:18:45 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Wed, 17 Oct 2001 20:18:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.84,2.85 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv13453 Modified Files: abstract.c Log Message: Fix error checking done by abstract_issubclass and abstract_isinstance. isinstance() now allows any object as the first argument and a class, a type or something with a __bases__ tuple attribute for the second argument. This closes SF patch #464992. Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.84 retrieving revision 2.85 diff -C2 -d -r2.84 -r2.85 *** abstract.c 2001/10/07 20:53:45 2.84 --- abstract.c 2001/10/18 03:18:43 2.85 *************** *** 1741,1783 **** /* isinstance(), issubclass() */ ! static int ! abstract_issubclass(PyObject *derived, PyObject *cls, int first) { static PyObject *__bases__ = NULL; PyObject *bases; - int i, n; - int r = 0; if (__bases__ == NULL) { __bases__ = PyString_FromString("__bases__"); if (__bases__ == NULL) ! return -1; } ! if (first) { ! 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; ! } ! Py_DECREF(bases); } if (derived == cls) return 1; ! bases = PyObject_GetAttr(derived, __bases__); ! if (bases == NULL || !PyTuple_Check(bases)) { ! Py_XDECREF(bases); ! PyErr_SetString(PyExc_TypeError, ! "issubclass() arg 1 must be a class"); ! return -1; ! } n = PyTuple_GET_SIZE(bases); for (i = 0; i < n; i++) { ! r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls, 0); if (r != 0) break; --- 1741,1784 ---- /* isinstance(), issubclass() */ ! static PyObject * ! abstract_get_bases(PyObject *cls) { static PyObject *__bases__ = NULL; PyObject *bases; if (__bases__ == NULL) { __bases__ = PyString_FromString("__bases__"); if (__bases__ == NULL) ! return NULL; } ! bases = PyObject_GetAttr(cls, __bases__); ! if (bases == NULL || !PyTuple_Check(bases)) { ! Py_XDECREF(bases); ! return NULL; } + return bases; + } + + + static int + abstract_issubclass(PyObject *derived, PyObject *cls) + { + PyObject *bases; + int i, n; + int r = 0; + + if (derived == cls) return 1; ! bases = abstract_get_bases(derived); ! if (bases == NULL) ! return 0; n = PyTuple_GET_SIZE(bases); for (i = 0; i < n; i++) { ! r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls); if (r != 0) break; *************** *** 1796,1805 **** int retval = 0; ! if (PyClass_Check(cls)) { ! if (PyInstance_Check(inst)) { ! PyObject *inclass = ! (PyObject*)((PyInstanceObject*)inst)->in_class; ! retval = PyClass_IsSubclass(inclass, cls); ! } } else if (PyType_Check(cls)) { --- 1797,1804 ---- int retval = 0; ! if (PyClass_Check(cls) && PyInstance_Check(inst)) { ! PyObject *inclass = ! (PyObject*)((PyInstanceObject*)inst)->in_class; ! retval = PyClass_IsSubclass(inclass, cls); } else if (PyType_Check(cls)) { *************** *** 1820,1824 **** return retval; } ! else if (!PyInstance_Check(inst)) { if (__class__ == NULL) { __class__ = PyString_FromString("__class__"); --- 1819,1830 ---- return retval; } ! else { ! PyObject *cls_bases = abstract_get_bases(cls); ! if (cls_bases == NULL) { ! PyErr_SetString(PyExc_TypeError, ! "isinstance() arg 2 must be a class or type"); ! return -1; ! } ! Py_DECREF(cls_bases); if (__class__ == NULL) { __class__ = PyString_FromString("__class__"); *************** *** 1827,1848 **** } 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 -1; } - else - retval = -1; } - else - retval = -1; - if (retval < 0) { - PyErr_SetString(PyExc_TypeError, - "isinstance() arg 2 must be a class or type " - "or tuple of those"); - } return retval; } --- 1833,1846 ---- } icls = PyObject_GetAttr(inst, __class__); ! if (icls == NULL) { ! PyErr_Clear(); ! retval = 0; ! } ! else { ! retval = abstract_issubclass(icls, cls); Py_DECREF(icls); } } return retval; } *************** *** 1854,1858 **** if (!PyClass_Check(derived) || !PyClass_Check(cls)) { ! retval = abstract_issubclass(derived, cls, 1); } else { --- 1852,1875 ---- if (!PyClass_Check(derived) || !PyClass_Check(cls)) { ! PyObject *derived_bases; ! PyObject *cls_bases; ! ! derived_bases = abstract_get_bases(derived); ! if (derived_bases == NULL) { ! PyErr_SetString(PyExc_TypeError, ! "issubclass() arg 1 must be a class"); ! return -1; ! } ! Py_DECREF(derived_bases); ! ! cls_bases = abstract_get_bases(cls); ! if (cls_bases == NULL) { ! PyErr_SetString(PyExc_TypeError, ! "issubclass() arg 2 must be a class"); ! return -1; ! } ! Py_DECREF(cls_bases); ! ! retval = abstract_issubclass(derived, cls); } else { From loewis@users.sourceforge.net Thu Oct 18 05:06:02 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 17 Oct 2001 21:06:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libos.tex,1.67,1.68 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv21278/Doc/lib Modified Files: libos.tex Log Message: Expose setgroups. Fixes feature request #468116. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -d -r1.67 -r1.68 *** libos.tex 2001/10/09 18:07:04 1.67 --- libos.tex 2001/10/18 04:06:00 1.68 *************** *** 205,208 **** --- 205,215 ---- \end{funcdesc} + \begin{funcdesc}{setgroups}{groups} + Set list of supplemental group ids associated with the current + process to \var{groups}. + Availability: \UNIX{}. + \versionadded{2.2} + \end{funcdesc} + \begin{funcdesc}{setpgrp}{} Calls the system call \cfunction{setpgrp()} or \cfunction{setpgrp(0, From loewis@users.sourceforge.net Thu Oct 18 05:06:02 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 17 Oct 2001 21:06:02 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.261,1.262 configure.in,1.269,1.270 pyconfig.h.in,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv21278 Modified Files: configure configure.in pyconfig.h.in Log Message: Expose setgroups. Fixes feature request #468116. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.261 retrieving revision 1.262 diff -C2 -d -r1.261 -r1.262 *** configure 2001/10/15 14:34:42 1.261 --- configure 2001/10/18 04:05:59 1.262 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.268 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.269 # Guess values for system-dependent variables and create Makefiles. *************** *** 4805,4809 **** nice pathconf pause plock poll pthread_init \ putenv readlink \ ! select setegid seteuid setgid \ setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \ sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ --- 4805,4809 ---- nice pathconf pause plock poll pthread_init \ putenv readlink \ ! select setegid seteuid setgid setgroups \ setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \ sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.269 retrieving revision 1.270 diff -C2 -d -r1.269 -r1.270 *** configure.in 2001/10/15 14:34:42 1.269 --- configure.in 2001/10/18 04:06:00 1.270 *************** *** 1392,1396 **** nice pathconf pause plock poll pthread_init \ putenv readlink \ ! select setegid seteuid setgid \ setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \ sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ --- 1392,1396 ---- nice pathconf pause plock poll pthread_init \ putenv readlink \ ! select setegid seteuid setgid setgroups \ setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \ sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** pyconfig.h.in 2001/10/15 14:34:42 1.15 --- pyconfig.h.in 2001/10/18 04:06:00 1.16 *************** *** 499,502 **** --- 499,505 ---- #undef HAVE_SETGID + /* Define if you have the setgroups function. */ + #undef HAVE_SETGROUPS + /* Define if you have the setlocale function. */ #undef HAVE_SETLOCALE From loewis@users.sourceforge.net Thu Oct 18 05:06:02 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 17 Oct 2001 21:06:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.281,1.282 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv21278/Misc Modified Files: NEWS Log Message: Expose setgroups. Fixes feature request #468116. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.281 retrieving revision 1.282 diff -C2 -d -r1.281 -r1.282 *** NEWS 2001/10/16 21:34:49 1.281 --- NEWS 2001/10/18 04:06:00 1.282 *************** *** 45,49 **** - readline now supports setting the startup_hook and the pre_event_hook. ! - posix supports chroot where available. - Decompression objects in the zlib module now accept an optional --- 45,49 ---- - readline now supports setting the startup_hook and the pre_event_hook. ! - posix supports chroot and setgroups where available. - Decompression objects in the zlib module now accept an optional From loewis@users.sourceforge.net Thu Oct 18 05:06:02 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 17 Oct 2001 21:06:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.200,2.201 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv21278/Modules Modified Files: posixmodule.c Log Message: Expose setgroups. Fixes feature request #468116. Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.200 retrieving revision 2.201 diff -C2 -d -r2.200 -r2.201 *** posixmodule.c 2001/10/04 22:44:26 2.200 --- posixmodule.c 2001/10/18 04:06:00 2.201 *************** *** 3128,3131 **** --- 3128,3176 ---- #endif /* HAVE_SETGID */ + #ifdef HAVE_SETGROUPS + static char posix_setgroups__doc__[] = + "setgroups(list) -> None\n\ + Set the groups of the current process to list."; + + static PyObject * + posix_setgroups(PyObject *self, PyObject *args) + { + PyObject *groups; + int i, len; + gid_t grouplist[MAX_GROUPS]; + + if (!PyArg_ParseTuple(args, "O:setgid", &groups)) + return NULL; + if (!PySequence_Check(groups)) { + PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence"); + return NULL; + } + len = PySequence_Size(groups); + if (len > MAX_GROUPS) { + PyErr_SetString(PyExc_ValueError, "too many groups"); + return NULL; + } + for(i = 0; i < len; i++) { + PyObject *elem; + elem = PySequence_GetItem(groups, i); + if (!elem) + return NULL; + if (!PyInt_Check(elem)) { + PyErr_SetString(PyExc_TypeError, + "groups must be integers"); + Py_DECREF(elem); + return NULL; + } + /* XXX: check that value fits into gid_t. */ + grouplist[i] = PyInt_AsLong(elem); + Py_DECREF(elem); + } + + if (setgroups(len, grouplist) < 0) + return posix_error(); + Py_INCREF(Py_None); + return Py_None; + } + #endif /* HAVE_SETGROUPS */ #ifdef HAVE_WAITPID *************** *** 5468,5471 **** --- 5513,5519 ---- {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__}, #endif /* HAVE_SETGID */ + #ifdef HAVE_SETGROUPS + {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__}, + #endif /* HAVE_SETGROUPS */ #ifdef HAVE_SETPGRP {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__}, From loewis@users.sourceforge.net Thu Oct 18 12:39:36 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 18 Oct 2001 04:39:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib asyncore.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv23907 Modified Files: asyncore.py Log Message: Patch #470744: Simplify __repr__ error handling. Index: asyncore.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asyncore.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** asyncore.py 2001/10/12 22:39:20 1.22 --- asyncore.py 2001/10/18 11:39:34 1.23 *************** *** 51,55 **** import socket import sys - import types import os --- 51,54 ---- *************** *** 209,213 **** def __repr__ (self): - try: status = [self.__class__.__module__+"."+self.__class__.__name__] if self.accepting and self.addr: --- 208,211 ---- *************** *** 215,234 **** elif self.connected: status.append ('connected') ! if self.addr: ! if type(self.addr) == types.TupleType: status.append ('%s:%d' % self.addr) ! else: ! status.append (self.addr) return '<%s at %#x>' % (' '.join (status), id (self)) - except: - pass - - try: - ar = repr (self.addr) - except AttributeError: - ar = 'no self.addr!' - - return '<__repr__() failed for %s instance at %x (addr=%s)>' % \ - (self.__class__.__name__, id (self), ar) def add_channel (self, map=None): --- 213,222 ---- elif self.connected: status.append ('connected') ! if self.addr is not None: ! try: status.append ('%s:%d' % self.addr) ! except TypeError: ! status.append (repr(self.addr)) return '<%s at %#x>' % (' '.join (status), id (self)) def add_channel (self, map=None): From loewis@users.sourceforge.net Thu Oct 18 12:45:21 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 18 Oct 2001 04:45:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python dynload_shlib.c,2.10,2.11 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv25029 Modified Files: dynload_shlib.c Log Message: Patch to bug #472202: Correctly recognize NetBSD before 199712. Index: dynload_shlib.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/dynload_shlib.c,v retrieving revision 2.10 retrieving revision 2.11 diff -C2 -d -r2.10 -r2.11 *** dynload_shlib.c 2001/09/05 14:24:43 2.10 --- dynload_shlib.c 2001/10/18 11:45:19 2.11 *************** *** 7,11 **** #include #include ! #if defined(__NetBSD__) && (NetBSD < 199712) #include #include --- 7,13 ---- #include #include ! #if defined(__NetBSD__) ! #include ! #if (NetBSD < 199712) #include #include *************** *** 16,21 **** #endif #endif ! #if defined(__OpenBSD__) && !defined(__ELF__) #define LEAD_UNDERSCORE "_" #else --- 18,24 ---- #endif #endif + #endif /* NetBSD */ ! #if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__) #define LEAD_UNDERSCORE "_" #else From loewis@users.sourceforge.net Thu Oct 18 15:07:14 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 18 Oct 2001 07:07:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libos.tex,1.68,1.69 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv20521 Modified Files: libos.tex Log Message: Elaborate on types and meaning of the setgroups arguments. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.68 retrieving revision 1.69 diff -C2 -d -r1.68 -r1.69 *** libos.tex 2001/10/18 04:06:00 1.68 --- libos.tex 2001/10/18 14:07:12 1.69 *************** *** 206,211 **** \begin{funcdesc}{setgroups}{groups} ! Set list of supplemental group ids associated with the current ! process to \var{groups}. Availability: \UNIX{}. \versionadded{2.2} --- 206,213 ---- \begin{funcdesc}{setgroups}{groups} ! Set the list of supplemental group ids associated with the current ! process to \var{groups}. \var{groups} must be a sequence, and each ! element must be an integer identifying a group. This operation is ! typical available only to the superuser. Availability: \UNIX{}. \versionadded{2.2} From fdrake@users.sourceforge.net Thu Oct 18 15:26:10 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 18 Oct 2001 07:26:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libinspect.tex,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv24750/lib Modified Files: libinspect.tex Log Message: Function descriptions must end as well as start! Index: libinspect.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libinspect.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** libinspect.tex 2001/10/16 23:01:06 1.6 --- libinspect.tex 2001/10/18 14:26:08 1.7 *************** *** 288,291 **** --- 288,292 ---- The optional second argument specifies the number of lines of context to return, which are centered around the current line. + \end{funcdesc} \begin{funcdesc}{getouterframes}{frame\optional{, context}} From tim_one@users.sourceforge.net Thu Oct 18 16:19:40 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 18 Oct 2001 08:19:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild BUILDno.txt,1.22,1.23 pythoncore.dsp,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv12235/python/PCbuild Modified Files: BUILDno.txt pythoncore.dsp Log Message: Bump Windows build # for 2.2b1. Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** BUILDno.txt 2001/09/27 16:28:15 1.22 --- BUILDno.txt 2001/10/18 15:19:38 1.23 *************** *** 34,37 **** --- 34,39 ---- Windows Python BUILD numbers ---------------------------- + 25 2.2b1 + 19-Oct-2001 24 2.2a4 28-Sep-2001 Index: pythoncore.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pythoncore.dsp,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** pythoncore.dsp 2001/10/12 22:08:39 1.25 --- pythoncore.dsp 2001/10/18 15:19:38 1.26 *************** *** 740,748 **** !IF "$(CFG)" == "pythoncore - Win32 Release" ! # ADD CPP /D BUILD=24 !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" ! # ADD CPP /D BUILD=24 !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" --- 740,748 ---- !IF "$(CFG)" == "pythoncore - Win32 Release" ! # ADD CPP /D BUILD=25 !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" ! # ADD CPP /D BUILD=25 !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" From fdrake@users.sourceforge.net Thu Oct 18 16:22:25 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 18 Oct 2001 08:22:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref refa1.tex,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv13312 Modified Files: refa1.tex Log Message: Fix typo reported by Michael Soulier. Index: refa1.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/refa1.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** refa1.tex 2001/08/27 20:02:17 1.6 --- refa1.tex 2001/10/18 15:22:23 1.7 *************** *** 166,170 **** terminology. ! \subsection{Definitions and rules \label{defintions}} \dfn{Names} refer to objects. Names are introduced by name binding --- 166,170 ---- terminology. ! \subsection{Definitions and rules \label{definitions}} \dfn{Names} refer to objects. Names are introduced by name binding From loewis@users.sourceforge.net Thu Oct 18 16:35:40 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 18 Oct 2001 08:35:40 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.262,1.263 configure.in,1.270,1.271 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv17976 Modified Files: configure configure.in Log Message: Use CXX in LINKCC if CXX is used to build main() and the system requires to link a C++ main using the C++ compiler. Fixes #472007. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.262 retrieving revision 1.263 diff -C2 -d -r1.262 -r1.263 *** configure 2001/10/18 04:05:59 1.262 --- configure 2001/10/18 15:35:37 1.263 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.269 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.270 [...4377 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 < *************** *** 7340,7344 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7343: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 7356,7360 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7359: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.270 retrieving revision 1.271 diff -C2 -d -r1.270 -r1.271 *** configure.in 2001/10/18 04:06:00 1.270 --- configure.in 2001/10/18 15:35:38 1.271 *************** *** 255,258 **** --- 255,261 ---- # LINKCC is the command that links the python executable -- default is $(CC). + # If CXX is set, and if it is needed to link a main function that was + # compiled with CXX, LINKCC is CXX instead. Always using CXX is undesirable: + # python might then depend on the C++ runtime # This is altered for AIX in order to build the export list before # linking. *************** *** 261,272 **** if test -z "$LINKCC" then case $ac_sys_system in AIX*) ! LINKCC="\$(srcdir)/Modules/makexp_aix Modules/python.exp \"\" \$(LIBRARY); \$(PURIFY) \$(CC)";; dgux*) ! LINKCC="LD_RUN_PATH=$libdir \$(PURIFY) \$(CC)";; Monterey64*) ! LINKCC="\$(PURIFY) \$(CC) -L/usr/lib/ia64l64";; ! *) LINKCC="\$(PURIFY) \$(CC)";; esac fi --- 264,288 ---- if test -z "$LINKCC" then + if test -z "$CXX"; then + LINKCC="\$(PURIFY) \$(CC)" + else + echo 'int main(){return 0;}' > conftest.$ac_ext + $CXX -c conftest.$ac_ext 2>&5 + if $CC -o conftest$ac_exeext conftest.$ac_objext 2>&5 \ + && test -s conftest$ac_exeext && ./conftest$ac_exeext + then + LINKCC="\$(PURIFY) \$(CC)" + else + LINKCC="\$(PURIFY) \$(CXX)" + fi + rm -fr conftest* + fi case $ac_sys_system in AIX*) ! LINKCC="\$(srcdir)/Modules/makexp_aix Modules/python.exp \"\" \$(LIBRARY); $(LINKCC)";; dgux*) ! LINKCC="LD_RUN_PATH=$libdir $(LINKCC)";; Monterey64*) ! LINKCC="$(LINKCC) -L/usr/lib/ia64l64";; esac fi From gvanrossum@users.sourceforge.net Thu Oct 18 16:49:23 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 08:49:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.125,1.126 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv23792/Misc Modified Files: ACKS Log Message: Fix SF bug #472234: type(obj) calls type->tp_init (Roeland Rengelink) The fix is a band-aid: type_call() now makes the same exception for a single-argument call to type() as type_new() was already making. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.125 retrieving revision 1.126 diff -C2 -d -r1.125 -r1.126 *** ACKS 2001/10/17 06:45:56 1.125 --- ACKS 2001/10/18 15:49:21 1.126 *************** *** 338,341 **** --- 338,342 ---- Bernhard Reiter Steven Reiz + Roeland Rengelink Jan Pieter Riegel Armin Rigo From gvanrossum@users.sourceforge.net Thu Oct 18 16:49:23 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 08:49:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.108,2.109 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv23792/Objects Modified Files: typeobject.c Log Message: Fix SF bug #472234: type(obj) calls type->tp_init (Roeland Rengelink) The fix is a band-aid: type_call() now makes the same exception for a single-argument call to type() as type_new() was already making. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.108 retrieving revision 2.109 diff -C2 -d -r2.108 -r2.109 *** typeobject.c 2001/10/17 13:59:09 2.108 --- typeobject.c 2001/10/18 15:49:21 2.109 *************** *** 148,151 **** --- 148,158 ---- obj = type->tp_new(type, args, kwds); if (obj != NULL) { + /* Ugly exception: when the call was type(something), + don't call tp_init on the result. */ + if (type == &PyType_Type && + PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 && + (kwds == NULL || + (PyDict_Check(kwds) && PyDict_Size(kwds) == 0))) + return obj; type = obj->ob_type; if (type->tp_init != NULL && From gvanrossum@users.sourceforge.net Thu Oct 18 16:49:23 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 08:49:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.90,1.91 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv23792/Lib/test Modified Files: test_descr.py Log Message: Fix SF bug #472234: type(obj) calls type->tp_init (Roeland Rengelink) The fix is a band-aid: type_call() now makes the same exception for a single-argument call to type() as type_new() was already making. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.90 retrieving revision 1.91 diff -C2 -d -r1.90 -r1.91 *** test_descr.py 2001/10/16 20:18:24 1.90 --- test_descr.py 2001/10/18 15:49:21 1.91 *************** *** 717,720 **** --- 717,732 ---- vereq(D().x, "DCBA") + # Make sure type(x) doesn't call x.__class__.__init__ + class T(type): + counter = 0 + def __init__(self, *args): + T.counter += 1 + class C: + __metaclass__ = T + vereq(T.counter, 1) + a = C() + vereq(type(a), C) + vereq(T.counter, 1) + def pymods(): if verbose: print "Testing Python subclass of module..." From jhylton@users.sourceforge.net Thu Oct 18 17:15:12 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 18 Oct 2001 09:15:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python compile.c,2.226,2.227 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv4250 Modified Files: compile.c Log Message: Fix for SF bug [ #471928 ] global made w/nested list comprehensions The symbol table pass didn't have an explicit case for the list_iter node which is used only for a nested list comprehension. As a result, the target of the list comprehension was treated as a use instead of an assignment. Fix is to add a case to symtable_node() to handle list_iter. Also, rework and document a couple of the subtler implementation issues in the symbol table pass. The symtable_node() switch statement depends on falling through the last several cases, in order to handle some of the more complicated nodes like atom. Add a comment explaining the behavior before the first fall through case. Add a comment /* fall through */ at the end of case so that it is explicitly marked as such. Move the for_stmt case out of the fall through logic, which simplifies both for_stmt and default. (The default used the local variable start to skip the first three nodes of a for_stmt when it fell through.) Rename the flag argument to symtable_assign() to def_flag and add a comment explaining its use: The third argument to symatble_assign() is a flag to be passed to symtable_add_def() if it is eventually called. The flag is useful to specify the particular type of assignment that should be recorded, e.g. an assignment caused by import. Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.226 retrieving revision 2.227 diff -C2 -d -r2.226 -r2.227 *** compile.c 2001/10/17 13:22:22 2.226 --- compile.c 2001/10/18 16:15:10 2.227 *************** *** 4992,4996 **** symtable_node(struct symtable *st, node *n) { ! int i, start = 0; loop: --- 4992,4996 ---- symtable_node(struct symtable *st, node *n) { ! int i; loop: *************** *** 5106,5115 **** } goto loop; ! /* watchout for fall-through logic below */ case argument: ! if (NCH(n) == 3) { n = CHILD(n, 2); goto loop; } case listmaker: if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == list_for) { --- 5106,5141 ---- } goto loop; ! case list_iter: ! n = CHILD(n, 0); ! if (TYPE(n) == list_for) { ! st->st_tmpname++; ! symtable_list_comprehension(st, n); ! st->st_tmpname--; ! } else { ! REQ(n, list_if); ! symtable_node(st, CHILD(n, 1)); ! if (NCH(n) == 3) { ! n = CHILD(n, 2); ! goto loop; ! } ! } ! break; ! case for_stmt: ! symtable_assign(st, CHILD(n, 1), 0); ! for (i = 3; i < NCH(n); ++i) ! if (TYPE(CHILD(n, i)) >= single_input) ! symtable_node(st, CHILD(n, i)); ! break; ! /* The remaining cases fall through to default except in ! special circumstances. This requires the individual cases ! to be coded with great care, even though they look like ! rather innocuous. Each case must double-check TYPE(n). ! */ case argument: ! if (TYPE(n) == argument && NCH(n) == 3) { n = CHILD(n, 2); goto loop; } + /* fall through */ case listmaker: if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == list_for) { *************** *** 5118,5123 **** symtable_node(st, CHILD(n, 0)); st->st_tmpname--; ! return; } case atom: if (TYPE(n) == atom && TYPE(CHILD(n, 0)) == NAME) { --- 5144,5150 ---- symtable_node(st, CHILD(n, 0)); st->st_tmpname--; ! break; } + /* fall through */ case atom: if (TYPE(n) == atom && TYPE(CHILD(n, 0)) == NAME) { *************** *** 5125,5139 **** break; } ! case for_stmt: ! if (TYPE(n) == for_stmt) { ! symtable_assign(st, CHILD(n, 1), 0); ! start = 3; ! } default: if (NCH(n) == 1) { n = CHILD(n, 0); goto loop; } ! for (i = start; i < NCH(n); ++i) if (TYPE(CHILD(n, i)) >= single_input) symtable_node(st, CHILD(n, i)); --- 5152,5165 ---- break; } ! /* fall through */ default: + /* Walk over every non-token child with a special case + for one child. + */ if (NCH(n) == 1) { n = CHILD(n, 0); goto loop; } ! for (i = 0; i < NCH(n); ++i) if (TYPE(CHILD(n, i)) >= single_input) symtable_node(st, CHILD(n, i)); *************** *** 5371,5376 **** } static void ! symtable_assign(struct symtable *st, node *n, int flag) { node *tmp; --- 5397,5408 ---- } + /* The third argument to symatble_assign() is a flag to be passed to + symtable_add_def() if it is eventually called. The flag is useful + to specify the particular type of assignment that should be + recorded, e.g. an assignment caused by import. + */ + static void ! symtable_assign(struct symtable *st, node *n, int def_flag) { node *tmp; *************** *** 5404,5408 **** } else { for (i = 0; i < NCH(n); i += 2) ! symtable_assign(st, CHILD(n, i), flag); } return; --- 5436,5440 ---- } else { for (i = 0; i < NCH(n); i += 2) ! symtable_assign(st, CHILD(n, i), def_flag); } return; *************** *** 5416,5420 **** int i; for (i = 0; i < NCH(n); i += 2) ! symtable_assign(st, CHILD(n, i), flag); return; } --- 5448,5452 ---- int i; for (i = 0; i < NCH(n); i += 2) ! symtable_assign(st, CHILD(n, i), def_flag); return; } *************** *** 5427,5431 **** if (strcmp(STR(tmp), "__debug__") == 0) symtable_warn(st, ASSIGN_DEBUG); ! symtable_add_def(st, STR(tmp), DEF_LOCAL | flag); } return; --- 5459,5463 ---- if (strcmp(STR(tmp), "__debug__") == 0) symtable_warn(st, ASSIGN_DEBUG); ! symtable_add_def(st, STR(tmp), DEF_LOCAL | def_flag); } return; *************** *** 5433,5448 **** if (NCH(n) == 3) symtable_add_def(st, STR(CHILD(n, 2)), ! DEF_LOCAL | flag); else symtable_add_def(st, STR(CHILD(CHILD(n, 0), 0)), ! DEF_LOCAL | flag); return; case dotted_name: ! symtable_add_def(st, STR(CHILD(n, 0)), DEF_LOCAL | flag); return; case NAME: ! symtable_add_def(st, STR(n), DEF_LOCAL | flag); return; default: --- 5465,5480 ---- if (NCH(n) == 3) symtable_add_def(st, STR(CHILD(n, 2)), ! DEF_LOCAL | def_flag); else symtable_add_def(st, STR(CHILD(CHILD(n, 0), 0)), ! DEF_LOCAL | def_flag); return; case dotted_name: ! symtable_add_def(st, STR(CHILD(n, 0)), DEF_LOCAL | def_flag); return; case NAME: ! symtable_add_def(st, STR(n), DEF_LOCAL | def_flag); return; default: *************** *** 5457,5461 **** for (i = 0; i < NCH(n); ++i) if (TYPE(CHILD(n, i)) >= single_input) ! symtable_assign(st, CHILD(n, i), flag); } } --- 5489,5493 ---- for (i = 0; i < NCH(n); ++i) if (TYPE(CHILD(n, i)) >= single_input) ! symtable_assign(st, CHILD(n, i), def_flag); } } From jhylton@users.sourceforge.net Thu Oct 18 17:23:13 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 18 Oct 2001 09:23:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_scope.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv7057 Modified Files: test_scope.py Log Message: Add test for local assigned to only in a nested list comp Index: test_scope.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_scope.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** test_scope.py 2001/09/25 19:29:35 1.20 --- test_scope.py 2001/10/18 16:23:11 1.21 *************** *** 486,487 **** --- 486,505 ---- warnings.resetwarnings() + + print "21. list comprehension with local variables" + + try: + print bad + except NameError: + pass + else: + print "bad should not be defined" + + def x(): + [bad for s in 'a b' for bad in s.split()] + + x() + try: + print bad + except NameError: + pass From jhylton@users.sourceforge.net Thu Oct 18 17:23:13 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 18 Oct 2001 09:23:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_scope,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv7057/output Modified Files: test_scope Log Message: Add test for local assigned to only in a nested list comp Index: test_scope =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_scope,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_scope 2001/07/30 21:55:29 1.9 --- test_scope 2001/10/18 16:23:11 1.10 *************** *** 21,22 **** --- 21,23 ---- 20. interaction with trace function 20. eval with free variables + 21. list comprehension with local variables From loewis@users.sourceforge.net Thu Oct 18 18:33:21 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 18 Oct 2001 10:33:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib asyncore.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv25053 Modified Files: asyncore.py Log Message: Reindent __repr__. Index: asyncore.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asyncore.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** asyncore.py 2001/10/18 11:39:34 1.23 --- asyncore.py 2001/10/18 17:33:19 1.24 *************** *** 208,222 **** def __repr__ (self): ! status = [self.__class__.__module__+"."+self.__class__.__name__] ! if self.accepting and self.addr: ! status.append ('listening') ! elif self.connected: ! status.append ('connected') ! if self.addr is not None: ! try: ! status.append ('%s:%d' % self.addr) ! except TypeError: ! status.append (repr(self.addr)) ! return '<%s at %#x>' % (' '.join (status), id (self)) def add_channel (self, map=None): --- 208,222 ---- def __repr__ (self): ! status = [self.__class__.__module__+"."+self.__class__.__name__] ! if self.accepting and self.addr: ! status.append ('listening') ! elif self.connected: ! status.append ('connected') ! if self.addr is not None: ! try: ! status.append ('%s:%d' % self.addr) ! except TypeError: ! status.append (repr(self.addr)) ! return '<%s at %#x>' % (' '.join (status), id (self)) def add_channel (self, map=None): From bwarsaw@users.sourceforge.net Thu Oct 18 18:50:48 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 18 Oct 2001 10:50:48 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0251.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv29162 Modified Files: pep-0251.txt Log Message: Updated some dates. Index: pep-0251.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0251.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pep-0251.txt 2001/09/04 22:38:15 1.5 --- pep-0251.txt 2001/10/18 17:50:46 1.6 *************** *** 30,38 **** 12-Dec-2001: 2.2c1 (release candidate) 14-Nov-2001: 2.2b2 ! 10-Oct-2001: 2.2b1 ! 19-Sep-2001: 2.2a4 ! 7-Sep-1001: 2.2a3 (new! an extra alpha to release more new stuff) ! 22-Aug-2001: 2.2a2 ! 18-Jul-2001: 2.2a1 --- 30,38 ---- 12-Dec-2001: 2.2c1 (release candidate) 14-Nov-2001: 2.2b2 ! 19-Oct-2001: 2.2b1 ! 28-Sep-2001: 2.2a4 [Released] ! 7-Sep-1001: 2.2a3 [Released] ! 22-Aug-2001: 2.2a2 [Released] ! 18-Jul-2001: 2.2a1 [Released] From bwarsaw@users.sourceforge.net Thu Oct 18 19:00:17 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 18 Oct 2001 11:00:17 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0238.txt,1.17,1.18 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv31217 Modified Files: pep-0238.txt Log Message: This PEP is in CVS so mark it as Final. Index: pep-0238.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0238.txt,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** pep-0238.txt 2001/09/04 03:48:48 1.17 --- pep-0238.txt 2001/10/18 18:00:15 1.18 *************** *** 3,7 **** Version: $Revision$ Author: pep@zadka.site.co.il (Moshe Zadka), guido@python.org (Guido van Rossum) ! Status: Draft Type: Standards Track Created: 11-Mar-2001 --- 3,7 ---- Version: $Revision$ Author: pep@zadka.site.co.il (Moshe Zadka), guido@python.org (Guido van Rossum) ! Status: Final Type: Standards Track Created: 11-Mar-2001 From bwarsaw@users.sourceforge.net Thu Oct 18 19:00:52 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 18 Oct 2001 11:00:52 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.135,1.136 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv31390 Modified Files: pep-0000.txt Log Message: Mark PEP 238 as Final Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.135 retrieving revision 1.136 diff -C2 -d -r1.135 -r1.136 *** pep-0000.txt 2001/09/26 05:01:09 1.135 --- pep-0000.txt 2001/10/18 18:00:50 1.136 *************** *** 45,50 **** Accepted PEPs (accepted for Python 2.2; may not be implemented yet) - S 238 Changing the Division Operator Zadka, van Rossum - SF 250 Using site-packages on Windows Moore I 251 Python 2.2 Release Schedule van Rossum, Warsaw S 252 Making Types Look More Like Classes van Rossum --- 45,48 ---- *************** *** 113,116 **** --- 111,116 ---- SF 235 Import on Case-Insensitive Platforms Peters SF 236 Back to the __future__ Peters + SF 238 Changing the Division Operator Zadka, van Rossum + SF 250 Using site-packages on Windows Moore SF 255 Simple Generators Schemenauer, et al SF 260 Simplify xrange() van Rossum *************** *** 193,197 **** SF 236 Back to the __future__ Peters S 237 Unifying Long Integers and Integers Zadka, van Rossum ! S 238 Changing the Division Operator Zadka, van Rossum S 239 Adding a Rational Type to Python Zadka S 240 Adding a Rational Literal to Python Zadka --- 193,197 ---- SF 236 Back to the __future__ Peters S 237 Unifying Long Integers and Integers Zadka, van Rossum ! SF 238 Changing the Division Operator Zadka, van Rossum S 239 Adding a Rational Type to Python Zadka S 240 Adding a Rational Literal to Python Zadka From gvanrossum@users.sourceforge.net Thu Oct 18 19:02:09 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 11:02:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib SocketServer.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv31391/Lib Modified Files: SocketServer.py Log Message: SF bug #471720: ThreadingMixIn/TCPServer forgets close Solved with a helper method that calls finish_request() and then close_request(). The code is by Max Neunhöffer. Index: SocketServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/SocketServer.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** SocketServer.py 2001/10/03 12:21:23 1.27 --- SocketServer.py 2001/10/18 18:02:07 1.28 *************** *** 449,456 **** """Mix-in class to handle each request in a new thread.""" def process_request(self, request, client_address): """Start a new thread to process the request.""" import threading ! t = threading.Thread(target = self.finish_request, args = (request, client_address)) t.start() --- 449,461 ---- """Mix-in class to handle each request in a new thread.""" + def process_request_thread(self, request, client_address): + """Same as in BaseServer but as a thread.""" + self.finish_request(request, client_address) + self.close_request(request) + def process_request(self, request, client_address): """Start a new thread to process the request.""" import threading ! t = threading.Thread(target = self.process_request_thread, args = (request, client_address)) t.start() From gvanrossum@users.sourceforge.net Thu Oct 18 19:02:09 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 11:02:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.282,1.283 ACKS,1.126,1.127 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv31391/Misc Modified Files: NEWS ACKS Log Message: SF bug #471720: ThreadingMixIn/TCPServer forgets close Solved with a helper method that calls finish_request() and then close_request(). The code is by Max Neunhöffer. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.282 retrieving revision 1.283 diff -C2 -d -r1.282 -r1.283 *** NEWS 2001/10/18 04:06:00 1.282 --- NEWS 2001/10/18 18:02:07 1.283 *************** *** 87,90 **** --- 87,93 ---- encoding. + - The SocketServer.ThreadingMixIn class now closes the request after + finish_request() returns. (Not when it errors out though.) + Tools/Demos Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.126 retrieving revision 1.127 diff -C2 -d -r1.126 -r1.127 *** ACKS 2001/10/18 15:49:21 1.126 --- ACKS 2001/10/18 18:02:07 1.127 *************** *** 297,300 **** --- 297,301 ---- Fredrik Nehr Chad Netzer + Max Neunhöffer George Neville-Neil Oscar Nierstrasz From fdrake@users.sourceforge.net Thu Oct 18 19:04:20 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 18 Oct 2001 11:04:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects weakrefobject.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv32253/Objects Modified Files: weakrefobject.c Log Message: When weakref proxies are involved in binary & ternary slot operations, the left-hand operand may not be the proxy in all cases. If it isn't, we end up doing two things: a) unwrapping something that isn't a PyWeakReference (later resulting in a core dump) and b) passing a proxy as the right-hand operand anyway, even though that can't be handled by the actual handler (maybe eventually causing a core dump). This is fixed by always unwrapping all the proxies involved before passing anything to the actual handler. Index: weakrefobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/weakrefobject.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** weakrefobject.c 2001/10/05 21:52:26 1.1 --- weakrefobject.c 2001/10/18 18:04:18 1.2 *************** *** 208,236 **** #define WRAP_UNARY(method, generic) \ static PyObject * \ ! method(PyWeakReference *proxy) { \ ! if (!proxy_checkref(proxy)) { \ ! return NULL; \ ! } \ ! return generic(PyWeakref_GET_OBJECT(proxy)); \ } #define WRAP_BINARY(method, generic) \ static PyObject * \ ! method(PyWeakReference *proxy, PyObject *v) { \ ! if (!proxy_checkref(proxy)) { \ ! return NULL; \ ! } \ ! return generic(PyWeakref_GET_OBJECT(proxy), v); \ } #define WRAP_TERNARY(method, generic) \ static PyObject * \ ! method(PyWeakReference *proxy, PyObject *v, PyObject *w) { \ ! if (!proxy_checkref(proxy)) { \ ! return NULL; \ ! } \ ! return generic(PyWeakref_GET_OBJECT(proxy), v, w); \ } --- 208,249 ---- + /* If a parameter is a proxy, check that it is still "live" and wrap it, + * replacing the original value with the raw object. Raises ReferenceError + * if the param is a dead proxy. + */ + #define UNWRAP(o) \ + if (PyWeakref_CheckProxy(o)) { \ + if (!proxy_checkref((PyWeakReference *)o)) \ + return NULL; \ + o = PyWeakref_GET_OBJECT(o); \ + } + #define WRAP_UNARY(method, generic) \ static PyObject * \ ! method(PyObject *proxy) { \ ! UNWRAP(proxy); \ ! return generic(proxy); \ } #define WRAP_BINARY(method, generic) \ static PyObject * \ ! method(PyObject *x, PyObject *y) { \ ! UNWRAP(x); \ ! UNWRAP(y); \ ! return generic(x, y); \ } + /* Note that the second and third args need to be checked for NULL since + * (at least) the tp_call slot can receive NULL for either of those args. + */ #define WRAP_TERNARY(method, generic) \ static PyObject * \ ! method(PyObject *proxy, PyObject *v, PyObject *w) { \ ! UNWRAP(proxy); \ ! if (v != NULL) \ ! UNWRAP(v); \ ! if (w != NULL) \ ! UNWRAP(w); \ ! return generic(proxy, v, w); \ } From fdrake@users.sourceforge.net Thu Oct 18 19:06:08 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 18 Oct 2001 11:06:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_weakref.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv32730/Lib/test Modified Files: test_weakref.py Log Message: Make sure we do not core dump when using proxies with the binary slot handlers. This was fixed in Objects/weakrefobject.c 1.2. Index: test_weakref.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_weakref.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_weakref.py 2001/09/20 21:33:42 1.12 --- test_weakref.py 2001/10/18 18:06:05 1.13 *************** *** 217,220 **** --- 217,228 ---- "list of refs does not match") + def test_newstyle_number_ops(self): + class F(float): + pass + f = F(2.0) + p = weakref.proxy(f) + self.assert_(p + 1.0 == 3.0) + self.assert_(1.0 + p == 3.0) # this used to SEGV + class Object: From fdrake@users.sourceforge.net Thu Oct 18 19:18:08 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 18 Oct 2001 11:18:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.283,1.284 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv3034 Modified Files: NEWS Log Message: Add a note about changes related to the weak reference objects. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.283 retrieving revision 1.284 diff -C2 -d -r1.283 -r1.284 *** NEWS 2001/10/18 18:02:07 1.283 --- NEWS 2001/10/18 18:18:06 1.284 *************** *** 37,40 **** --- 37,44 ---- example). + - Weak reference objects are now part of the core and offers a C API. + A bug which could allow a core dump when binary operations involved + proxy reference has been fixed. + Extension modules From fdrake@users.sourceforge.net Thu Oct 18 19:41:14 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 18 Oct 2001 11:41:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs boilerplate.tex,1.66,1.67 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv8280/texinputs Modified Files: boilerplate.tex Log Message: Bump release information. Index: boilerplate.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/boilerplate.tex,v retrieving revision 1.66 retrieving revision 1.67 diff -C2 -d -r1.66 -r1.67 *** boilerplate.tex 2001/09/21 21:18:16 1.66 --- boilerplate.tex 2001/10/18 18:41:12 1.67 *************** *** 6,11 **** } ! \date{\today} % XXX update before release! \release{2.2} % software release, not documentation ! \setreleaseinfo{a4} % empty for final release \setshortversion{2.2} % major.minor only for software --- 6,11 ---- } ! \date{October 19, 2001} % XXX update before release! \release{2.2} % software release, not documentation ! \setreleaseinfo{b1} % empty for final release \setshortversion{2.2} % major.minor only for software From fdrake@users.sourceforge.net Thu Oct 18 19:46:25 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 18 Oct 2001 11:46:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile,1.226,1.227 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv9569 Modified Files: Makefile Log Message: Bump version number. Remove inconsistent use of HTMLDIR. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile,v retrieving revision 1.226 retrieving revision 1.227 diff -C2 -d -r1.226 -r1.227 *** Makefile 2001/09/21 21:18:16 1.226 --- Makefile 2001/10/18 18:46:22 1.227 *************** *** 62,66 **** # Ideally, you shouldn't need to edit beyond this point - HTMLDIR= html INFODIR= info TOOLSDIR= tools --- 62,65 ---- *************** *** 68,72 **** # This is the *documentation* release, and is used to construct the file # names of the downloadable tarballs. ! RELEASE=2.2a4 PYTHON= python --- 67,71 ---- # This is the *documentation* release, and is used to construct the file # names of the downloadable tarballs. ! RELEASE=2.2b1 PYTHON= python *************** *** 369,373 **** html-$(RELEASE).tar: $(ALLHTMLFILES) ! cd $(HTMLDIR) && \ tar cf ../html-$(RELEASE).tar *.html */*.css */*.html \ */*.gif */*.txt --- 368,372 ---- html-$(RELEASE).tar: $(ALLHTMLFILES) ! cd html && \ tar cf ../html-$(RELEASE).tar *.html */*.css */*.html \ */*.gif */*.txt *************** *** 381,385 **** html-$(RELEASE).zip: $(ALLHTMLFILES) rm -f $@ ! cd $(HTMLDIR) && \ zip -q -9 ../$@ *.html */*.css */*.html */*.gif */*.txt --- 380,384 ---- html-$(RELEASE).zip: $(ALLHTMLFILES) rm -f $@ ! cd html && \ zip -q -9 ../$@ *.html */*.css */*.html */*.gif */*.txt From gvanrossum@users.sourceforge.net Thu Oct 18 19:49:39 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 11:49:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python frozen.c,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv9628/Python Modified Files: frozen.c Log Message: Fix the frozen bytecode for __hello__ (betcha didn't know that existed :-). Add a test that prevents the __hello__ bytecode from going stale unnoticed again. The test also tests the loophole noted in SF bug #404545. This test will fail right now; I'll check in the fix in a minute. Index: frozen.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/frozen.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** frozen.c 2000/09/01 23:29:28 1.9 --- frozen.c 2001/10/18 18:49:37 1.10 *************** *** 8,11 **** --- 8,15 ---- some famous words... */ + /* To regenerate this data after the bytecode or marshal format has changed, + go to ../Tools/freeze/ and freeze the hello.py file; then copy and paste + the appropriate bytes from M___main__.c. */ + static unsigned char M___hello__[] = { 99,0,0,0,0,1,0,0,0,115,15,0,0,0,127,0, *************** *** 13,26 **** 0,0,115,14,0,0,0,72,101,108,108,111,32,119,111,114, 108,100,46,46,46,78,40,0,0,0,0,40,0,0,0,0, ! 115,8,0,0,0,104,101,108,108,111,46,112,121,115,1,0, ! 0,0,63,1,0,115,0,0,0,0, }; static struct _frozen _PyImport_FrozenModules[] = { /* Test module */ ! {"__hello__", M___hello__, 90}, /* Test package (negative size indicates package-ness) */ ! {"__phello__", M___hello__, -90}, ! {"__phello__.spam", M___hello__, 90}, {0, 0, 0} /* sentinel */ }; --- 17,33 ---- 0,0,115,14,0,0,0,72,101,108,108,111,32,119,111,114, 108,100,46,46,46,78,40,0,0,0,0,40,0,0,0,0, ! 40,0,0,0,0,40,0,0,0,0,115,8,0,0,0,104, ! 101,108,108,111,46,112,121,115,1,0,0,0,63,1,0,115, ! 0,0,0,0, }; + #define SIZE sizeof(M___hello__) + static struct _frozen _PyImport_FrozenModules[] = { /* Test module */ ! {"__hello__", M___hello__, SIZE}, /* Test package (negative size indicates package-ness) */ ! {"__phello__", M___hello__, -SIZE}, ! {"__phello__.spam", M___hello__, SIZE}, {0, 0, 0} /* sentinel */ }; From gvanrossum@users.sourceforge.net Thu Oct 18 19:49:39 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 11:49:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_frozen.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv9628/Lib/test Added Files: test_frozen.py Log Message: Fix the frozen bytecode for __hello__ (betcha didn't know that existed :-). Add a test that prevents the __hello__ bytecode from going stale unnoticed again. The test also tests the loophole noted in SF bug #404545. This test will fail right now; I'll check in the fix in a minute. --- NEW FILE: test_frozen.py --- # Test the frozen module defined in frozen.c. from test_support import TestFailed import sys, os try: import __hello__ except ImportError, x: raise TestFailed, "import __hello__ failed:", x try: import __phello__ except ImportError, x: raise TestFailed, "import __phello__ failed:", x try: import __phello__.spam except ImportError, x: raise TestFailed, "import __phello__.spam failed:", x try: import __phello__.foo except ImportError: pass else: raise TestFailed, "import __phello__.foo should have failed" From gvanrossum@users.sourceforge.net Thu Oct 18 19:49:39 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 11:49:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_frozen,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv9628/Lib/test/output Added Files: test_frozen Log Message: Fix the frozen bytecode for __hello__ (betcha didn't know that existed :-). Add a test that prevents the __hello__ bytecode from going stale unnoticed again. The test also tests the loophole noted in SF bug #404545. This test will fail right now; I'll check in the fix in a minute. --- NEW FILE: test_frozen --- test_frozen Hello world... Hello world... Hello world... From gvanrossum@users.sourceforge.net Thu Oct 18 19:49:39 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 11:49:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib __phello__.foo.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv9628/Lib Added Files: __phello__.foo.py Log Message: Fix the frozen bytecode for __hello__ (betcha didn't know that existed :-). Add a test that prevents the __hello__ bytecode from going stale unnoticed again. The test also tests the loophole noted in SF bug #404545. This test will fail right now; I'll check in the fix in a minute. --- NEW FILE: __phello__.foo.py --- # This file exists as a helper for the test.test_frozen module. From gvanrossum@users.sourceforge.net Thu Oct 18 19:54:13 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 11:54:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python import.c,2.187,2.188 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv11485 Modified Files: import.c Log Message: First part of SF patch #416704: More robust freeze, by Toby Dickenson. This fixes the behavior reported by SF bug #404545, where a file x.y.py could be imported by the statement "import x.y" when there's a frozen package x (I believe even if x.y also exists as a frozen module). Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.187 retrieving revision 2.188 diff -C2 -d -r2.187 -r2.188 *** import.c 2001/10/04 14:52:06 2.187 --- import.c 2001/10/18 18:54:11 2.188 *************** *** 878,882 **** if (strlen(realname) > MAXPATHLEN) { ! PyErr_SetString(PyExc_OverflowError, "module name is too long"); return NULL; } --- 878,883 ---- if (strlen(realname) > MAXPATHLEN) { ! PyErr_SetString(PyExc_OverflowError, ! "module name is too long"); return NULL; } *************** *** 884,890 **** if (path != NULL && PyString_Check(path)) { ! /* Submodule of "frozen" package: ! Set name to the fullname, path to NULL ! and continue as "usual" */ if (PyString_Size(path) + 1 + strlen(name) >= (size_t)buflen) { PyErr_SetString(PyExc_ImportError, --- 885,890 ---- if (path != NULL && PyString_Check(path)) { ! /* The only type of submodule allowed inside a "frozen" ! package are other frozen modules or packages. */ if (PyString_Size(path) + 1 + strlen(name) >= (size_t)buflen) { PyErr_SetString(PyExc_ImportError, *************** *** 896,900 **** strcat(buf, name); strcpy(name, buf); ! path = NULL; } if (path == NULL) { --- 896,906 ---- strcat(buf, name); strcpy(name, buf); ! if (find_frozen(name) != NULL) { ! strcpy(buf, name); ! return &fd_frozen; ! } ! PyErr_Format(PyExc_ImportError, ! "No frozen submodule named %.200s", name); ! return NULL; } if (path == NULL) { *************** *** 1442,1445 **** --- 1448,1457 ---- return NULL; } + if (p->code == NULL) { + PyErr_Format(PyExc_ImportError, + "Excluded frozen object named %.200s", + name); + return NULL; + } size = p->size; if (size < 0) *************** *** 1464,1467 **** --- 1476,1485 ---- if (p == NULL) return 0; + if (p->code == NULL) { + PyErr_Format(PyExc_ImportError, + "Excluded frozen object named %.200s", + name); + return -1; + } size = p->size; ispackage = (size < 0); From tim_one@users.sourceforge.net Thu Oct 18 19:57:33 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 18 Oct 2001 11:57:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python frozen.c,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv12177/python/Python Modified Files: frozen.c Log Message: Squash compiler wng about signed/unsigned mismatch. Index: frozen.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/frozen.c,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** frozen.c 2001/10/18 18:49:37 1.10 --- frozen.c 2001/10/18 18:57:31 1.11 *************** *** 22,26 **** }; ! #define SIZE sizeof(M___hello__) static struct _frozen _PyImport_FrozenModules[] = { --- 22,26 ---- }; ! #define SIZE (int)sizeof(M___hello__) static struct _frozen _PyImport_FrozenModules[] = { From fdrake@users.sourceforge.net Thu Oct 18 19:58:32 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 18 Oct 2001 11:58:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libos.tex,1.69,1.70 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv12491/lib Modified Files: libos.tex Log Message: Straighten out the exec*() function descriptions a bit, and clarify a few points in the spawn*() description. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.69 retrieving revision 1.70 diff -C2 -d -r1.69 -r1.70 *** libos.tex 2001/10/18 14:07:12 1.69 --- libos.tex 2001/10/18 18:58:30 1.70 *************** *** 868,917 **** \end{funcdesc} ! \begin{funcdesc}{execl}{path, arg0, arg1, ...} ! This is equivalent to ! \samp{execv(\var{path}, (\var{arg0}, \var{arg1}, ...))}. ! Availability: \UNIX{}, Windows. ! \end{funcdesc} ! ! \begin{funcdesc}{execle}{path, arg0, arg1, ..., env} ! This is equivalent to ! \samp{execve(\var{path}, (\var{arg0}, \var{arg1}, ...), \var{env})}. ! Availability: \UNIX{}, Windows. ! \end{funcdesc} ! ! \begin{funcdesc}{execlp}{path, arg0, arg1, ...} ! This is equivalent to ! \samp{execvp(\var{path}, (\var{arg0}, \var{arg1}, ...))}. ! Availability: \UNIX{}, Windows. ! \end{funcdesc} ! ! \begin{funcdesc}{execv}{path, args} ! Execute the executable \var{path} with argument list \var{args}, ! replacing the current process (the Python interpreter). ! The argument list may be a tuple or list of strings. ! Availability: \UNIX{}, Windows. ! \end{funcdesc} ! \begin{funcdesc}{execve}{path, args, env} ! Execute the executable \var{path} with argument list \var{args}, ! and environment \var{env}, replacing the current process (the Python ! interpreter). ! The argument list may be a tuple or list of strings. ! The environment must be a dictionary mapping strings to strings. ! Availability: \UNIX{}, Windows. ! \end{funcdesc} ! \begin{funcdesc}{execvp}{path, args} ! This is like \samp{execv(\var{path}, \var{args})} but duplicates ! the shell's actions in searching for an executable file in a list of ! directories. The directory list is obtained from ! \code{environ['PATH']}. ! Availability: \UNIX{}, Windows. ! \end{funcdesc} ! \begin{funcdesc}{execvpe}{path, args, env} ! This is a cross between \function{execve()} and \function{execvp()}. ! The directory list is obtained from \code{\var{env}['PATH']}. ! Availability: \UNIX{}, Windows. \end{funcdesc} --- 868,915 ---- \end{funcdesc} ! \begin{funcdesc}{execl}{path, arg0, arg1, \moreargs} ! \funcline{execle}{path, arg0, arg1, \moreargs, env} ! \funcline{execlp}{file, arg0, arg1, \moreargs} ! \funcline{execlpe}{file, arg0, arg1, \moreargs, env} ! \funcline{execv}{path, args} ! \funcline{execve}{path, args, env} ! \funcline{execvp}{file, args} ! \funcline{execvpe}{file, args, env} ! These functions all execute a new program, replacing the current ! process; they do not return. On \UNIX, the new executable is loaded ! into the current process, and will have the same process ID as the ! caller. Errors will be reported as \exception{OSError} exceptions. ! The \character{l} and \character{v} variants of the ! \function{exec*()} functions differ in how command-line arguments are ! passed. The \character{l} variants are perhaps the easiest to work ! with if the number of parameters is fixed when the code is written; ! the individual parameters simply become additional parameters to the ! \function{execl*()} functions. The \character{v} variants are good ! when the number of parameters is variable, with the arguments being ! passed in a list or tuple as the \var{args} parameter. In either ! case, the arguments to the child process must start with the name of ! the command being run. ! The variants which include a \character{p} near the end ! (\function{execlp()}, \function{execlpe()}, \function{execvp()}, ! and \function{execvpe()}) will use the \envvar{PATH} environment ! variable to locate the program \var{file}. When the environment is ! being replaced (using one of the \function{exec*e()} variants, ! discussed in the next paragraph), the ! new environment is used as the source of the \envvar{PATH} variable. ! The other variants, \function{execl()}, \function{execle()}, ! \function{execv()}, and \function{execve()}, will not use the ! \envvar{PATH} variable to locate the executable; \var{path} must ! contain an appropriate absolute or relative path. ! For \function{execle()}, \function{execlpe()}, \function{execve()}, ! and \function{execvpe()} (note that these all end in \character{e}), ! the \var{env} parameter must be a mapping which is used to define the ! environment variables for the new process; the \function{execl()}, ! \function{execlp()}, \function{execv()}, and \function{execvp()} ! all cause the new process to inherit the environment of the current ! process. ! Availability: \UNIX, Windows. \end{funcdesc} *************** *** 971,980 **** \begin{funcdesc}{spawnl}{mode, path, \moreargs} \funcline{spawnle}{mode, path, \moreargs, env} ! \funcline{spawnlp}{mode, path, \moreargs} ! \funcline{spawnlpe}{mode, path, \moreargs, env} \funcline{spawnv}{mode, path, args} \funcline{spawnve}{mode, path, args, env} ! \funcline{spawnvp}{mode, path, args} ! \funcline{spawnvpe}{mode, path, args, env} Execute the program \var{path} in a new process. If \var{mode} is \constant{P_NOWAIT}, this function returns the process ID of the new --- 969,978 ---- \begin{funcdesc}{spawnl}{mode, path, \moreargs} \funcline{spawnle}{mode, path, \moreargs, env} ! \funcline{spawnlp}{mode, file, \moreargs} ! \funcline{spawnlpe}{mode, file, \moreargs, env} \funcline{spawnv}{mode, path, args} \funcline{spawnve}{mode, path, args, env} ! \funcline{spawnvp}{mode, file, args} ! \funcline{spawnvpe}{mode, file, args, env} Execute the program \var{path} in a new process. If \var{mode} is \constant{P_NOWAIT}, this function returns the process ID of the new *************** *** 983,1002 **** \var{signal} is the signal that killed the process. - For \function{spawnle()}, \function{spawnlpe()}, \function{spawnve()}, - and \function{spawnvpe()} (note that these all end in \character{e}), - the \var{env} parameter must be a mapping which is used to define the - environment variables for the new process; the \function{spawnl()}, - \function{spawnlp()}, \function{spawnv()}, and \function{spawnvp()} - all cause the new process to inherit the environment of the current - process. - - The variants which include a second \character{p} near the end - (\function{spawnlp()}, \function{spawnlpe()}, \function{spawnvp()}, - and \function{spawnvpe()}) will use the \envvar{PATH} environment - variable to locate the program \var{path}. The other variants, - \function{spawnl()}, \function{spawnle()}, \function{spawnv()}, and - \function{spawnve()}, will not use the \envvar{PATH} variable to - locate the executable. - The \character{l} and \character{v} variants of the \function{spawn*()} functions differ in how command-line arguments are --- 981,984 ---- *************** *** 1010,1013 **** --- 992,1015 ---- the command being run. + The variants which include a second \character{p} near the end + (\function{spawnlp()}, \function{spawnlpe()}, \function{spawnvp()}, + and \function{spawnvpe()}) will use the \envvar{PATH} environment + variable to locate the program \var{file}. When the environment is + being replaced (using one of the \function{spawn*e()} variants, + discussed in the next paragraph), the new environment is used as the + source of the \envvar{PATH} variable. The other variants, + \function{spawnl()}, \function{spawnle()}, \function{spawnv()}, and + \function{spawnve()}, will not use the \envvar{PATH} variable to + locate the executable; \var{path} must contain an appropriate absolute + or relative path. + + For \function{spawnle()}, \function{spawnlpe()}, \function{spawnve()}, + and \function{spawnvpe()} (note that these all end in \character{e}), + the \var{env} parameter must be a mapping which is used to define the + environment variables for the new process; the \function{spawnl()}, + \function{spawnlp()}, \function{spawnv()}, and \function{spawnvp()} + all cause the new process to inherit the environment of the current + process. + As an example, the following calls to \function{spawnlp()} and \function{spawnvpe()} are equivalent: *************** *** 1021,1025 **** \end{verbatim} ! Availability: \UNIX{}, Windows. \versionadded{1.6} \end{funcdesc} --- 1023,1028 ---- \end{verbatim} ! Availability: \UNIX, Windows. \function{spawnvp()} and ! \function{spawnvpe()} are not available on Windows. \versionadded{1.6} \end{funcdesc} From gvanrossum@users.sourceforge.net Thu Oct 18 20:15:34 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 12:15:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/freeze freeze.py,1.39,1.40 makefreeze.py,1.11,1.12 modulefinder.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/freeze In directory usw-pr-cvs1:/tmp/cvs-serv16030 Modified Files: freeze.py makefreeze.py modulefinder.py Log Message: Part 2/2 of SF patch #416704: More robust freeze, by Toby Dickenson. (With slight cosmetic improvements to shorten lines and a grammar fix to a docstring.) This addes -X and -E options to freeze. From the docstring: -X module Like -x, except the module can never be imported by the frozen binary. -E: Freeze will fail if any modules can't be found (that were not excluded using -x or -X). Index: freeze.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/freeze/freeze.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** freeze.py 2001/06/02 06:16:02 1.39 --- freeze.py 2001/10/18 19:15:31 1.40 *************** *** 43,48 **** -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 --- 43,55 ---- -h: Print this help message. ! -x module Exclude the specified module. It will still be imported ! by the frozen binary if it exists on the host system. ! ! -X module Like -x, except the module can never be imported by ! the frozen binary. + -E: Freeze will fail if any modules can't be found (that + were not excluded using -x or -X). + -i filename: Include a file with additional command line options. Used to prevent command lines growing beyond the capabilities of *************** *** 115,123 **** win = sys.platform[:3] == 'win' replace_paths = [] # settable with -r option # default the exclude list for each platform if win: exclude = exclude + [ ! 'dos', 'dospath', 'mac', 'macpath', 'macfs', 'MACFS', 'posix', 'os2', 'ce'] # modules that are imported by the Python runtime implicits = ["site", "exceptions"] --- 122,135 ---- win = sys.platform[:3] == 'win' replace_paths = [] # settable with -r option + error_if_any_missing = 0 # default the exclude list for each platform if win: exclude = exclude + [ ! 'dos', 'dospath', 'mac', 'macpath', 'macfs', 'MACFS', 'posix', ! 'os2', 'ce', 'riscos', 'riscosenviron', 'riscospath', ! ] + fail_import = exclude[:] + # modules that are imported by the Python runtime implicits = ["site", "exceptions"] *************** *** 130,141 **** subsystem = 'console' ! # parse command line by first replacing any "-i" options with the file contents. pos = 1 ! while pos < len(sys.argv)-1: # last option can not be "-i", so this ensures "pos+1" is in range! if sys.argv[pos] == '-i': try: options = string.split(open(sys.argv[pos+1]).read()) except IOError, why: ! usage("File name '%s' specified with the -i option can not be read - %s" % (sys.argv[pos+1], why) ) # Replace the '-i' and the filename with the read params. sys.argv[pos:pos+2] = options --- 142,156 ---- subsystem = 'console' ! # parse command line by first replacing any "-i" options with the ! # file contents. pos = 1 ! while pos < len(sys.argv)-1: ! # last option can not be "-i", so this ensures "pos+1" is in range! if sys.argv[pos] == '-i': try: options = string.split(open(sys.argv[pos+1]).read()) except IOError, why: ! usage("File name '%s' specified with the -i option " ! "can not be read - %s" % (sys.argv[pos+1], why) ) # Replace the '-i' and the filename with the read params. sys.argv[pos:pos+2] = options *************** *** 145,149 **** # Now parse the command line with the extras inserted. try: ! opts, args = getopt.getopt(sys.argv[1:], 'r:a:de:hmo:p:P:qs:wx:l:') except getopt.error, msg: usage('getopt error: ' + str(msg)) --- 160,164 ---- # Now parse the command line with the extras inserted. try: ! opts, args = getopt.getopt(sys.argv[1:], 'r:a:dEe:hmo:p:P:qs:wX:x:l:') except getopt.error, msg: usage('getopt error: ' + str(msg)) *************** *** 176,179 **** --- 191,199 ---- if o == '-x': exclude.append(a) + if o == '-X': + exclude.append(a) + fail_import.append(a) + if o == '-E': + error_if_any_missing = 1 if o == '-l': addn_link.append(a) *************** *** 226,230 **** # sanity check of directories and files check_dirs = [prefix, exec_prefix, binlib, incldir] ! if not win: check_dirs = check_dirs + extensions # These are not directories on Windows. for dir in check_dirs: if not os.path.exists(dir): --- 246,252 ---- # sanity check of directories and files check_dirs = [prefix, exec_prefix, binlib, incldir] ! if not win: ! # These are not directories on Windows. ! check_dirs = check_dirs + extensions for dir in check_dirs: if not os.path.exists(dir): *************** *** 351,356 **** dict = mf.modules # generate output for frozen modules ! files = makefreeze.makefreeze(base, dict, debug, custom_entry_point) # look for unfrozen modules (builtin and of unknown origin) --- 373,384 ---- dict = mf.modules + if error_if_any_missing: + missing = mf.any_missing() + if missing: + sys.exit("There are some missing modules: %r" % missing) + # generate output for frozen modules ! files = makefreeze.makefreeze(base, dict, debug, custom_entry_point, ! fail_import) # look for unfrozen modules (builtin and of unknown origin) Index: makefreeze.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/freeze/makefreeze.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** makefreeze.py 2000/07/09 03:09:57 1.11 --- makefreeze.py 2001/10/18 19:15:32 1.12 *************** *** 33,37 **** """ ! def makefreeze(base, dict, debug=0, entry_point = None): if entry_point is None: entry_point = default_entry_point done = [] --- 33,37 ---- """ ! def makefreeze(base, dict, debug=0, entry_point=None, fail_import=()): if entry_point is None: entry_point = default_entry_point done = [] *************** *** 64,67 **** --- 64,74 ---- for mod, mangled, size in done: outfp.write('\t{"%s", M_%s, %d},\n' % (mod, mangled, size)) + outfp.write('\n') + # The following modules have a NULL code pointer, indicating + # that the prozen program should not search for them on the host + # system. Importing them will *always* raise an ImportError. + # The zero value size is never used. + for mod in fail_import: + outfp.write('\t{"%s", NULL, 0},\n' % (mod,)) outfp.write(trailer) outfp.write(entry_point) Index: modulefinder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/freeze/modulefinder.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** modulefinder.py 2001/09/05 23:42:36 1.17 --- modulefinder.py 2001/10/18 19:15:32 1.18 *************** *** 357,362 **** def find_module(self, name, path): ! if name in self.excludes: ! self.msgout(3, "find_module -> Excluded") raise ImportError, name --- 357,366 ---- def find_module(self, name, path): ! if path: ! fullname = '.'.join(path)+'.'+name ! else: ! fullname = name ! if fullname in self.excludes: ! self.msgout(3, "find_module -> Excluded", fullname) raise ImportError, name *************** *** 397,400 **** --- 401,413 ---- mods.sort() print "?", key, "from", string.join(mods, ', ') + + def any_missing(self): + keys = self.badmodules.keys() + missing = [] + for key in keys: + if key not in self.excludes: + # Missing, and its not supposed to be + missing.append(key) + return missing def replace_paths_in_code(self, co): From gvanrossum@users.sourceforge.net Thu Oct 18 20:20:27 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 12:20:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.284,1.285 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv18542 Modified Files: NEWS Log Message: Note stricter tp_compare return value requirements. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.284 retrieving revision 1.285 diff -C2 -d -r1.284 -r1.285 *** NEWS 2001/10/18 18:18:06 1.284 --- NEWS 2001/10/18 19:20:25 1.285 *************** *** 104,107 **** --- 104,113 ---- C API + - The documentation for the tp_compare slot is updated to require that + the return value must be -1, 0, 1; an arbitrary number <0 or >0 is + not correct. This is not yet enforced but will be enforced in + Python 2.3; even later, we may use -2 to indicate errors and +2 for + "NotImplemented". Right now, -1 should be used for an error return. + - PyLong_AsLongLong() now accepts int (as well as long) arguments. Consequently, PyArg_ParseTuple's 'L' code also accepts int (as well From fdrake@users.sourceforge.net Thu Oct 18 20:21:48 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 18 Oct 2001 12:21:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects weakrefobject.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv19027/Objects Modified Files: weakrefobject.c Log Message: Remove an unnecessary check for NULL. Index: weakrefobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/weakrefobject.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** weakrefobject.c 2001/10/18 18:04:18 1.2 --- weakrefobject.c 2001/10/18 19:21:46 1.3 *************** *** 234,239 **** } ! /* Note that the second and third args need to be checked for NULL since ! * (at least) the tp_call slot can receive NULL for either of those args. */ #define WRAP_TERNARY(method, generic) \ --- 234,239 ---- } ! /* Note that the third arg needs to be checked for NULL since the tp_call ! * slot can receive NULL for this arg. */ #define WRAP_TERNARY(method, generic) \ *************** *** 241,246 **** method(PyObject *proxy, PyObject *v, PyObject *w) { \ UNWRAP(proxy); \ ! if (v != NULL) \ ! UNWRAP(v); \ if (w != NULL) \ UNWRAP(w); \ --- 241,245 ---- method(PyObject *proxy, PyObject *v, PyObject *w) { \ UNWRAP(proxy); \ ! UNWRAP(v); \ if (w != NULL) \ UNWRAP(w); \ From fdrake@users.sourceforge.net Thu Oct 18 20:28:31 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 18 Oct 2001 12:28:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_weakref.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20603/Lib/test Modified Files: test_weakref.py Log Message: Add a test for calling a weakref proxy with a dictionary of keyword args. Index: test_weakref.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_weakref.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** test_weakref.py 2001/10/18 18:06:05 1.13 --- test_weakref.py 2001/10/18 19:28:29 1.14 *************** *** 161,164 **** --- 161,167 ---- self.assert_(o.bar == 'twinkies!', "call through proxy not passed through to original") + ref1(x='Splat.') + self.assert_(o.bar == 'Splat.', + "call through proxy not passed through to original") # expect due to too few args From effbot@users.sourceforge.net Thu Oct 18 20:30:17 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Thu, 18 Oct 2001 12:30:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.66,2.67 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv20834/Modules Modified Files: _sre.c Log Message: SRE bug #441409: compile should raise error for non-strings SRE bug #432570, 448951: reset group after failed match also bumped version number to 2.2.0 Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.66 retrieving revision 2.67 diff -C2 -d -r2.66 -r2.67 *** _sre.c 2001/09/18 20:55:24 2.66 --- _sre.c 2001/10/18 19:30:11 2.67 *************** *** 33,36 **** --- 33,37 ---- * 2001-07-01 fl added BIGCHARSET support (from Martin von Loewis) * 2001-09-18 fl added _getliteral helper + * 2001-10-18 fl fixed group reset issue (from Matthew Mueller) * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. *************** *** 48,52 **** static char copyright[] = ! " SRE 2.1.1 Copyright (c) 1997-2001 by Secret Labs AB "; #include "Python.h" --- 49,53 ---- static char copyright[] = ! " SRE 2.2.0 Copyright (c) 1997-2001 by Secret Labs AB "; #include "Python.h" *************** *** 1062,1065 **** --- 1063,1067 ---- return i; i = mark_restore(state, 0, lastmark); + state->lastmark = lastmark; if (i < 0) return i; From effbot@users.sourceforge.net Thu Oct 18 20:30:18 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Thu, 18 Oct 2001 12:30:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sre.py,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv20834/Lib Modified Files: sre.py Log Message: SRE bug #441409: compile should raise error for non-strings SRE bug #432570, 448951: reset group after failed match also bumped version number to 2.2.0 Index: sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** sre.py 2001/09/18 20:55:24 1.38 --- sre.py 2001/10/18 19:30:15 1.39 *************** *** 105,109 **** "UNICODE", "error" ] ! __version__ = "2.1.1" # this module works under 1.5.2 and later. don't use string methods --- 105,109 ---- "UNICODE", "error" ] ! __version__ = "2.2.0" # this module works under 1.5.2 and later. don't use string methods *************** *** 198,201 **** --- 198,203 ---- _cache_repl = {} + _pattern_type = type(sre_compile.compile("", 0)) + _MAXCACHE = 100 *************** *** 210,215 **** return p pattern, flags = key ! if type(pattern) not in sre_compile.STRING_TYPES: return pattern try: p = sre_compile.compile(pattern, flags) --- 212,219 ---- return p pattern, flags = key ! if type(pattern) is _pattern_type: return pattern + if type(pattern) not in sre_compile.STRING_TYPES: + raise TypeError, "first argument must be string or compiled pattern" try: p = sre_compile.compile(pattern, flags) *************** *** 313,317 **** return _compile, (p.pattern, p.flags) ! copy_reg.pickle(type(_compile("", 0)), _pickle, _compile) # -------------------------------------------------------------------- --- 317,321 ---- return _compile, (p.pattern, p.flags) ! copy_reg.pickle(_pattern_type, _pickle, _compile) # -------------------------------------------------------------------- From effbot@users.sourceforge.net Thu Oct 18 20:30:18 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Thu, 18 Oct 2001 12:30:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_sre.py,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20834/Lib/test Modified Files: test_sre.py Log Message: SRE bug #441409: compile should raise error for non-strings SRE bug #432570, 448951: reset group after failed match also bumped version number to 2.2.0 Index: test_sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sre.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** test_sre.py 2001/09/18 20:55:24 1.29 --- test_sre.py 2001/10/18 19:30:16 1.30 *************** *** 205,208 **** --- 205,214 ---- test(r"""pat.match('ac').group(1, 'b2', 3)""", ('a', None, 'c')) + # bug 448951 (similar to 429357, but with single char match) + # (Also test greedy matches.) + for op in '','?','*': + test(r"""sre.match(r'((.%s):)?z', 'z').groups()"""%op, (None, None)) + test(r"""sre.match(r'((.%s):)?z', 'a:z').groups()"""%op, ('a:', 'a')) + if verbose: print "Running tests on sre.escape" From fdrake@users.sourceforge.net Thu Oct 18 20:34:02 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 18 Oct 2001 12:34:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_hotshot.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv22760/Lib/test Modified Files: test_hotshot.py Log Message: Do not expect line number events when running under "python -O". The right fix is to generate line number events anyway ;-), but this will have to do for now. Index: test_hotshot.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_hotshot.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_hotshot.py 2001/10/13 03:00:11 1.3 --- test_hotshot.py 2001/10/18 19:34:00 1.4 *************** *** 54,57 **** --- 54,60 ---- def check_events(self, expected): events = self.get_events_wotime() + if not __debug__: + # Running under -O, so we don't get LINE events + expected = [ev for ev in expected if ev[0] != LINE] if events != expected: self.fail( From bwarsaw@users.sourceforge.net Thu Oct 18 20:41:50 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 18 Oct 2001 12:41:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libgettext.tex,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv25652 Modified Files: libgettext.tex Log Message: Some minor clarifications for find()'s arguments based on SF bug #463572. Closing. Index: libgettext.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libgettext.tex,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** libgettext.tex 2001/07/06 19:28:48 1.8 --- libgettext.tex 2001/10/18 19:41:48 1.9 *************** *** 99,105 **** This function implements the standard \file{.mo} file search algorithm. It takes a \var{domain}, identical to what ! \function{textdomain()} takes, and optionally a \var{localedir} (as in ! \function{bindtextdomain()}), and a list of languages. All arguments ! are strings. If \var{localedir} is not given, then the default system locale --- 99,105 ---- This function implements the standard \file{.mo} file search algorithm. It takes a \var{domain}, identical to what ! \function{textdomain()} takes. Optional \var{localedir} is as in ! \function{bindtextdomain()} Optional \var{languages} is a list of ! strings, where each string is a language code. If \var{localedir} is not given, then the default system locale *************** *** 109,114 **** \envvar{LC_ALL}, \envvar{LC_MESSAGES}, and \envvar{LANG}. The first one returning a non-empty value is used for the \var{languages} variable. ! The environment variables can contain a colon separated list of ! languages, which will be split. \function{find()} then expands and normalizes the languages, and then --- 109,115 ---- \envvar{LC_ALL}, \envvar{LC_MESSAGES}, and \envvar{LANG}. The first one returning a non-empty value is used for the \var{languages} variable. ! The environment variables should contain a colon separated list of ! languages, which will be split on the colon to produce the expected ! list of language code strings. \function{find()} then expands and normalizes the languages, and then From gvanrossum@users.sourceforge.net Thu Oct 18 20:44:12 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 12:44:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.201,2.202 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv26104/Modules Modified Files: posixmodule.c Log Message: Shut up warnings for setgroups() on Linux -- you have to #include it seems. This requires yet another configure test. Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.201 retrieving revision 2.202 diff -C2 -d -r2.201 -r2.202 *** posixmodule.c 2001/10/18 04:06:00 2.201 --- posixmodule.c 2001/10/18 19:44:10 2.202 *************** *** 29,32 **** --- 29,33 ---- #include #include + #ifdef HAVE_SYS_WAIT_H #include /* For WNOHANG */ *************** *** 40,43 **** --- 41,48 ---- #include #endif /* HAVE_FCNTL_H */ + + #ifdef HAVE_GRP_H + #include + #endif /* pick up declaration of confstr on some systems? */ From gvanrossum@users.sourceforge.net Thu Oct 18 20:44:12 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 12:44:12 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.263,1.264 configure.in,1.271,1.272 pyconfig.h.in,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv26104 Modified Files: configure configure.in pyconfig.h.in Log Message: Shut up warnings for setgroups() on Linux -- you have to #include it seems. This requires yet another configure test. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.263 retrieving revision 1.264 diff -C2 -d -r1.263 -r1.264 *** configure 2001/10/18 15:35:37 1.263 --- configure 2001/10/18 19:44:08 1.264 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.270 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.272 # Guess values for system-dependent variables and create Makefiles. *************** *** 1969,1973 **** fi ! for ac_hdr in dlfcn.h fcntl.h limits.h langinfo.h locale.h \ ncurses.h poll.h pthread.h \ signal.h stdarg.h stddef.h stdlib.h thread.h unistd.h utime.h termios.h \ --- 1969,1973 ---- fi ! for ac_hdr in dlfcn.h fcntl.h grp.h limits.h langinfo.h locale.h \ ncurses.h poll.h pthread.h \ signal.h stdarg.h stddef.h stdlib.h thread.h unistd.h utime.h termios.h \ Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.271 retrieving revision 1.272 diff -C2 -d -r1.271 -r1.272 *** configure.in 2001/10/18 15:35:38 1.271 --- configure.in 2001/10/18 19:44:10 1.272 *************** *** 500,504 **** # checks for header files AC_HEADER_STDC ! AC_CHECK_HEADERS(dlfcn.h fcntl.h limits.h langinfo.h locale.h \ ncurses.h poll.h pthread.h \ signal.h stdarg.h stddef.h stdlib.h thread.h unistd.h utime.h termios.h \ --- 500,504 ---- # checks for header files AC_HEADER_STDC ! AC_CHECK_HEADERS(dlfcn.h fcntl.h grp.h limits.h langinfo.h locale.h \ ncurses.h poll.h pthread.h \ signal.h stdarg.h stddef.h stdlib.h thread.h unistd.h utime.h termios.h \ Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** pyconfig.h.in 2001/10/18 04:06:00 1.16 --- pyconfig.h.in 2001/10/18 19:44:10 1.17 *************** *** 313,319 **** #undef SIZEOF_WCHAR_T - /* Define if you have the _getpty function. */ - #undef HAVE__GETPTY - /* Define if you have the alarm function. */ #undef HAVE_ALARM --- 313,316 ---- *************** *** 418,421 **** --- 415,421 ---- #undef HAVE_GETPRIORITY + /* Define if you have the _getpty function. */ + #undef HAVE__GETPTY + /* Define if you have the getpwent function. */ #undef HAVE_GETPWENT *************** *** 592,603 **** #undef HAVE_WAITPID ! /* Define if you have the header file. */ ! #undef HAVE_DB_H /* Define if you have the header file. */ #undef HAVE_DB1_NDBM_H ! /* Define if you have the header file. */ ! #undef HAVE_DB_185_H /* Define if you have the header file. */ --- 592,603 ---- #undef HAVE_WAITPID ! /* Define if you have the header file. */ ! #undef HAVE_DB_185_H /* Define if you have the header file. */ #undef HAVE_DB1_NDBM_H ! /* Define if you have the header file. */ ! #undef HAVE_DB_H /* Define if you have the header file. */ *************** *** 612,615 **** --- 612,618 ---- /* Define if you have the header file. */ #undef HAVE_GDBM_NDBM_H + + /* Define if you have the header file. */ + #undef HAVE_GRP_H /* Define if you have the header file. */ From tim_one@users.sourceforge.net Thu Oct 18 20:56:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 18 Oct 2001 12:56:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.54,1.55 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv27875/python/Lib Modified Files: pydoc.py Log Message: SF bug [#472347] pydoc and properties. The GUI-mode code to display properties blew up if the property functions (get, set, etc) weren't simply methods (or functions). "The problem" here is really that the generic document() method dispatches to one of .doc{routine, class, module, other}(), but all of those require a different(!) number of arguments. Thus document isn't general-purpose at all: you have to know exactly what kind of thing is it you're going to document first, in order to pass the correct number of arguments to .document for it to pass on. As an expedient hack, just tacked "*ignored" on to the end of the formal argument lists for the .docXXX routines so that .document's caller doesn't have to know in advance which path .document is going to take. Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -d -r1.54 -r1.55 *** pydoc.py 2001/09/27 04:08:16 1.54 --- pydoc.py 2001/10/18 19:56:16 1.55 *************** *** 487,491 **** return '

    \n%s
    \n' % result ! def docmodule(self, object, name=None, mod=None): """Produce HTML documentation for a module object.""" name = object.__name__ # ignore the passed-in name --- 487,491 ---- return '
    \n%s
    \n' % result ! def docmodule(self, object, name=None, mod=None, *ignored): """Produce HTML documentation for a module object.""" name = object.__name__ # ignore the passed-in name *************** *** 602,606 **** return result ! def docclass(self, object, name=None, mod=None, funcs={}, classes={}): """Produce HTML documentation for a class object.""" realname = object.__name__ --- 602,607 ---- return result ! def docclass(self, object, name=None, mod=None, funcs={}, classes={}, ! *ignored): """Produce HTML documentation for a class object.""" realname = object.__name__ *************** *** 801,805 **** return '
    %s
    %s
    \n' % (decl, doc) ! def docother(self, object, name=None, mod=None): """Produce HTML documentation for a data object.""" lhs = name and '%s = ' % name or '' --- 802,806 ---- return '
    %s
    %s
    \n' % (decl, doc) ! def docother(self, object, name=None, mod=None, *ignored): """Produce HTML documentation for a data object.""" lhs = name and '%s = ' % name or '' From tim_one@users.sourceforge.net Thu Oct 18 20:56:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 18 Oct 2001 12:56:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test pydocfodder.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv27875/python/Lib/test Modified Files: pydocfodder.py Log Message: SF bug [#472347] pydoc and properties. The GUI-mode code to display properties blew up if the property functions (get, set, etc) weren't simply methods (or functions). "The problem" here is really that the generic document() method dispatches to one of .doc{routine, class, module, other}(), but all of those require a different(!) number of arguments. Thus document isn't general-purpose at all: you have to know exactly what kind of thing is it you're going to document first, in order to pass the correct number of arguments to .document for it to pass on. As an expedient hack, just tacked "*ignored" on to the end of the formal argument lists for the .docXXX routines so that .document's caller doesn't have to know in advance which path .document is going to take. Index: pydocfodder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pydocfodder.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pydocfodder.py 2001/10/15 22:59:59 1.2 --- pydocfodder.py 2001/10/18 19:56:17 1.3 *************** *** 178,179 **** --- 178,210 ---- def D_method(self): "Method defined in D." + + class FunkyProperties(object): + """From SF bug 472347, by Roeland Rengelink. + + Property getters etc may not be vanilla functions or methods, + and this used to make GUI pydoc blow up. + """ + + def __init__(self): + self.desc = {'x':0} + + class get_desc: + def __init__(self, attr): + self.attr = attr + def __call__(self, inst): + print 'Get called', self, inst + return inst.desc[self.attr] + class set_desc: + def __init__(self, attr): + self.attr = attr + def __call__(self, inst, val): + print 'Set called', self, inst, val + inst.desc[self.attr] = val + class del_desc: + def __init__(self, attr): + self.attr = attr + def __call__(self, inst): + print 'Del called', self, inst + del inst.desc[self.attr] + + x = property(get_desc('x'), set_desc('x'), del_desc('x'), 'prop x') From gvanrossum@users.sourceforge.net Thu Oct 18 21:34:27 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 13:34:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include structseq.h,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv7266/Include Added Files: structseq.h Log Message: SF patch #462296: Add attributes to os.stat results; by Nick Mathewson. This is a big one, touching lots of files. Some of the platforms aren't tested yet. Briefly, this changes the return value of the os/posix functions stat(), fstat(), statvfs(), fstatvfs(), and the time functions localtime(), gmtime(), and strptime() from tuples into pseudo-sequences. When accessed as a sequence, they behave exactly as before. But they also have attributes like st_mtime or tm_year. The stat return value, moreover, has a few platform-specific attributes that are not available through the sequence interface (because everybody expects the sequence to have a fixed length, these couldn't be added there). If your platform's struct stat doesn't define st_blksize, st_blocks or st_rdev, they won't be accessible from Python either. (Still missing is a documentation update.) --- NEW FILE: structseq.h --- /* Tuple object interface */ #ifndef Py_STRUCTSEQ_H #define Py_STRUCTSEQ_H #ifdef __cplusplus extern "C" { #endif typedef struct PyStructSequence_Field { char *name; char *doc; } PyStructSequence_Field; typedef struct PyStructSequence_Desc { char *name; char *doc; struct PyStructSequence_Field *fields; int n_in_sequence; } PyStructSequence_Desc; extern DL_IMPORT(void) PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc); extern DL_IMPORT(PyObject *) PyStructSequence_New(PyTypeObject* type); typedef struct { PyObject_VAR_HEAD PyObject *ob_item[1]; } PyStructSequence; /* Macro, *only* to be used to fill in brand new objects */ #define PyStructSequence_SET_ITEM(op, i, v) \ (((PyStructSequence *)(op))->ob_item[i] = v) #ifdef __cplusplus } #endif #endif /* !Py_STRUCTSEQ_H */ From gvanrossum@users.sourceforge.net Thu Oct 18 21:34:27 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 13:34:27 -0700 Subject: [Python-checkins] CVS: python/dist/src Makefile.pre.in,1.63,1.64 configure,1.264,1.265 configure.in,1.272,1.273 pyconfig.h.in,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv7266 Modified Files: Makefile.pre.in configure configure.in pyconfig.h.in Log Message: SF patch #462296: Add attributes to os.stat results; by Nick Mathewson. This is a big one, touching lots of files. Some of the platforms aren't tested yet. Briefly, this changes the return value of the os/posix functions stat(), fstat(), statvfs(), fstatvfs(), and the time functions localtime(), gmtime(), and strptime() from tuples into pseudo-sequences. When accessed as a sequence, they behave exactly as before. But they also have attributes like st_mtime or tm_year. The stat return value, moreover, has a few platform-specific attributes that are not available through the sequence interface (because everybody expects the sequence to have a fixed length, these couldn't be added there). If your platform's struct stat doesn't define st_blksize, st_blocks or st_rdev, they won't be accessible from Python either. (Still missing is a documentation update.) Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.63 retrieving revision 1.64 diff -C2 -d -r1.63 -r1.64 *** Makefile.pre.in 2001/10/17 06:26:53 1.63 --- Makefile.pre.in 2001/10/18 20:34:24 1.64 *************** *** 264,267 **** --- 264,268 ---- Objects/sliceobject.o \ Objects/stringobject.o \ + Objects/structseq.o \ Objects/tupleobject.o \ Objects/typeobject.o \ *************** *** 466,469 **** --- 467,471 ---- Include/sliceobject.h \ Include/stringobject.h \ + Include/structseq.h \ Include/structmember.h \ Include/symtable.h \ Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.264 retrieving revision 1.265 diff -C2 -d -r1.264 -r1.265 *** configure 2001/10/18 19:44:08 1.264 --- configure 2001/10/18 20:34:24 1.265 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.272 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.273 [...1321 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 < *************** *** 7356,7360 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7359: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 7460,7464 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7463: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.272 retrieving revision 1.273 diff -C2 -d -r1.272 -r1.273 *** configure.in 2001/10/18 19:44:10 1.272 --- configure.in 2001/10/18 20:34:24 1.273 *************** *** 1535,1538 **** --- 1535,1541 ---- AC_STRUCT_TM AC_STRUCT_TIMEZONE + AC_STRUCT_ST_RDEV + AC_STRUCT_ST_BLKSIZE + AC_STRUCT_ST_BLOCKS AC_MSG_CHECKING(for time.h that defines altzone) Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** pyconfig.h.in 2001/10/18 19:44:10 1.17 --- pyconfig.h.in 2001/10/18 20:34:24 1.18 *************** *** 19,22 **** --- 19,31 ---- #undef gid_t + /* Define if your struct stat has st_blksize. */ + #undef HAVE_ST_BLKSIZE + + /* Define if your struct stat has st_blocks. */ + #undef HAVE_ST_BLOCKS + + /* Define if your struct stat has st_rdev. */ + #undef HAVE_ST_RDEV + /* Define if your struct tm has tm_zone. */ #undef HAVE_TM_ZONE From gvanrossum@users.sourceforge.net Thu Oct 18 21:34:27 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 13:34:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_os.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv7266/Lib/test Modified Files: test_os.py Log Message: SF patch #462296: Add attributes to os.stat results; by Nick Mathewson. This is a big one, touching lots of files. Some of the platforms aren't tested yet. Briefly, this changes the return value of the os/posix functions stat(), fstat(), statvfs(), fstatvfs(), and the time functions localtime(), gmtime(), and strptime() from tuples into pseudo-sequences. When accessed as a sequence, they behave exactly as before. But they also have attributes like st_mtime or tm_year. The stat return value, moreover, has a few platform-specific attributes that are not available through the sequence interface (because everybody expects the sequence to have a fixed length, these couldn't be added there). If your platform's struct stat doesn't define st_blksize, st_blocks or st_rdev, they won't be accessible from Python either. (Still missing is a documentation update.) Index: test_os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_os.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_os.py 2001/09/20 21:33:42 1.6 --- test_os.py 2001/10/18 20:34:25 1.7 *************** *** 12,16 **** from test_support import TESTFN, run_unittest - class TemporaryFileTests(unittest.TestCase): def setUp(self): --- 12,15 ---- *************** *** 62,69 **** self.check_tempfile(os.tmpnam()) def test_main(): run_unittest(TemporaryFileTests) ! if __name__ == "__main__": --- 61,186 ---- self.check_tempfile(os.tmpnam()) + # Test attributes on return values from os.*stat* family. + class StatAttributeTests(unittest.TestCase): + def setUp(self): + os.mkdir(TESTFN) + self.fname = os.path.join(TESTFN, "f1") + f = open(self.fname, 'wb') + f.write("ABC") + f.close() + + def tearDown(self): + os.unlink(self.fname) + os.rmdir(TESTFN) + def test_stat_attributes(self): + if not hasattr(os, "stat"): + return + + import stat + result = os.stat(self.fname) + + # Make sure direct access works + self.assertEquals(result[stat.ST_SIZE], 3) + self.assertEquals(result.st_size, 3) + + import sys + + # Make sure all the attributes are there + members = dir(result) + for name in dir(stat): + if name[:3] == 'ST_': + attr = name.lower() + self.assertEquals(getattr(result, attr), + result[getattr(stat, name)]) + self.assert_(attr in members) + + try: + result[200] + self.fail("No exception thrown") + except IndexError: + pass + + # Make sure that assignment fails + try: + result.st_mode = 1 + self.fail("No exception thrown") + except TypeError: + pass + + try: + result.st_rdev = 1 + self.fail("No exception thrown") + except TypeError: + pass + + try: + result.parrot = 1 + self.fail("No exception thrown") + except AttributeError: + pass + + # Use the stat_result constructor with a too-short tuple. + try: + result2 = os.stat_result((10,)) + self.fail("No exception thrown") + except TypeError: + pass + + # Use the constructr with a too-long tuple. + try: + result2 = os.stat_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)) + except TypeError: + pass + + + def test_statvfs_attributes(self): + if not hasattr(os, "statvfs"): + return + + import statvfs + result = os.statvfs(self.fname) + + # Make sure direct access works + self.assertEquals(result.f_bfree, result[statvfs.F_BFREE]) + + # Make sure all the attributes are there + members = dir(result) + for name in dir(statvfs): + if name[:2] == 'F_': + attr = name.lower() + self.assertEquals(getattr(result, attr), + result[getattr(statvfs, name)]) + self.assert_(attr in members) + + # Make sure that assignment really fails + try: + result.f_bfree = 1 + self.fail("No exception thrown") + except TypeError: + pass + + try: + result.parrot = 1 + self.fail("No exception thrown") + except AttributeError: + pass + + # Use the constructor with a too-short tuple. + try: + result2 = os.statvfs_result((10,)) + self.fail("No exception thrown") + except TypeError: + pass + + # Use the constructr with a too-long tuple. + try: + result2 = os.statvfs_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)) + except TypeError: + pass + def test_main(): run_unittest(TemporaryFileTests) ! run_unittest(StatAttributeTests) if __name__ == "__main__": From gvanrossum@users.sourceforge.net Thu Oct 18 21:34:27 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 13:34:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules macmodule.c,1.45,1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory usw-pr-cvs1:/tmp/cvs-serv7266/Mac/Modules Modified Files: macmodule.c Log Message: SF patch #462296: Add attributes to os.stat results; by Nick Mathewson. This is a big one, touching lots of files. Some of the platforms aren't tested yet. Briefly, this changes the return value of the os/posix functions stat(), fstat(), statvfs(), fstatvfs(), and the time functions localtime(), gmtime(), and strptime() from tuples into pseudo-sequences. When accessed as a sequence, they behave exactly as before. But they also have attributes like st_mtime or tm_year. The stat return value, moreover, has a few platform-specific attributes that are not available through the sequence interface (because everybody expects the sequence to have a fixed length, these couldn't be added there). If your platform's struct stat doesn't define st_blksize, st_blocks or st_rdev, they won't be accessible from Python either. (Still missing is a documentation update.) Index: macmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/macmodule.c,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** macmodule.c 2001/08/11 23:18:55 1.45 --- macmodule.c 2001/10/18 20:34:25 1.46 *************** *** 26,29 **** --- 26,30 ---- #include "Python.h" + #include "structseq.h" #include "ceval.h" *************** *** 461,469 **** --- 462,578 ---- } + static char stat_result__doc__[] = + "stat_result: Result from stat or lstat.\n\n\ + This object may be accessed either as a tuple of\n\ + (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\ + or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\ + \n\ + Macintosh: The fields st_rsize, st_creator, and st_type are available from\n\ + os.xstat.\n\ + \n\ + See os.stat for more information.\n"; + + #define COMMON_STAT_RESULT_FIELDS \ + { "st_mode", "protection bits" }, \ + { "st_ino", "inode" }, \ + { "st_dev", "device" }, \ + { "st_nlink", "number of hard links" }, \ + { "st_uid", "user ID of owner" }, \ + { "st_gid", "group ID of owner" }, \ + { "st_size", "total size, in bytes" }, \ + { "st_atime", "time of last access" }, \ + { "st_mtime", "time of last modification" }, \ + { "st_ctime", "time of last change" }, + + + + static PyStructSequence_Field stat_result_fields[] = { + COMMON_STAT_RESULT_FIELDS + {0} + }; + + static PyStructSequence_Desc stat_result_desc = { + "stat_result", + stat_result__doc__, + stat_result_fields, + 10 + }; + + static PyTypeObject StatResultType; + + #ifdef TARGET_API_MAC_OS8 + static PyStructSequence_Field xstat_result_fields[] = { + COMMON_XSTAT_RESULT_FIELDS + { "st_rsize" }, + { "st_creator" }, + { "st_type "}, + {0} + }; + + static PyStructSequence_Desc xstat_result_desc = { + "xstat_result", + stat_result__doc__, + xstat_result_fields, + 13 + }; + + static PyTypeObject XStatResultType; + #endif + static PyObject * + _pystat_from_struct_stat(struct stat st, void* _mst) + { + PyObject *v; + + #if TARGET_API_MAC_OS8 + struct macstat *mst; + + if (_mst != NULL) + v = PyStructSequence_New(&XStatResultType); + else + #endif + v = PyStructSequence_New(&StatResultType); + PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode)); + PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino)); + PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev)); + PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink)); + PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid)); + PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid)); + PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long)st.st_size)); + PyStructSequence_SET_ITEM(v, 7, + PyFloat_FromDouble((double)st.st_atime)); + PyStructSequence_SET_ITEM(v, 8, + PyFloat_FromDouble((double)st.st_mtime)); + PyStructSequence_SET_ITEM(v, 9, + PyFloat_FromDouble((double)st.st_ctime)); + #if TARGET_API_MAC_OS8 + if (_mst != NULL) { + mst = (struct macstat *) _mst; + PyStructSequence_SET_ITEM(v, 10, + PyInt_FromLong((long)mst->st_rsize)); + PyStructSequence_SET_ITEM(v, 11, + PyString_FromStringAndSize(mst->st_creator, + 4)); + PyStructSequence_SET_ITEM(v, 12, + PyString_FromStringAndSize(mst->st_type, + 4)); + } + #endif + + if (PyErr_Occurred()) { + Py_DECREF(v); + return NULL; + } + + return v; + } + + + static PyObject * mac_stat(self, args) PyObject *self; PyObject *args; { + PyObject *v; struct stat st; char *path; *************** *** 476,490 **** if (res != 0) return mac_error(); ! return Py_BuildValue("(lllllllddd)", ! (long)st.st_mode, ! (long)st.st_ino, ! (long)st.st_dev, ! (long)st.st_nlink, ! (long)st.st_uid, ! (long)st.st_gid, ! (long)st.st_size, ! (double)st.st_atime, ! (double)st.st_mtime, ! (double)st.st_ctime); } --- 585,590 ---- if (res != 0) return mac_error(); ! ! return _pystat_from_struct_stat(st, NULL); } *************** *** 505,519 **** if (res != 0) return mac_error(); ! return Py_BuildValue("(lllllllddd)", ! (long)st.st_mode, ! (long)st.st_ino, ! (long)st.st_dev, ! (long)st.st_nlink, ! (long)st.st_uid, ! (long)st.st_gid, ! (long)st.st_size, ! (double)st.st_atime, ! (double)st.st_mtime, ! (double)st.st_ctime); } #endif /* WEHAVE_FSTAT */ --- 605,610 ---- if (res != 0) return mac_error(); ! ! return _pystat_from_struct_stat(st, NULL); } #endif /* WEHAVE_FSTAT */ *************** *** 546,563 **** if (res != 0) return mac_error(); ! return Py_BuildValue("(llllllldddls#s#)", ! (long)st.st_mode, ! (long)st.st_ino, ! (long)st.st_dev, ! (long)st.st_nlink, ! (long)st.st_uid, ! (long)st.st_gid, ! (long)st.st_size, ! (double)st.st_atime, ! (double)st.st_mtime, ! (double)st.st_ctime, ! (long)mst.st_rsize, ! mst.st_creator, 4, ! mst.st_type, 4); } #endif --- 637,642 ---- if (res != 0) return mac_error(); ! ! return _pystat_from_struct_stat(st, (void*) &mst); } #endif *************** *** 767,769 **** --- 846,856 ---- MacError = PyErr_NewException("mac.error", NULL, NULL); PyDict_SetItemString(d, "error", MacError); + + PyStructSequence_InitType(&StatResultType, &stat_result_desc); + PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType); + + #if TARGET_API_MAC_OS8 + PyStructSequence_InitType(&XStatResultType, &xstat_result_desc); + PyDict_SetItemString(d, "xstat_result", (PyObject*) &XStatResultType); + #endif } From gvanrossum@users.sourceforge.net Thu Oct 18 21:34:27 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 13:34:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.285,1.286 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv7266/Misc Modified Files: NEWS Log Message: SF patch #462296: Add attributes to os.stat results; by Nick Mathewson. This is a big one, touching lots of files. Some of the platforms aren't tested yet. Briefly, this changes the return value of the os/posix functions stat(), fstat(), statvfs(), fstatvfs(), and the time functions localtime(), gmtime(), and strptime() from tuples into pseudo-sequences. When accessed as a sequence, they behave exactly as before. But they also have attributes like st_mtime or tm_year. The stat return value, moreover, has a few platform-specific attributes that are not available through the sequence interface (because everybody expects the sequence to have a fixed length, these couldn't be added there). If your platform's struct stat doesn't define st_blksize, st_blocks or st_rdev, they won't be accessible from Python either. (Still missing is a documentation update.) Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.285 retrieving revision 1.286 diff -C2 -d -r1.285 -r1.286 *** NEWS 2001/10/18 19:20:25 1.285 --- NEWS 2001/10/18 20:34:25 1.286 *************** *** 49,53 **** - readline now supports setting the startup_hook and the pre_event_hook. ! - posix supports chroot and setgroups where available. - Decompression objects in the zlib module now accept an optional --- 49,63 ---- - readline now supports setting the startup_hook and the pre_event_hook. ! - os and posix supports chroot() and setgroups() where available. The ! stat(), fstat(), statvfs() and fstatvfs() functions now return ! "pseudo-sequences" -- the various fields can now be accessed as ! attributes (e.g. os.stat("/").st_mtime) but for backwards ! compatibility they also behave as a fixed-length sequence. Some ! platform-specific fields (e.g. st_rdev) are only accessible as ! attributes. ! ! - time: localtime(), gmtime() and strptime() now return a ! pseudo-sequence similar to the os.stat() return value, with ! attributes like tm_year etc. - Decompression objects in the zlib module now accept an optional From gvanrossum@users.sourceforge.net Thu Oct 18 21:34:28 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 13:34:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/RISCOS/Modules riscosmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/RISCOS/Modules In directory usw-pr-cvs1:/tmp/cvs-serv7266/RISCOS/Modules Modified Files: riscosmodule.c Log Message: SF patch #462296: Add attributes to os.stat results; by Nick Mathewson. This is a big one, touching lots of files. Some of the platforms aren't tested yet. Briefly, this changes the return value of the os/posix functions stat(), fstat(), statvfs(), fstatvfs(), and the time functions localtime(), gmtime(), and strptime() from tuples into pseudo-sequences. When accessed as a sequence, they behave exactly as before. But they also have attributes like st_mtime or tm_year. The stat return value, moreover, has a few platform-specific attributes that are not available through the sequence interface (because everybody expects the sequence to have a fixed length, these couldn't be added there). If your platform's struct stat doesn't define st_blksize, st_blocks or st_rdev, they won't be accessible from Python either. (Still missing is a documentation update.) Index: riscosmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/RISCOS/Modules/riscosmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** riscosmodule.c 2001/03/02 05:57:54 1.1 --- riscosmodule.c 2001/10/18 20:34:25 1.2 *************** *** 114,119 **** } static PyObject *riscos_stat(PyObject *self,PyObject *args) ! { char *path; int ob,len; bits t=0; --- 114,157 ---- } + static char stat_result__doc__[] = + "stat_result: Result from stat or lstat.\n\n\ + This object may be accessed either as a tuple of\n\ + (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\ + or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\ + \n\ + RiscOS: The fields st_ftype, st_attrs, and st_obtype are also available.\n\ + \n\ + See os.stat for more information.\n"; + + static PyStructSequence_Field stat_result_fields[] = { + { "st_mode", "protection bits" }, + { "st_ino", "inode" }, + { "st_dev", "device" }, + { "st_nlink", "number of hard links" }, + { "st_uid", "user ID of owner" }, + { "st_gid", "group ID of owner" }, + { "st_size", "total size, in bytes" }, + { "st_atime", "time of last access" }, + { "st_mtime", "time of last modification" }, + { "st_ctime", "time of last change" }, + { "st_ftype", "file type" }, + { "st_attrs", "attributes" }, + { "st_obtype", "object type" } + { 0 } + }; + + static PyStructSequence_Desc stat_result_desc = { + "stat_result", + stat_result__doc__, + stat_result_fields, + 13 + }; + + static PyTypeObject StatResultType; + static PyObject *riscos_stat(PyObject *self,PyObject *args) ! { ! PyObject *v; ! char *path; int ob,len; bits t=0; *************** *** 131,149 **** mode|=(at&7)<<6; mode|=((at&112)*9)>>4; ! return Py_BuildValue("(lllllllllllll)", ! (long)mode,/*st_mode*/ ! 0,/*st_ino*/ ! 0,/*st_dev*/ ! 0,/*st_nlink*/ ! 0,/*st_uid*/ ! 0,/*st_gid*/ ! (long)len,/*st_size*/ ! (long)t,/*st_atime*/ ! (long)t,/*st_mtime*/ ! (long)t,/*st_ctime*/ ! (long)ft,/*file type*/ ! (long)at,/*attributes*/ ! (long)ob/*object type*/ ! ); } --- 169,200 ---- mode|=(at&7)<<6; mode|=((at&112)*9)>>4; ! ! v = PyStructSequence_New(&StatResultType); ! ! PyStructSequence_SET_ITEM(v, 0, ! PyInt_FromLong((long) mode)); /*st_mode*/ ! PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) 0)); /*st_ino*/ ! PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) 0)); /*st_dev*/ ! PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) 0)); /*st_nlink*/ ! PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) 0)); /*st_uid*/ ! PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) 0)); /*st_gid*/ ! PyStructSequence_SET_ITEM(v, 6, ! PyInt_FromLong((long) len)); /*st_size*/ ! PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) t)); /*st_atime*/ ! PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) t)); /*st_mtime*/ ! PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) t)); /*st_ctime*/ ! PyStructSequence_SET_ITEM(v, 10, ! PyInt_FromLong((long) ft)); /*file type*/ ! PyStructSequence_SET_ITEM(v, 11, ! PyInt_FromLong((long) at)); /*attributes*/ ! PyStructSequence_SET_ITEM(v, 12, ! PyInt_FromLong((long) ot)); /*object type*/ ! ! if (PyErr_Occurred()) { ! Py_DECREF(v); ! return NULL; ! } ! ! return v; } *************** *** 272,276 **** initriscos() { ! PyObject *m, *d; m = Py_InitModule("riscos", riscos_methods); --- 323,327 ---- initriscos() { ! PyObject *m, *d, *stat_m; m = Py_InitModule("riscos", riscos_methods); *************** *** 281,283 **** --- 332,337 ---- if (RiscosError == NULL || PyDict_SetItemString(d, "error", RiscosError) != 0) Py_FatalError("can't define riscos.error"); + + PyStructSequence_InitType(&StatResultType, &stat_result_desc); + PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType); } From gvanrossum@users.sourceforge.net Thu Oct 18 21:34:28 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 13:34:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.202,2.203 timemodule.c,2.114,2.115 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv7266/Modules Modified Files: posixmodule.c timemodule.c Log Message: SF patch #462296: Add attributes to os.stat results; by Nick Mathewson. This is a big one, touching lots of files. Some of the platforms aren't tested yet. Briefly, this changes the return value of the os/posix functions stat(), fstat(), statvfs(), fstatvfs(), and the time functions localtime(), gmtime(), and strptime() from tuples into pseudo-sequences. When accessed as a sequence, they behave exactly as before. But they also have attributes like st_mtime or tm_year. The stat return value, moreover, has a few platform-specific attributes that are not available through the sequence interface (because everybody expects the sequence to have a fixed length, these couldn't be added there). If your platform's struct stat doesn't define st_blksize, st_blocks or st_rdev, they won't be accessible from Python either. (Still missing is a documentation update.) Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.202 retrieving revision 2.203 diff -C2 -d -r2.202 -r2.203 *** posixmodule.c 2001/10/18 19:44:10 2.202 --- posixmodule.c 2001/10/18 20:34:25 2.203 *************** *** 18,21 **** --- 18,22 ---- #include "Python.h" + #include "structseq.h" #if defined(PYOS_OS2) *************** *** 517,520 **** --- 518,612 ---- } + static char stat_result__doc__[] = + "stat_result: Result from stat or lstat.\n\n\ + This object may be accessed either as a tuple of\n\ + (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\ + or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\ + \n\ + Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev, + they are available as attributes only.\n\ + \n\ + See os.stat for more information.\n"; + + static PyStructSequence_Field stat_result_fields[] = { + {"st_mode", "protection bits"}, + {"st_ino", "inode"}, + {"st_dev", "device"}, + {"st_nlink", "number of hard links"}, + {"st_uid", "user ID of owner"}, + {"st_gid", "group ID of owner"}, + {"st_size", "total size, in bytes"}, + {"st_atime", "time of last access"}, + {"st_mtime", "time of last modification"}, + {"st_ctime", "time of last change"}, + #ifdef HAVE_ST_BLKSIZE + {"st_blksize", "blocksize for filesystem I/O"}, + #endif + #ifdef HAVE_ST_BLOCKS + {"st_blocks", "number of blocks allocated"}, + #endif + #ifdef HAVE_ST_RDEV + {"st_rdev", "device type (if inode device)"}, + #endif + {0} + }; + + #ifdef HAVE_ST_BLKSIZE + #define ST_BLKSIZE_IDX 10 + #else + #define ST_BLKSIZE_IDX 9 + #endif + + #ifdef HAVE_ST_BLOCKS + #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1) + #else + #define ST_BLOCKS_IDX ST_BLKSIZE_IDX + #endif + + #ifdef HAVE_ST_RDEV + #define ST_RDEV_IDX (ST_BLOCKS_IDX+1) + #else + #define ST_RDEV_IDX ST_BLOCKS_IDX + #endif + + static PyStructSequence_Desc stat_result_desc = { + "stat_result", /* name */ + stat_result__doc__, /* doc */ + stat_result_fields, + 10 + }; + + static char statvfs_result__doc__[] = + "statvfs_result: Result from statvfs or fstatvfs.\n\n\ + This object may be accessed either as a tuple of\n\ + (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax), + or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on. + \n\ + See os.statvfs for more information.\n"; + + static PyStructSequence_Field statvfs_result_fields[] = { + {"f_bsize", }, + {"f_frsize", }, + {"f_blocks", }, + {"f_bfree", }, + {"f_bavail", }, + {"f_files", }, + {"f_ffree", }, + {"f_favail", }, + {"f_flag", }, + {"f_namemax",}, + {0} + }; + + static PyStructSequence_Desc statvfs_result_desc = { + "statvfs_result", /* name */ + statvfs_result__doc__, /* doc */ + statvfs_result_fields, + 10 + }; + + static PyTypeObject StatResultType; + static PyTypeObject StatVFSResultType; + /* pack a system stat C structure into the Python stat tuple (used by posix_stat() and posix_fstat()) */ *************** *** 522,558 **** _pystat_fromstructstat(STRUCT_STAT st) { ! PyObject *v = PyTuple_New(10); if (v == NULL) return NULL; ! PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode)); #ifdef HAVE_LARGEFILE_SUPPORT ! PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino)); #else ! PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino)); #endif #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS) ! PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev)); #else ! PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev)); #endif ! PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink)); ! PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid)); ! PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid)); #ifdef HAVE_LARGEFILE_SUPPORT ! PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size)); #else ! PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size)); #endif #if SIZEOF_TIME_T > SIZEOF_LONG ! PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime)); ! PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime)); ! PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime)); #else ! PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime)); ! PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime)); ! PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime)); #endif if (PyErr_Occurred()) { Py_DECREF(v); --- 614,669 ---- _pystat_fromstructstat(STRUCT_STAT st) { ! PyObject *v = PyStructSequence_New(&StatResultType); if (v == NULL) return NULL; ! PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode)); #ifdef HAVE_LARGEFILE_SUPPORT ! PyStructSequence_SET_ITEM(v, 1, ! PyLong_FromLongLong((LONG_LONG)st.st_ino)); #else ! PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino)); #endif #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS) ! PyStructSequence_SET_ITEM(v, 2, ! PyLong_FromLongLong((LONG_LONG)st.st_dev)); #else ! PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev)); #endif ! PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink)); ! PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid)); ! PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid)); #ifdef HAVE_LARGEFILE_SUPPORT ! PyStructSequence_SET_ITEM(v, 6, ! PyLong_FromLongLong((LONG_LONG)st.st_size)); #else ! PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size)); #endif #if SIZEOF_TIME_T > SIZEOF_LONG ! PyStructSequence_SET_ITEM(v, 7, ! PyLong_FromLongLong((LONG_LONG)st.st_atime)); ! PyStructSequence_SET_ITEM(v, 8, ! PyLong_FromLongLong((LONG_LONG)st.st_mtime)); ! PyStructSequence_SET_ITEM(v, 9, ! PyLong_FromLongLong((LONG_LONG)st.st_ctime)); #else ! PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime)); ! PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime)); ! PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime)); #endif + #ifdef HAVE_ST_BLKSIZE + PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX, + PyInt_FromLong((long)st.st_blksize)); + #endif + #ifdef HAVE_ST_BLOCKS + PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX, + PyInt_FromLong((long)st.st_blocks)); + #endif + #ifdef HAVE_ST_RDEV + PyStructSequence_SET_ITEM(v, ST_RDEV_IDX, + PyInt_FromLong((long)st.st_rdev)); + #endif + if (PyErr_Occurred()) { Py_DECREF(v); *************** *** 563,567 **** } - static PyObject * posix_do_stat(PyObject *self, PyObject *args, char *format, --- 674,677 ---- *************** *** 4174,4177 **** --- 4284,4326 ---- #include + static PyObject* + _pystatvfs_fromstructstatvfs(struct statvfs st) { + PyObject *v = PyStructSequence_New(&StatVFSResultType); + if (v == NULL) + return NULL; + + #if !defined(HAVE_LARGEFILE_SUPPORT) + PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize)); + PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize)); + PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks)); + PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree)); + PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail)); + PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files)); + PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree)); + PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail)); + PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag)); + PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax)); + #else + PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize)); + PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize)); + PyStructSequence_SET_ITEM(v, 2, + PyLong_FromLongLong((LONG_LONG) st.f_blocks)); + PyStructSequence_SET_ITEM(v, 3, + PyLong_FromLongLong((LONG_LONG) st.f_bfree)); + PyStructSequence_SET_ITEM(v, 4, + PyLong_FromLongLong((LONG_LONG) st.f_bavail)); + PyStructSequence_SET_ITEM(v, 5, + PyLong_FromLongLong((LONG_LONG) st.f_files)); + PyStructSequence_SET_ITEM(v, 6, + PyLong_FromLongLong((LONG_LONG) st.f_ffree)); + PyStructSequence_SET_ITEM(v, 7, + PyLong_FromLongLong((LONG_LONG) st.f_favail)); + PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag)); + PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax)); + #endif + + return v; + } + static char posix_fstatvfs__doc__[] = "fstatvfs(fd) -> \n\ *************** *** 4184,4187 **** --- 4333,4337 ---- int fd, res; struct statvfs st; + if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd)) return NULL; *************** *** 4191,4219 **** if (res != 0) return posix_error(); ! #if !defined(HAVE_LARGEFILE_SUPPORT) ! return Py_BuildValue("(llllllllll)", ! (long) st.f_bsize, ! (long) st.f_frsize, ! (long) st.f_blocks, ! (long) st.f_bfree, ! (long) st.f_bavail, ! (long) st.f_files, ! (long) st.f_ffree, ! (long) st.f_favail, ! (long) st.f_flag, ! (long) st.f_namemax); ! #else ! return Py_BuildValue("(llLLLLLLll)", ! (long) st.f_bsize, ! (long) st.f_frsize, ! (LONG_LONG) st.f_blocks, ! (LONG_LONG) st.f_bfree, ! (LONG_LONG) st.f_bavail, ! (LONG_LONG) st.f_files, ! (LONG_LONG) st.f_ffree, ! (LONG_LONG) st.f_favail, ! (long) st.f_flag, ! (long) st.f_namemax); ! #endif } #endif /* HAVE_FSTATVFS */ --- 4341,4346 ---- if (res != 0) return posix_error(); ! ! return _pystatvfs_fromstructstatvfs(st); } #endif /* HAVE_FSTATVFS */ *************** *** 4241,4269 **** if (res != 0) return posix_error_with_filename(path); ! #if !defined(HAVE_LARGEFILE_SUPPORT) ! return Py_BuildValue("(llllllllll)", ! (long) st.f_bsize, ! (long) st.f_frsize, ! (long) st.f_blocks, ! (long) st.f_bfree, ! (long) st.f_bavail, ! (long) st.f_files, ! (long) st.f_ffree, ! (long) st.f_favail, ! (long) st.f_flag, ! (long) st.f_namemax); ! #else /* HAVE_LARGEFILE_SUPPORT */ ! return Py_BuildValue("(llLLLLLLll)", ! (long) st.f_bsize, ! (long) st.f_frsize, ! (LONG_LONG) st.f_blocks, ! (LONG_LONG) st.f_bfree, ! (LONG_LONG) st.f_bavail, ! (LONG_LONG) st.f_files, ! (LONG_LONG) st.f_ffree, ! (LONG_LONG) st.f_favail, ! (long) st.f_flag, ! (long) st.f_namemax); ! #endif } #endif /* HAVE_STATVFS */ --- 4368,4373 ---- if (res != 0) return posix_error_with_filename(path); ! ! return _pystatvfs_fromstructstatvfs(st); } #endif /* HAVE_STATVFS */ *************** *** 5826,5828 **** --- 5930,5938 ---- posix_putenv_garbage = PyDict_New(); #endif + + PyStructSequence_InitType(&StatResultType, &stat_result_desc); + PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType); + + PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc); + PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatResultType); } Index: timemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/timemodule.c,v retrieving revision 2.114 retrieving revision 2.115 diff -C2 -d -r2.114 -r2.115 *** timemodule.c 2001/09/25 13:59:01 2.114 --- timemodule.c 2001/10/18 20:34:25 2.115 *************** *** 3,6 **** --- 3,7 ---- #include "Python.h" + #include "structseq.h" #include *************** *** 211,227 **** a floating point number for subsecond precision."; static PyObject * tmtotuple(struct tm *p) { ! return Py_BuildValue("(iiiiiiiii)", ! p->tm_year + 1900, ! p->tm_mon + 1, /* Want January == 1 */ ! p->tm_mday, ! p->tm_hour, ! p->tm_min, ! p->tm_sec, ! (p->tm_wday + 6) % 7, /* Want Monday == 0 */ ! p->tm_yday + 1, /* Want January, 1 == 1 */ ! p->tm_isdst); } --- 212,262 ---- a floating point number for subsecond precision."; + static PyStructSequence_Field struct_time_type_fields[] = { + {"tm_year", NULL}, + {"tm_mon", NULL}, + {"tm_mday", NULL}, + {"tm_hour", NULL}, + {"tm_min", NULL}, + {"tm_sec", NULL}, + {"tm_wday", NULL}, + {"tm_yday", NULL}, + {"tm_isdst", NULL}, + {0} + }; + + static PyStructSequence_Desc struct_time_type_desc = { + "struct_time", + NULL, + struct_time_type_fields, + 9, + }; + + static PyTypeObject StructTimeType; + static PyObject * tmtotuple(struct tm *p) { ! PyObject *v = PyStructSequence_New(&StructTimeType); ! if (v == NULL) ! return NULL; ! ! #define SET(i,val) PyStructSequence_SET_ITEM(v, i, PyInt_FromLong((long) val)) ! ! SET(0, p->tm_year + 1900); ! SET(1, p->tm_mon + 1); /* Want January == 1 */ ! SET(2, p->tm_mday); ! SET(3, p->tm_hour); ! SET(4, p->tm_min); ! SET(5, p->tm_sec); ! SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */ ! SET(7, p->tm_yday + 1); /* Want January, 1 == 1 */ ! SET(8, p->tm_isdst); ! #undef SET ! if (PyErr_Occurred()) { ! Py_XDECREF(v); ! return NULL; ! } ! ! return v; } *************** *** 675,678 **** --- 710,716 ---- #endif /* __CYGWIN__ */ #endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/ + + PyStructSequence_InitType(&StructTimeType, &struct_time_type_desc); + PyDict_SetItemString(d, "struct_time", (PyObject*) &StructTimeType); } *************** *** 853,856 **** --- 891,895 ---- #endif /* !macintosh */ #endif /* !HAVE_SELECT */ + return 0; } From gvanrossum@users.sourceforge.net Thu Oct 18 21:47:53 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 13:47:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects structseq.c,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12181 Added Files: structseq.c Log Message: Missing file structseq.c for SF patch #462296 --- NEW FILE: structseq.c --- /* Implementation helper: a struct that looks like a tuple. See timemodule and posixmodule for example uses. */ #include "Python.h" #include "structmember.h" #include "structseq.h" static char visible_length_key[] = "n_sequence_fields"; static char real_length_key[] = "n_fields"; #define VISIBLE_SIZE(op) ((op)->ob_size) #define VISIBLE_SIZE_TP(tp) PyInt_AsLong( \ PyDict_GetItemString((tp)->tp_dict, visible_length_key)) #define REAL_SIZE_TP(tp) PyInt_AsLong( \ PyDict_GetItemString((tp)->tp_dict, real_length_key)) #define REAL_SIZE(op) REAL_SIZE_TP((op)->ob_type) PyObject * PyStructSequence_New(PyTypeObject *type) { PyStructSequence *obj; obj = PyObject_New(PyStructSequence, type); obj->ob_size = VISIBLE_SIZE_TP(type); return (PyObject*) obj; } static void structseq_dealloc(PyStructSequence *obj) { int i, size; size = REAL_SIZE(obj); for (i = 0; i < size; ++i) { Py_XDECREF(obj->ob_item[i]); } PyObject_FREE(obj); } static int structseq_length(PyStructSequence *obj) { return VISIBLE_SIZE(obj); } static PyObject* structseq_item(PyStructSequence *obj, int i) { if (i < 0 || i >= VISIBLE_SIZE(obj)) { PyErr_SetString(PyExc_IndexError, "tuple index out of range"); return NULL; } Py_INCREF(obj->ob_item[i]); return obj->ob_item[i]; } static PyObject* structseq_slice(PyStructSequence *obj, int low, int high) { PyTupleObject *np; int i; if (low < 0) low = 0; if (high > VISIBLE_SIZE(obj)) high = VISIBLE_SIZE(obj); if (high < low) high = low; np = (PyTupleObject *)PyTuple_New(high-low); if (np == NULL) return NULL; for(i = low; i < high; ++i) { PyObject *v = obj->ob_item[i]; Py_INCREF(v); PyTuple_SET_ITEM(np, i, v); } return (PyObject *) np; } static PyObject * structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *arg = NULL; PyStructSequence *res = NULL; int len, required_len, i; static char *kwlist[] = {"sequence", 0}; static char msgbuf[128]; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:structseq", kwlist, &arg)) return NULL; if (!PySequence_Check(arg)) { PyErr_SetString(PyExc_TypeError, "constructor requires a sequence"); return NULL; } len = PySequence_Length(arg); required_len = REAL_SIZE_TP(type); if (len != required_len) { sprintf(msgbuf, "constructor takes exactly %d arguments (%d given)", required_len, len); PyErr_SetString(PyExc_TypeError, msgbuf); return NULL; } res = (PyStructSequence*) PyStructSequence_New(type); for (i = 0; i < len; ++i) { /* INCREF???? XXXX */ res->ob_item[i] = PySequence_GetItem(arg, i); } return (PyObject*) res; } static PyObject * make_tuple(PyStructSequence *obj) { return structseq_slice(obj, 0, VISIBLE_SIZE(obj)); } static PyObject * structseq_repr(PyStructSequence *obj) { PyObject *tup, *str; tup = make_tuple(obj); str = PyObject_Repr(tup); Py_DECREF(tup); return str; } static PyObject * structseq_concat(PyStructSequence *obj, PyObject *b) { PyObject *tup, *result; tup = make_tuple(obj); result = PySequence_Concat(tup, b); Py_DECREF(tup); return result; } static PyObject * structseq_repeat(PyStructSequence *obj, int n) { PyObject *tup, *result; tup = make_tuple(obj); result = PySequence_Repeat(tup, n); Py_DECREF(tup); return result; } static int structseq_contains(PyStructSequence *obj, PyObject *o) { PyObject *tup; int result; tup = make_tuple(obj); result = PySequence_Contains(tup, o); Py_DECREF(tup); return result; } static long structseq_hash(PyObject *obj) { PyObject *tup; long result; tup = make_tuple((PyStructSequence*) obj); result = PyObject_Hash(tup); Py_DECREF(tup); return result; } static PyObject * structseq_richcompare(PyObject *obj, PyObject *o2, int op) { PyObject *tup, *result; tup = make_tuple((PyStructSequence*) obj); result = PyObject_RichCompare(tup, o2, op); Py_DECREF(tup); return result; } static PySequenceMethods structseq_as_sequence = { (inquiry)structseq_length, (binaryfunc)structseq_concat, /* sq_concat */ (intargfunc)structseq_repeat, /* sq_repeat */ (intargfunc)structseq_item, /* sq_item */ (intintargfunc)structseq_slice, /* sq_slice */ 0, /* sq_ass_item */ 0, /* sq_ass_slice */ (objobjproc)structseq_contains, /* sq_contains */ }; static PyTypeObject _struct_sequence_template = { PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */ NULL, /* tp_name */ 0, /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)structseq_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)structseq_repr, /* tp_repr */ 0, /* tp_as_number */ &structseq_as_sequence, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc)structseq_hash, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ NULL, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ structseq_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ NULL, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ structseq_new, /* tp_new */ }; void PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) { PyObject *dict; PyMemberDef* members; int n_members, i; for (i = 0; desc->fields[i].name != NULL; ++i) ; n_members = i; memcpy(type, &_struct_sequence_template, sizeof(PyTypeObject)); type->tp_name = desc->name; type->tp_doc = desc->doc; type->tp_basicsize = sizeof(PyStructSequence)+ sizeof(PyObject*)*(n_members-1); type->tp_itemsize = 0; members = PyMem_NEW(PyMemberDef, n_members+1); for (i = 0; i < n_members; ++i) { members[i].name = desc->fields[i].name; members[i].type = T_OBJECT; members[i].offset = offsetof(PyStructSequence, ob_item) + i * sizeof(PyObject*); members[i].flags = READONLY; members[i].doc = desc->fields[i].doc; } members[n_members].name = NULL; type->tp_members = members; if (PyType_Ready(type) < 0) return; Py_INCREF(type); dict = type->tp_dict; PyDict_SetItemString(dict, visible_length_key, PyInt_FromLong((long) desc->n_in_sequence)); PyDict_SetItemString(dict, real_length_key, PyInt_FromLong((long) n_members)); } From tim_one@users.sourceforge.net Thu Oct 18 21:49:38 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 18 Oct 2001 13:49:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.286,2.287 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv12399/python/Python Modified Files: ceval.c Log Message: SF Patch (but with no patch) 472555 Remove trailing common in enumeration. Some AIX compiler didn't like the trailing comma at the end of the why_code enum decl. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.286 retrieving revision 2.287 diff -C2 -d -r2.286 -r2.287 *** ceval.c 2001/10/17 13:29:30 2.286 --- ceval.c 2001/10/18 20:49:35 2.287 *************** *** 471,475 **** WHY_BREAK, /* 'break' statement */ WHY_CONTINUE, /* 'continue' statement */ ! WHY_YIELD, /* 'yield' operator */ }; --- 471,475 ---- WHY_BREAK, /* 'break' statement */ WHY_CONTINUE, /* 'continue' statement */ ! WHY_YIELD /* 'yield' operator */ }; From gvanrossum@users.sourceforge.net Thu Oct 18 21:51:34 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 13:51:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild pythoncore.dsp,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv13093 Modified Files: pythoncore.dsp Log Message: add structseq.c to project Index: pythoncore.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pythoncore.dsp,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** pythoncore.dsp 2001/10/18 15:19:38 1.26 --- pythoncore.dsp 2001/10/18 20:51:32 1.27 *************** *** 1588,1591 **** --- 1588,1606 ---- # Begin Source File + SOURCE=..\Objects\structseq.c + + !IF "$(CFG)" == "pythoncore - Win32 Release" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" + + !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Release" + + !ENDIF + + # End Source File + # Begin Source File + SOURCE=..\Python\symtable.c From gvanrossum@users.sourceforge.net Thu Oct 18 21:53:17 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 13:53:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.203,2.204 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv13686 Modified Files: posixmodule.c Log Message: Don't leave bare newlines in long strings -- VC doesn't like that. Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.203 retrieving revision 2.204 diff -C2 -d -r2.203 -r2.204 *** posixmodule.c 2001/10/18 20:34:25 2.203 --- posixmodule.c 2001/10/18 20:53:15 2.204 *************** *** 524,528 **** or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\ \n\ ! Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev, they are available as attributes only.\n\ \n\ --- 524,528 ---- or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\ \n\ ! Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\ they are available as attributes only.\n\ \n\ *************** *** 580,585 **** "statvfs_result: Result from statvfs or fstatvfs.\n\n\ This object may be accessed either as a tuple of\n\ ! (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax), ! or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on. \n\ See os.statvfs for more information.\n"; --- 580,585 ---- "statvfs_result: Result from statvfs or fstatvfs.\n\n\ This object may be accessed either as a tuple of\n\ ! (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax),\n\ ! or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\ \n\ See os.statvfs for more information.\n"; From effbot@users.sourceforge.net Thu Oct 18 21:58:27 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Thu, 18 Oct 2001 13:58:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libnntplib.tex,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv15002/Doc/lib Modified Files: libnntplib.tex Log Message: changed misleading argument name Index: libnntplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libnntplib.tex,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** libnntplib.tex 2001/10/01 13:50:15 1.26 --- libnntplib.tex 2001/10/18 20:58:25 1.27 *************** *** 198,209 **** \end{methoddesc} ! \begin{methoddesc}{body}{id,\optional{fileHandle}} Send a \samp{BODY} command, where \var{id} has the same meaning as for ! \method{stat()}. If the \var{fileHandle} parameter is supplied, then ! the body is stored in a file. If \var{fileHandle} is a string, then the method will open a file object with that name, write to it then close it. ! If \var{fileHandle} is a file object, then it will start calling \method{write()} on it to store the lines of the body. ! Return as for \method{head()}. If \var{fileHandle} is supplied. Then the returned \var{list} is an empty list. \end{methoddesc} --- 198,209 ---- \end{methoddesc} ! \begin{methoddesc}{body}{id,\optional{file}} Send a \samp{BODY} command, where \var{id} has the same meaning as for ! \method{stat()}. If the \var{file} parameter is supplied, then ! the body is stored in a file. If \var{file} is a string, then the method will open a file object with that name, write to it then close it. ! If \var{file} is a file object, then it will start calling \method{write()} on it to store the lines of the body. ! Return as for \method{head()}. If \var{file} is supplied. Then the returned \var{list} is an empty list. \end{methoddesc} From effbot@users.sourceforge.net Thu Oct 18 21:58:27 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Thu, 18 Oct 2001 13:58:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib nntplib.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv15002/Lib Modified Files: nntplib.py Log Message: changed misleading argument name Index: nntplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/nntplib.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** nntplib.py 2001/10/01 13:46:55 1.27 --- nntplib.py 2001/10/18 20:58:25 1.28 *************** *** 212,216 **** return resp ! def getlongresp(self,fileHandle=None): """Internal: get a response plus following text from the server. Raise various errors if the response indicates an error.""" --- 212,216 ---- return resp ! def getlongresp(self, file=None): """Internal: get a response plus following text from the server. Raise various errors if the response indicates an error.""" *************** *** 219,224 **** try: # If a string was passed then open a file with that name ! if isinstance(fileHandle, types.StringType): ! openedFile = fileHandle = open(fileHandle, "w") resp = self.getresp() --- 219,224 ---- try: # If a string was passed then open a file with that name ! if isinstance(file, types.StringType): ! openedFile = file = open(file, "w") resp = self.getresp() *************** *** 232,237 **** if line[:2] == '..': line = line[1:] ! if fileHandle: ! fileHandle.write(line + "\n") else: list.append(line) --- 232,237 ---- if line[:2] == '..': line = line[1:] ! if file: ! file.write(line + "\n") else: list.append(line) *************** *** 248,255 **** return self.getresp() ! def longcmd(self, line, fileHandle=None): """Internal: send a command and get the response plus following text.""" self.putcmd(line) ! return self.getlongresp(fileHandle) def newgroups(self, date, time): --- 248,255 ---- return self.getresp() ! def longcmd(self, line, file=None): """Internal: send a command and get the response plus following text.""" self.putcmd(line) ! return self.getlongresp(file) def newgroups(self, date, time): *************** *** 356,362 **** return self.statcmd('LAST') ! def artcmd(self, line, fileHandle=None): """Internal: process a HEAD, BODY or ARTICLE command.""" ! resp, list = self.longcmd(line,fileHandle) resp, nr, id = self.statparse(resp) return resp, nr, id, list --- 356,362 ---- return self.statcmd('LAST') ! def artcmd(self, line, file=None): """Internal: process a HEAD, BODY or ARTICLE command.""" ! resp, list = self.longcmd(line, file) resp, nr, id = self.statparse(resp) return resp, nr, id, list *************** *** 373,380 **** return self.artcmd('HEAD ' + id) ! def body(self, id, fileHandle=None): """Process a BODY command. Argument: - id: article number or message id ! - fileHandle: Filename string or file object to store the article in Returns: - resp: server response if successful --- 373,380 ---- return self.artcmd('HEAD ' + id) ! def body(self, id, file=None): """Process a BODY command. Argument: - id: article number or message id ! - file: Filename string or file object to store the article in Returns: - resp: server response if successful *************** *** 382,388 **** - id: message id - list: the lines of the article's body or an empty list ! if fileHandle was used""" ! return self.artcmd('BODY ' + id, fileHandle) def article(self, id): --- 382,388 ---- - id: message id - list: the lines of the article's body or an empty list ! if file was used""" ! return self.artcmd('BODY ' + id, file) def article(self, id): From gvanrossum@users.sourceforge.net Thu Oct 18 22:19:34 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 14:19:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_os.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20335 Modified Files: test_os.py Log Message: The assignment to result.st_rdev can raise AttributeError as well as TypeError (on systems where it's not defined at all, it raises AttributeError; when it's defined, assignment to it raises TypeError). Index: test_os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_os.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_os.py 2001/10/18 20:34:25 1.7 --- test_os.py 2001/10/18 21:19:31 1.8 *************** *** 112,116 **** result.st_rdev = 1 self.fail("No exception thrown") ! except TypeError: pass --- 112,116 ---- result.st_rdev = 1 self.fail("No exception thrown") ! except (AttributeError, TypeError): pass From loewis@users.sourceforge.net Thu Oct 18 22:24:07 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 18 Oct 2001 14:24:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python dynload_shlib.c,2.11,2.12 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv21029 Modified Files: dynload_shlib.c Log Message: Move dlfcn.h block out of NetBSD block, assuming that NetBSD before 199712 didn't have dlfcn.h, or that it wouldn't conflict with the other stuff defined. Index: dynload_shlib.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/dynload_shlib.c,v retrieving revision 2.11 retrieving revision 2.12 diff -C2 -d -r2.11 -r2.12 *** dynload_shlib.c 2001/10/18 11:45:19 2.11 --- dynload_shlib.c 2001/10/18 21:24:04 2.12 *************** *** 7,10 **** --- 7,11 ---- #include #include + #if defined(__NetBSD__) #include *************** *** 13,22 **** #include #define dlerror() "error in dynamic linking" ! #else #ifdef HAVE_DLFCN_H #include #endif - #endif - #endif /* NetBSD */ #if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__) --- 14,23 ---- #include #define dlerror() "error in dynamic linking" ! #endif ! #endif /* NetBSD */ ! #ifdef HAVE_DLFCN_H #include #endif #if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__) From tim_one@users.sourceforge.net Thu Oct 18 22:57:39 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 18 Oct 2001 14:57:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib ConfigParser.py,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv29225/python/Lib Modified Files: ConfigParser.py Log Message: Whitespace normalization. Index: ConfigParser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ConfigParser.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** ConfigParser.py 2001/10/04 19:58:46 1.37 --- ConfigParser.py 2001/10/18 21:57:37 1.38 *************** *** 310,314 **** states = {'1': 1, 'yes': 1, 'true': 1, 'on': 1, '0': 0, 'no': 0, 'false': 0, 'off': 0} ! v = self.get(section, option) if not states.has_key(v.lower()): raise ValueError, 'Not a boolean: %s' % v --- 310,314 ---- states = {'1': 1, 'yes': 1, 'true': 1, 'on': 1, '0': 0, 'no': 0, 'false': 0, 'off': 0} ! v = self.get(section, option) if not states.has_key(v.lower()): raise ValueError, 'Not a boolean: %s' % v From tim_one@users.sourceforge.net Thu Oct 18 22:57:39 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 18 Oct 2001 14:57:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/compiler __init__.py,1.6,1.7 ast.py,1.18,1.19 future.py,1.2,1.3 misc.py,1.10,1.11 pyassem.py,1.28,1.29 pycodegen.py,1.55,1.56 symbols.py,1.9,1.10 transformer.py,1.29,1.30 visitor.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/compiler In directory usw-pr-cvs1:/tmp/cvs-serv29225/python/Lib/compiler Modified Files: __init__.py ast.py future.py misc.py pyassem.py pycodegen.py symbols.py transformer.py visitor.py Log Message: Whitespace normalization. Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/__init__.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** __init__.py 2001/09/27 04:18:36 1.6 --- __init__.py 2001/10/18 21:57:37 1.7 *************** *** 16,20 **** compile(source, filename, mode, flags=None, dont_inherit=None) ! Returns a code object. A replacement for the builtin compile() function. compileFile(filename) --- 16,20 ---- compile(source, filename, mode, flags=None, dont_inherit=None) ! Returns a code object. A replacement for the builtin compile() function. compileFile(filename) *************** *** 25,27 **** from visitor import walk from pycodegen import compile, compileFile - --- 25,26 ---- Index: ast.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/ast.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** ast.py 2001/09/17 20:17:02 1.18 --- ast.py 2001/10/18 21:57:37 1.19 *************** *** 439,443 **** if flags & CO_VARKEYWORDS: self.kwargs = 1 ! --- 439,443 ---- if flags & CO_VARKEYWORDS: self.kwargs = 1 ! Index: future.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/future.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** future.py 2001/08/18 00:07:46 1.2 --- future.py 2001/10/18 21:57:37 1.3 *************** *** 17,21 **** features = ("nested_scopes", "generators", "division") ! def __init__(self): self.found = {} # set --- 17,21 ---- features = ("nested_scopes", "generators", "division") ! def __init__(self): self.found = {} # set *************** *** 71,73 **** print v.found print - --- 71,72 ---- Index: misc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/misc.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** misc.py 2001/09/17 18:02:21 1.10 --- misc.py 2001/10/18 21:57:37 1.11 *************** *** 73,75 **** node.filename = filename worklist.extend(node.getChildNodes()) - --- 73,74 ---- Index: pyassem.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/pyassem.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** pyassem.py 2001/10/17 13:37:29 1.28 --- pyassem.py 2001/10/18 21:57:37 1.29 *************** *** 56,60 **** # however. :-( If a client needs to remove these edges, call # pruneEdges(). ! self.current.addNext(block) self.startBlock(block) --- 56,60 ---- # however. :-( If a client needs to remove these edges, call # pruneEdges(). ! self.current.addNext(block) self.startBlock(block) *************** *** 111,115 **** # XXX This is a total mess. There must be a better way to get # the code blocks in the right order. ! self.fixupOrderHonorNext(blocks, default_next) self.fixupOrderForward(blocks, default_next) --- 111,115 ---- # XXX This is a total mess. There must be a better way to get # the code blocks in the right order. ! self.fixupOrderHonorNext(blocks, default_next) self.fixupOrderForward(blocks, default_next) *************** *** 117,121 **** def fixupOrderHonorNext(self, blocks, default_next): """Fix one problem with DFS. ! The DFS uses child block, but doesn't know about the special "next" block. As a result, the DFS can order blocks so that a --- 117,121 ---- def fixupOrderHonorNext(self, blocks, default_next): """Fix one problem with DFS. ! The DFS uses child block, but doesn't know about the special "next" block. As a result, the DFS can order blocks so that a *************** *** 201,205 **** for b in c: blocks.append(b) ! def getBlocks(self): return self.blocks.elements() --- 201,205 ---- for b in c: blocks.append(b) ! def getBlocks(self): return self.blocks.elements() *************** *** 208,212 **** """Return nodes appropriate for use with dominator""" return self.entry ! def getContainedGraphs(self): l = [] --- 208,212 ---- """Return nodes appropriate for use with dominator""" return self.entry ! def getContainedGraphs(self): l = [] *************** *** 247,251 **** insts = map(str, self.insts) return "" % (self.label, self.bid, ! string.join(insts, '\n')) def emit(self, inst): --- 247,251 ---- insts = map(str, self.insts) return "" % (self.label, self.bid, ! string.join(insts, '\n')) def emit(self, inst): *************** *** 332,336 **** self.klass = klass if optimized: ! self.flags = CO_OPTIMIZED | CO_NEWLOCALS else: self.flags = 0 --- 332,336 ---- self.klass = klass if optimized: ! self.flags = CO_OPTIMIZED | CO_NEWLOCALS else: self.flags = 0 *************** *** 568,572 **** if name[:9] == "_convert_": opname = name[9:] ! _converters[opname] = obj del name, obj, opname --- 568,572 ---- if name[:9] == "_convert_": opname = name[9:] ! _converters[opname] = obj del name, obj, opname *************** *** 624,628 **** l.append(elt) return tuple(l) ! def isJump(opname): if opname[:4] == 'JUMP': --- 624,628 ---- l.append(elt) return tuple(l) ! def isJump(opname): if opname[:4] == 'JUMP': *************** *** 655,659 **** class LineAddrTable: """lnotab ! This class builds the lnotab, which is documented in compile.c. Here's a brief recap: --- 655,659 ---- class LineAddrTable: """lnotab ! This class builds the lnotab, which is documented in compile.c. Here's a brief recap: *************** *** 718,722 **** def getTable(self): return string.join(map(chr, self.lnotab), '') ! class StackDepthTracker: # XXX 1. need to keep track of stack depth on jumps --- 718,722 ---- def getTable(self): return string.join(map(chr, self.lnotab), '') ! class StackDepthTracker: # XXX 1. need to keep track of stack depth on jumps *************** *** 793,797 **** ('LOAD_', 1), ] ! def UNPACK_SEQUENCE(self, count): return count-1 --- 793,797 ---- ('LOAD_', 1), ] ! def UNPACK_SEQUENCE(self, count): return count-1 *************** *** 821,824 **** def DUP_TOPX(self, argc): return argc ! findDepth = StackDepthTracker().findDepth --- 821,824 ---- def DUP_TOPX(self, argc): return argc ! findDepth = StackDepthTracker().findDepth Index: pycodegen.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/pycodegen.py,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** pycodegen.py 2001/09/17 21:02:51 1.55 --- pycodegen.py 2001/10/18 21:57:37 1.56 *************** *** 37,41 **** class BlockStack(misc.Stack): __super_init = misc.Stack.__init__ ! def __init__(self): self.__super_init(self) --- 37,41 ---- class BlockStack(misc.Stack): __super_init = misc.Stack.__init__ ! def __init__(self): self.__super_init(self) *************** *** 60,64 **** if flags is not None or dont_inherit is not None: raise RuntimeError, "not implemented yet" ! if mode == "single": gen = Interactive(source, filename) --- 60,64 ---- if flags is not None or dont_inherit is not None: raise RuntimeError, "not implemented yet" ! if mode == "single": gen = Interactive(source, filename) *************** *** 199,203 **** defined in the initClass() method, which is a hook for initializing these methods after all the classes have been ! defined. """ --- 199,203 ---- defined in the initClass() method, which is a hook for initializing these methods after all the classes have been ! defined. """ *************** *** 313,317 **** def set_lineno(self, node, force=0): ! """Emit SET_LINENO if node has lineno attribute and it is different than the last lineno emitted. --- 313,317 ---- def set_lineno(self, node, force=0): ! """Emit SET_LINENO if node has lineno attribute and it is different than the last lineno emitted. *************** *** 514,518 **** self.nextBlock() elif kind == END_FINALLY: ! msg = "'continue' not allowed inside 'finally' clause (%s, %d)" raise SyntaxError, msg % (node.filename, node.lineno) --- 514,518 ---- self.nextBlock() elif kind == END_FINALLY: ! msg = "'continue' not allowed inside 'finally' clause (%s, %d)" raise SyntaxError, msg % (node.filename, node.lineno) *************** *** 559,563 **** # list comprehensions __list_count = 0 ! def visitListComp(self, node): self.set_lineno(node) --- 559,563 ---- # list comprehensions __list_count = 0 ! def visitListComp(self, node): self.set_lineno(node) *************** *** 569,573 **** self.emit('LOAD_ATTR', 'append') self._implicitNameOp('STORE', append) ! stack = [] for i, for_ in zip(range(len(node.quals)), node.quals): --- 569,573 ---- self.emit('LOAD_ATTR', 'append') self._implicitNameOp('STORE', append) ! stack = [] for i, for_ in zip(range(len(node.quals)), node.quals): *************** *** 584,588 **** self.emit('CALL_FUNCTION', 1) self.emit('POP_TOP') ! for start, cont, anchor in stack: if cont: --- 584,588 ---- self.emit('CALL_FUNCTION', 1) self.emit('POP_TOP') ! for start, cont, anchor in stack: if cont: *************** *** 595,599 **** self.startBlock(anchor) self._implicitNameOp('DELETE', append) ! self.__list_count = self.__list_count - 1 --- 595,599 ---- self.startBlock(anchor) self._implicitNameOp('DELETE', append) ! self.__list_count = self.__list_count - 1 *************** *** 676,680 **** self.emit('JUMP_FORWARD', lElse) self.startBlock(handlers) ! last = len(node.handlers) - 1 for i in range(len(node.handlers)): --- 676,680 ---- self.emit('JUMP_FORWARD', lElse) self.startBlock(handlers) ! last = len(node.handlers) - 1 for i in range(len(node.handlers)): *************** *** 708,712 **** self.visit(node.else_) self.nextBlock(end) ! def visitTryFinally(self, node): body = self.newBlock() --- 708,712 ---- self.visit(node.else_) self.nextBlock(end) ! def visitTryFinally(self, node): body = self.newBlock() *************** *** 747,751 **** self.set_lineno(node) self.loadName(node.name) ! def visitPass(self, node): self.set_lineno(node) --- 747,751 ---- self.set_lineno(node) self.loadName(node.name) ! def visitPass(self, node): self.set_lineno(node) *************** *** 1140,1144 **** scopes = None ! def __init__(self, tree): self.graph = pyassem.PyFlowGraph("", tree.filename) --- 1140,1144 ---- scopes = None ! def __init__(self, tree): self.graph = pyassem.PyFlowGraph("", tree.filename) *************** *** 1155,1159 **** scopes = None futures = () ! def __init__(self, tree): self.graph = pyassem.PyFlowGraph("", tree.filename) --- 1155,1159 ---- scopes = None futures = () ! def __init__(self, tree): self.graph = pyassem.PyFlowGraph("", tree.filename) *************** *** 1172,1176 **** scopes = None futures = () ! def __init__(self, tree): self.graph = pyassem.PyFlowGraph("", tree.filename) --- 1172,1176 ---- scopes = None futures = () ! def __init__(self, tree): self.graph = pyassem.PyFlowGraph("", tree.filename) *************** *** 1202,1207 **** name = func.name args, hasTupleArg = generateArgList(func.argnames) ! self.graph = pyassem.PyFlowGraph(name, func.filename, args, ! optimized=1) self.isLambda = isLambda self.super_init() --- 1202,1207 ---- name = func.name args, hasTupleArg = generateArgList(func.argnames) ! self.graph = pyassem.PyFlowGraph(name, func.filename, args, ! optimized=1) self.isLambda = isLambda self.super_init() *************** *** 1235,1239 **** self.emit('LOAD_FAST', '.%d' % (i * 2)) self.unpackSequence(arg) ! def unpackSequence(self, tup): if VERSION > 1: --- 1235,1239 ---- self.emit('LOAD_FAST', '.%d' % (i * 2)) self.unpackSequence(arg) ! def unpackSequence(self, tup): if VERSION > 1: *************** *** 1250,1254 **** class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode, ! CodeGenerator): super_init = CodeGenerator.__init__ # call be other init scopes = None --- 1250,1254 ---- class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode, ! CodeGenerator): super_init = CodeGenerator.__init__ # call be other init scopes = None Index: symbols.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/symbols.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** symbols.py 2001/09/14 22:45:57 1.9 --- symbols.py 2001/10/18 21:57:37 1.10 *************** *** 132,136 **** Be careful to stop if a child does not think the name is ! free. """ self.globals[name] = 1 --- 132,136 ---- Be careful to stop if a child does not think the name is ! free. """ self.globals[name] = 1 *************** *** 173,177 **** class ModuleScope(Scope): __super_init = Scope.__init__ ! def __init__(self): self.__super_init("global", self) --- 173,177 ---- class ModuleScope(Scope): __super_init = Scope.__init__ ! def __init__(self): self.__super_init("global", self) *************** *** 184,188 **** __counter = 1 ! def __init__(self, module, klass=None): i = self.__counter --- 184,188 ---- __counter = 1 ! def __init__(self, module, klass=None): i = self.__counter *************** *** 200,204 **** self.scopes = {} self.klass = None ! # node that define new scopes --- 200,204 ---- self.scopes = {} self.klass = None ! # node that define new scopes *************** *** 218,222 **** self.visit(node.code, scope) self.handle_free_vars(scope, parent) ! def visitLambda(self, node, parent): for n in node.defaults: --- 218,222 ---- self.visit(node.code, scope) self.handle_free_vars(scope, parent) ! def visitLambda(self, node, parent): for n in node.defaults: *************** *** 327,331 **** if node.upper: self.visit(node.upper, scope, 0) ! def visitAugAssign(self, node, scope): # If the LHS is a name, then this counts as assignment. --- 327,331 ---- if node.upper: self.visit(node.upper, scope, 0) ! def visitAugAssign(self, node, scope): # If the LHS is a name, then this counts as assignment. *************** *** 372,377 **** def get_names(syms): return [s for s in [s.get_name() for s in syms.get_symbols()] ! if not (s.startswith('_[') or s.startswith('.'))] ! for file in sys.argv[1:]: print file --- 372,377 ---- def get_names(syms): return [s for s in [s.get_name() for s in syms.get_symbols()] ! if not (s.startswith('_[') or s.startswith('.'))] ! for file in sys.argv[1:]: print file Index: transformer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/transformer.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** transformer.py 2001/10/17 13:32:52 1.29 --- transformer.py 2001/10/18 21:57:37 1.30 *************** *** 693,697 **** n.lineno = nodelist[0][2] return n ! def atom_number(self, nodelist): ### need to verify this matches compile.c --- 693,697 ---- n.lineno = nodelist[0][2] return n ! def atom_number(self, nodelist): ### need to verify this matches compile.c *************** *** 700,704 **** n.lineno = nodelist[0][2] return n ! def atom_string(self, nodelist): ### need to verify this matches compile.c --- 700,704 ---- n.lineno = nodelist[0][2] return n ! def atom_string(self, nodelist): ### need to verify this matches compile.c *************** *** 744,748 **** # ('const', xxxx)) Nodes) return Discard(Const(None)) ! def com_arglist(self, nodelist): # varargslist: --- 744,748 ---- # ('const', xxxx)) Nodes) return Discard(Const(None)) ! def com_arglist(self, nodelist): # varargslist: *************** *** 806,810 **** def com_fplist(self, node): ! # fplist: fpdef (',' fpdef)* [','] if len(node) == 2: return self.com_fpdef(node[1]) --- 806,810 ---- def com_fplist(self, node): ! # fplist: fpdef (',' fpdef)* [','] if len(node) == 2: return self.com_fpdef(node[1]) *************** *** 855,859 **** # try_fin_stmt: "try" ":" suite "finally" ":" suite n = TryFinally(self.com_node(nodelist[2]), ! self.com_node(nodelist[5])) n.lineno = nodelist[0][2] return n --- 855,859 ---- # try_fin_stmt: "try" ":" suite "finally" ":" suite n = TryFinally(self.com_node(nodelist[2]), ! self.com_node(nodelist[5])) n.lineno = nodelist[0][2] return n *************** *** 923,927 **** primary = self.com_apply_trailer(primary, ch) return self.com_assign_trailer(primary, node[-1], ! assigning) node = node[1] elif t == symbol.atom: --- 923,927 ---- primary = self.com_apply_trailer(primary, ch) return self.com_assign_trailer(primary, node[-1], ! assigning) node = node[1] elif t == symbol.atom: *************** *** 1024,1028 **** # XXX should raise SyntaxError for assignment ! lineno = node[1][2] fors = [] --- 1024,1028 ---- # XXX should raise SyntaxError for assignment ! lineno = node[1][2] fors = [] *************** *** 1101,1105 **** node = nodelist[i] if node[0] == token.STAR or node[0] == token.DOUBLESTAR: ! break kw, result = self.com_argument(node, kw) args.append(result) --- 1101,1105 ---- node = nodelist[i] if node[0] == token.STAR or node[0] == token.DOUBLESTAR: ! break kw, result = self.com_argument(node, kw) args.append(result) *************** *** 1146,1150 **** # slicing: simple_slicing | extended_slicing # simple_slicing: primary "[" short_slice "]" ! # extended_slicing: primary "[" slice_list "]" # slice_list: slice_item ("," slice_item)* [","] --- 1146,1150 ---- # slicing: simple_slicing | extended_slicing # simple_slicing: primary "[" short_slice "]" ! # extended_slicing: primary "[" slice_list "]" # slice_list: slice_item ("," slice_item)* [","] Index: visitor.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/visitor.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** visitor.py 2001/08/29 18:17:22 1.8 --- visitor.py 2001/10/18 21:57:37 1.9 *************** *** 79,83 **** """ examples = {} ! def dispatch(self, node, *args): self.node = node --- 79,83 ---- """ examples = {} ! def dispatch(self, node, *args): self.node = node From tim_one@users.sourceforge.net Thu Oct 18 22:57:39 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 18 Oct 2001 14:57:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test pickletester.py,1.9,1.10 regrtest.py,1.60,1.61 test_binascii.py,1.10,1.11 test_cpickle.py,1.8,1.9 test_email.py,1.11,1.12 test_os.py,1.8,1.9 test_pickle.py,1.7,1.8 test_socket_ssl.py,1.3,1.4 test_zlib.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv29225/python/Lib/test Modified Files: pickletester.py regrtest.py test_binascii.py test_cpickle.py test_email.py test_os.py test_pickle.py test_socket_ssl.py test_zlib.py Log Message: Whitespace normalization. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** pickletester.py 2001/10/15 21:38:56 1.9 --- pickletester.py 2001/10/18 21:57:37 1.10 *************** *** 76,80 **** 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh' + \ '\x06tq\nh\nK\x05e.' ! def create_data(): c = C() --- 76,80 ---- 'C\nq\x05oq\x06}q\x07(U\x03fooq\x08K\x01U\x03barq\tK\x02ubh' + \ '\x06tq\nh\nK\x05e.' ! def create_data(): c = C() Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -d -r1.60 -r1.61 *** regrtest.py 2001/10/17 13:45:28 1.60 --- regrtest.py 2001/10/18 21:57:37 1.61 *************** *** 200,204 **** bad.sort() skipped.sort() ! if good and not quiet: if not bad and not skipped and len(good) > 1: --- 200,204 ---- bad.sort() skipped.sort() ! if good and not quiet: if not bad and not skipped and len(good) > 1: Index: test_binascii.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_binascii.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** test_binascii.py 2001/10/11 14:09:03 1.10 --- test_binascii.py 2001/10/18 21:57:37 1.11 *************** *** 114,116 **** # Verify the treatment of Unicode strings verify(binascii.hexlify(u'a') == '61', "hexlify failed for Unicode") - --- 114,115 ---- Index: test_cpickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_cpickle.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_cpickle.py 2001/10/15 21:38:56 1.8 --- test_cpickle.py 2001/10/18 21:57:37 1.9 *************** *** 5,9 **** class cPickleTests(AbstractPickleTests, AbstractPickleModuleTests): ! def setUp(self): self.dumps = cPickle.dumps --- 5,9 ---- class cPickleTests(AbstractPickleTests, AbstractPickleModuleTests): ! def setUp(self): self.dumps = cPickle.dumps Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_email.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** test_email.py 2001/10/17 20:52:26 1.11 --- test_email.py 2001/10/18 21:57:37 1.12 *************** *** 292,296 **** From: test@dom.ain References: <0@dom.ain> <1@dom.ain> <2@dom.ain> <3@dom.ain> <4@dom.ain> ! <5@dom.ain> <6@dom.ain> <7@dom.ain> <8@dom.ain> <9@dom.ain> Test""") --- 292,296 ---- From: test@dom.ain References: <0@dom.ain> <1@dom.ain> <2@dom.ain> <3@dom.ain> <4@dom.ain> ! \t<5@dom.ain> <6@dom.ain> <7@dom.ain> <8@dom.ain> <9@dom.ain> Test""") Index: test_os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_os.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_os.py 2001/10/18 21:19:31 1.8 --- test_os.py 2001/10/18 21:57:37 1.9 *************** *** 69,73 **** f.write("ABC") f.close() ! def tearDown(self): os.unlink(self.fname) --- 69,73 ---- f.write("ABC") f.close() ! def tearDown(self): os.unlink(self.fname) *************** *** 134,138 **** pass ! def test_statvfs_attributes(self): if not hasattr(os, "statvfs"): --- 134,138 ---- pass ! def test_statvfs_attributes(self): if not hasattr(os, "statvfs"): Index: test_pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pickle.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_pickle.py 2001/10/15 21:38:56 1.7 --- test_pickle.py 2001/10/18 21:57:37 1.8 *************** *** 9,13 **** self.dumps = pickle.dumps self.loads = pickle.loads ! module = pickle error = KeyError --- 9,13 ---- self.dumps = pickle.dumps self.loads = pickle.loads ! module = pickle error = KeyError Index: test_socket_ssl.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_socket_ssl.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_socket_ssl.py 2001/10/18 00:30:14 1.3 --- test_socket_ssl.py 2001/10/18 21:57:37 1.4 *************** *** 26,30 **** buf = f.read() f.close() - - - --- 26,27 ---- Index: test_zlib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_zlib.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** test_zlib.py 2001/10/16 20:39:49 1.15 --- test_zlib.py 2001/10/18 21:57:37 1.16 *************** *** 96,100 **** else: print "max_length decompressobj succeeded" ! # Misc tests of max_length deco = zlib.decompressobj(-12) --- 96,100 ---- else: print "max_length decompressobj succeeded" ! # Misc tests of max_length deco = zlib.decompressobj(-12) From loewis@users.sourceforge.net Thu Oct 18 23:05:38 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 18 Oct 2001 15:05:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.204,2.205 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv30889 Modified Files: posixmodule.c Log Message: Expose O_LARGEFILE, O_DIRECT, O_DIRECTORY, and O_NOFOLLOW. Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.204 retrieving revision 2.205 diff -C2 -d -r2.204 -r2.205 *** posixmodule.c 2001/10/18 20:53:15 2.204 --- posixmodule.c 2001/10/18 22:05:36 2.205 *************** *** 5871,5874 **** --- 5871,5891 ---- if (ins(d, "O_TEXT", (long)O_TEXT)) return -1; #endif + #ifdef O_LARGEFILE + if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1; + #endif + + /* GNU extensions. */ + #ifdef O_DIRECT + /* Direct disk access. */ + if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1; + #endif + #ifdef O_DIRECTORY + /* Must be a directory. */ + if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1; + #endif + #ifdef O_NOFOLLOW + /* Do not follow links. */ + if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1; + #endif #ifdef HAVE_SPAWNV From loewis@users.sourceforge.net Thu Oct 18 23:07:51 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 18 Oct 2001 15:07:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_fcntl.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv31426 Modified Files: test_fcntl.py Log Message: Assume a 64-bit start and len if O_LARGEFILE is available. Index: test_fcntl.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_fcntl.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** test_fcntl.py 2001/05/09 21:11:59 1.18 --- test_fcntl.py 2001/10/18 22:07:48 1.19 *************** *** 10,13 **** --- 10,20 ---- filename = TESTFN + try: + os.O_LARGEFILE + except AttributeError: + start_len = "ll" + else: + start_len = "qq" + if sys.platform in ('netbsd1', 'Darwin1.2', 'darwin1', 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5', *************** *** 18,22 **** lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0) else: ! lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) if verbose: print 'struct.pack: ', `lockdata` --- 25,29 ---- lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0) else: ! lockdata = struct.pack('hh'+start_len+'hh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) if verbose: print 'struct.pack: ', `lockdata` From gvanrossum@users.sourceforge.net Fri Oct 19 02:18:45 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 18:18:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libreadline.tex,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv2159/Doc/lib Modified Files: libreadline.tex Log Message: SF patch #443759: Add Interface to readline's add_history This was submitted by Moshe, but apparently he's too busy to check it in himself. He wrote: Here is a function in GNU readline called add_history, which is used to manage the history list. Though Python uses this function internally, it does not expose it to the Python programmer. This patch adds direct interface to this function with documentation. This could be used by friendly modules to "seed" the history with commands. Index: libreadline.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libreadline.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** libreadline.tex 2001/09/30 21:09:58 1.7 --- libreadline.tex 2001/10/19 01:18:43 1.8 *************** *** 97,100 **** --- 97,104 ---- \end{funcdesc} + \begin{funcdesc}{add_history}{line} + Append a line to the history buffer, as if it was the last line typed. + \end{funcdesc} + \begin{seealso} From gvanrossum@users.sourceforge.net Fri Oct 19 02:18:45 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 18:18:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules readline.c,2.38,2.39 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv2159/Modules Modified Files: readline.c Log Message: SF patch #443759: Add Interface to readline's add_history This was submitted by Moshe, but apparently he's too busy to check it in himself. He wrote: Here is a function in GNU readline called add_history, which is used to manage the history list. Though Python uses this function internally, it does not expose it to the Python programmer. This patch adds direct interface to this function with documentation. This could be used by friendly modules to "seed" the history with commands. Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.38 retrieving revision 2.39 diff -C2 -d -r2.38 -r2.39 *** readline.c 2001/09/30 21:09:59 2.38 --- readline.c 2001/10/19 01:18:43 2.39 *************** *** 288,292 **** --- 288,309 ---- set the readline word delimiters for tab-completion"; + static PyObject * + py_add_history(PyObject *self, PyObject *args) + { + char *line; + + if(!PyArg_ParseTuple(args, "s:add_history", &line)) { + return NULL; + } + add_history(line); + Py_INCREF(Py_None); + return Py_None; + } + static char doc_add_history[] = "\ + add_history(string) -> None\n\ + add a line to the history buffer"; + + /* get the tab-completion word-delimiters that readline uses */ *************** *** 376,379 **** --- 393,397 ---- {"set_completer_delims", set_completer_delims, METH_VARARGS, doc_set_completer_delims}, + {"add_history", py_add_history, METH_VARARGS, doc_add_history}, {"get_completer_delims", get_completer_delims, METH_OLDARGS, doc_get_completer_delims}, From gvanrossum@users.sourceforge.net Fri Oct 19 02:32:01 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 18:32:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.286,1.287 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv3916/Misc Modified Files: NEWS Log Message: SF patch #460805 by Chris Gonnerman: Support for unsetenv() This adds unsetenv to posix, and uses it in the __delitem__ method of os.environ. (XXX Should we change the preferred name for putenv to setenv, for consistency?) Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.286 retrieving revision 1.287 diff -C2 -d -r1.286 -r1.287 *** NEWS 2001/10/18 20:34:25 1.286 --- NEWS 2001/10/19 01:31:59 1.287 *************** *** 47,58 **** - binascii has now two quopri support functions, a2b_qp and b2a_qp. ! - readline now supports setting the startup_hook and the pre_event_hook. ! - os and posix supports chroot() and setgroups() where available. The ! stat(), fstat(), statvfs() and fstatvfs() functions now return ! "pseudo-sequences" -- the various fields can now be accessed as ! attributes (e.g. os.stat("/").st_mtime) but for backwards ! compatibility they also behave as a fixed-length sequence. Some ! platform-specific fields (e.g. st_rdev) are only accessible as attributes. --- 47,59 ---- - binascii has now two quopri support functions, a2b_qp and b2a_qp. ! - readline now supports setting the startup_hook and the ! pre_event_hook, and adds the add_history() function. ! - os and posix supports chroot(), setgroups() and unsetenv() where ! available. The stat(), fstat(), statvfs() and fstatvfs() functions ! now return "pseudo-sequences" -- the various fields can now be ! accessed as attributes (e.g. os.stat("/").st_mtime) but for ! backwards compatibility they also behave as a fixed-length sequence. ! Some platform-specific fields (e.g. st_rdev) are only accessible as attributes. From gvanrossum@users.sourceforge.net Fri Oct 19 02:32:01 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 18:32:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib os.py,1.47,1.48 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv3916/Lib Modified Files: os.py Log Message: SF patch #460805 by Chris Gonnerman: Support for unsetenv() This adds unsetenv to posix, and uses it in the __delitem__ method of os.environ. (XXX Should we change the preferred name for putenv to setenv, for consistency?) Index: os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/os.py,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -d -r1.47 -r1.48 *** os.py 2001/03/07 09:05:44 1.47 --- os.py 2001/10/19 01:31:59 1.48 *************** *** 355,358 **** --- 355,366 ---- import UserDict + # Fake unsetenv() for Windows + # not sure about os2 and dos here but + # I'm guessing they are the same. + + if name in ('os2', 'nt', 'dos'): + def unsetenv(key): + putenv(key, "") + if name == "riscos": # On RISC OS, all env access goes through getenv and putenv *************** *** 371,376 **** def __getitem__(self, key): return self.data[key.upper()] ! def __delitem__(self, key): ! del self.data[key.upper()] def has_key(self, key): return self.data.has_key(key.upper()) --- 379,391 ---- def __getitem__(self, key): return self.data[key.upper()] ! try: ! unsetenv ! except NameError: ! def __delitem__(self, key): ! del self.data[key.upper()] ! else: ! def __delitem__(self, key): ! unsetenv(key) ! del self.data[key.upper()] def has_key(self, key): return self.data.has_key(key.upper()) *************** *** 392,395 **** --- 407,419 ---- for k, v in dict.items(): self[k] = v + try: + unsetenv + except NameError: + pass + else: + def __delitem__(self, key): + unsetenv(key) + del self.data[key] + environ = _Environ(environ) From gvanrossum@users.sourceforge.net Fri Oct 19 02:32:01 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 18:32:01 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.265,1.266 configure.in,1.273,1.274 pyconfig.h.in,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv3916 Modified Files: configure configure.in pyconfig.h.in Log Message: SF patch #460805 by Chris Gonnerman: Support for unsetenv() This adds unsetenv to posix, and uses it in the __delitem__ method of os.environ. (XXX Should we change the preferred name for putenv to setenv, for consistency?) Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.265 retrieving revision 1.266 diff -C2 -d -r1.265 -r1.266 *** configure 2001/10/18 20:34:24 1.265 --- configure 2001/10/19 01:31:59 1.266 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.273 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.274 # Guess values for system-dependent variables and create Makefiles. *************** *** 4825,4829 **** sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ ! truncate uname waitpid _getpty getpriority do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 --- 4825,4829 ---- sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ ! truncate uname unsetenv waitpid _getpty getpriority do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.273 retrieving revision 1.274 diff -C2 -d -r1.273 -r1.274 *** configure.in 2001/10/18 20:34:24 1.273 --- configure.in 2001/10/19 01:31:59 1.274 *************** *** 1412,1416 **** sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ ! truncate uname waitpid _getpty getpriority) # check for openpty and forkpty --- 1412,1416 ---- sigaction siginterrupt sigrelse strftime strptime symlink sysconf \ tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ ! truncate uname unsetenv waitpid _getpty getpriority) # check for openpty and forkpty Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** pyconfig.h.in 2001/10/18 20:34:24 1.18 --- pyconfig.h.in 2001/10/19 01:31:59 1.19 *************** *** 322,325 **** --- 322,328 ---- #undef SIZEOF_WCHAR_T + /* Define if you have the _getpty function. */ + #undef HAVE__GETPTY + /* Define if you have the alarm function. */ #undef HAVE_ALARM *************** *** 424,430 **** #undef HAVE_GETPRIORITY - /* Define if you have the _getpty function. */ - #undef HAVE__GETPTY - /* Define if you have the getpwent function. */ #undef HAVE_GETPWENT --- 427,430 ---- *************** *** 598,612 **** #undef HAVE_UNAME /* Define if you have the waitpid function. */ #undef HAVE_WAITPID ! /* Define if you have the header file. */ ! #undef HAVE_DB_185_H /* Define if you have the header file. */ #undef HAVE_DB1_NDBM_H ! /* Define if you have the header file. */ ! #undef HAVE_DB_H /* Define if you have the header file. */ --- 598,615 ---- #undef HAVE_UNAME + /* Define if you have the unsetenv function. */ + #undef HAVE_UNSETENV + /* Define if you have the waitpid function. */ #undef HAVE_WAITPID ! /* Define if you have the header file. */ ! #undef HAVE_DB_H /* Define if you have the header file. */ #undef HAVE_DB1_NDBM_H ! /* Define if you have the header file. */ ! #undef HAVE_DB_185_H /* Define if you have the header file. */ From gvanrossum@users.sourceforge.net Fri Oct 19 02:32:02 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 18:32:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.205,2.206 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv3916/Modules Modified Files: posixmodule.c Log Message: SF patch #460805 by Chris Gonnerman: Support for unsetenv() This adds unsetenv to posix, and uses it in the __delitem__ method of os.environ. (XXX Should we change the preferred name for putenv to setenv, for consistency?) Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.205 retrieving revision 2.206 diff -C2 -d -r2.205 -r2.206 *** posixmodule.c 2001/10/18 22:05:36 2.205 --- posixmodule.c 2001/10/19 01:31:59 2.206 *************** *** 4084,4087 **** --- 4084,4118 ---- #endif /* putenv */ + #ifdef HAVE_UNSETENV + static char posix_unsetenv__doc__[] = + "unsetenv(key) -> None\n\ + Delete an environment variable."; + + static PyObject * + posix_unsetenv(PyObject *self, PyObject *args) + { + char *s1; + + if (!PyArg_ParseTuple(args, "s:unsetenv", &s1)) + return NULL; + + unsetenv(s1); + + /* Remove the key from posix_putenv_garbage; + * this will cause it to be collected. This has to + * happen after the real unsetenv() call because the + * old value was still accessible until then. + */ + if (PyDict_DelItem(posix_putenv_garbage, + PyTuple_GET_ITEM(args, 0))) { + /* really not much we can do; just leak */ + PyErr_Clear(); + } + + Py_INCREF(Py_None); + return Py_None; + } + #endif /* unsetenv */ + #ifdef HAVE_STRERROR static char posix_strerror__doc__[] = *************** *** 5667,5670 **** --- 5698,5704 ---- #ifdef HAVE_PUTENV {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__}, + #endif + #ifdef HAVE_UNSETENV + {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__}, #endif #ifdef HAVE_STRERROR From gvanrossum@users.sourceforge.net Fri Oct 19 02:46:23 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 18:46:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python marshal.c,1.67,1.68 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv6806 Modified Files: marshal.c Log Message: SF patch #470393 (Jim Ahlstrom): Add missing marshal function In Include/, marshal.h declares both PyMarshal_ReadLongFromFile() and PyMarshal_ReadShortFromFile(), but the second is missing from marshal.c. [Shouldn't the return type be declared as 'short' instead of 'int'? But 'int' is what was in marshal.h all those years... --Guido] Index: marshal.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/marshal.c,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -d -r1.67 -r1.68 *** marshal.c 2001/08/30 14:50:20 1.67 --- marshal.c 2001/10/19 01:46:21 1.68 *************** *** 636,639 **** --- 636,647 ---- } + int + PyMarshal_ReadShortFromFile(FILE *fp) + { + RFILE rf; + rf.fp = fp; + return r_short(&rf); + } + long PyMarshal_ReadLongFromFile(FILE *fp) From gvanrossum@users.sourceforge.net Fri Oct 19 02:51:13 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 18:51:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.127,1.128 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv7584 Modified Files: ACKS Log Message: Another. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.127 retrieving revision 1.128 diff -C2 -d -r1.127 -r1.128 *** ACKS 2001/10/18 18:02:07 1.127 --- ACKS 2001/10/19 01:51:11 1.128 *************** *** 150,153 **** --- 150,154 ---- Ben Gertzfield Jonathan Giddy + Chris Gonnerman David Goodger Hans de Graaff From gvanrossum@users.sourceforge.net Fri Oct 19 03:01:33 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 19:01:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include unicodeobject.h,2.35,2.36 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv8577/Include Modified Files: unicodeobject.h Log Message: SF patch #470578: Fixes to synchronize unicode() and str() This patch implements what we have discussed on python-dev late in September: str(obj) and unicode(obj) should behave similar, while the old behaviour is retained for unicode(obj, encoding, errors). The patch also adds a new feature with which objects can provide unicode(obj) with input data: the __unicode__ method. Currently no new tp_unicode slot is implemented; this is left as option for the future. Note that PyUnicode_FromEncodedObject() no longer accepts Unicode objects as input. The API name already suggests that Unicode objects do not belong in the list of acceptable objects and the functionality was only needed because PyUnicode_FromEncodedObject() was being used directly by unicode(). The latter was changed in the discussed way: * unicode(obj) calls PyObject_Unicode() * unicode(obj, encoding, errors) calls PyUnicode_FromEncodedObject() One thing left open to discussion is whether to leave the PyUnicode_FromObject() API as a thin API extension on top of PyUnicode_FromEncodedObject() or to turn it into a (macro) alias for PyObject_Unicode() and deprecate it. Doing so would have some surprising consequences though, e.g. u"abc" + 123 would turn out as u"abc123"... [Marc-Andre didn't have time to check this in before the deadline. I hope this is OK, Marc-Andre! You can still make changes and commit them on the trunk after the branch has been made, but then please mail Barry a context diff if you want the change to be merged into the 2.2b1 release branch. GvR] Index: unicodeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/unicodeobject.h,v retrieving revision 2.35 retrieving revision 2.36 diff -C2 -d -r2.35 -r2.36 *** unicodeobject.h 2001/09/20 10:35:45 2.35 --- unicodeobject.h 2001/10/19 02:01:31 2.36 *************** *** 455,466 **** Coercion is done in the following way: ! 1. Unicode objects are passed back as-is with incremented ! refcount. ! ! 2. String and other char buffer compatible objects are decoded under the assumptions that they contain data using the current default encoding. Decoding is done in "strict" mode. ! 3. All other objects raise an exception. The API returns NULL in case of an error. The caller is responsible --- 455,464 ---- Coercion is done in the following way: ! 1. String and other char buffer compatible objects are decoded under the assumptions that they contain data using the current default encoding. Decoding is done in "strict" mode. ! 2. All other objects (including Unicode objects) raise an ! exception. The API returns NULL in case of an error. The caller is responsible *************** *** 475,484 **** ); ! /* Shortcut for PyUnicode_FromEncodedObject(obj, NULL, "strict"); ! which results in using the default encoding as basis for ! decoding the object. ! ! Coerces obj to an Unicode object and return a reference with *incremented* refcount. The API returns NULL in case of an error. The caller is responsible --- 473,483 ---- ); ! /* Coerce obj to an Unicode object and return a reference with *incremented* refcount. + + Unicode objects are passed back as-is (subclasses are converted to + true Unicode objects), all other objects are delegated to + PyUnicode_FromEncodedObject(obj, NULL, "strict") which results in + using the default encoding as basis for decoding the object. The API returns NULL in case of an error. The caller is responsible From gvanrossum@users.sourceforge.net Fri Oct 19 03:01:33 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 19:01:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.157,2.158 unicodeobject.c,2.118,2.119 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv8577/Objects Modified Files: object.c unicodeobject.c Log Message: SF patch #470578: Fixes to synchronize unicode() and str() This patch implements what we have discussed on python-dev late in September: str(obj) and unicode(obj) should behave similar, while the old behaviour is retained for unicode(obj, encoding, errors). The patch also adds a new feature with which objects can provide unicode(obj) with input data: the __unicode__ method. Currently no new tp_unicode slot is implemented; this is left as option for the future. Note that PyUnicode_FromEncodedObject() no longer accepts Unicode objects as input. The API name already suggests that Unicode objects do not belong in the list of acceptable objects and the functionality was only needed because PyUnicode_FromEncodedObject() was being used directly by unicode(). The latter was changed in the discussed way: * unicode(obj) calls PyObject_Unicode() * unicode(obj, encoding, errors) calls PyUnicode_FromEncodedObject() One thing left open to discussion is whether to leave the PyUnicode_FromObject() API as a thin API extension on top of PyUnicode_FromEncodedObject() or to turn it into a (macro) alias for PyObject_Unicode() and deprecate it. Doing so would have some surprising consequences though, e.g. u"abc" + 123 would turn out as u"abc123"... [Marc-Andre didn't have time to check this in before the deadline. I hope this is OK, Marc-Andre! You can still make changes and commit them on the trunk after the branch has been made, but then please mail Barry a context diff if you want the change to be merged into the 2.2b1 release branch. GvR] Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.157 retrieving revision 2.158 diff -C2 -d -r2.157 -r2.158 *** object.c 2001/10/16 20:18:24 2.157 --- object.c 2001/10/19 02:01:31 2.158 *************** *** 297,333 **** if (v == NULL) res = PyString_FromString(""); ! else if (PyUnicode_Check(v)) { Py_INCREF(v); return v; } ! else if (PyString_Check(v)) { Py_INCREF(v); res = v; } - else if (v->ob_type->tp_str != NULL) - res = (*v->ob_type->tp_str)(v); else { PyObject *func; ! static PyObject *strstr; ! if (strstr == NULL) { ! strstr= PyString_InternFromString("__str__"); ! if (strstr == NULL) return NULL; } ! if (!PyInstance_Check(v) || ! (func = PyObject_GetAttr(v, strstr)) == NULL) { ! PyErr_Clear(); ! res = PyObject_Repr(v); ! } ! else { res = PyEval_CallObject(func, (PyObject *)NULL); Py_DECREF(func); } } if (res == NULL) return NULL; if (!PyUnicode_Check(res)) { ! PyObject* str; ! str = PyUnicode_FromObject(res); Py_DECREF(res); if (str) --- 297,344 ---- if (v == NULL) res = PyString_FromString(""); ! if (PyUnicode_CheckExact(v)) { Py_INCREF(v); return v; } ! if (PyUnicode_Check(v)) { ! /* For a Unicode subtype that's not a Unicode object, ! return a true Unicode object with the same data. */ ! return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(v), ! PyUnicode_GET_SIZE(v)); ! } ! if (PyString_Check(v)) { Py_INCREF(v); res = v; } else { PyObject *func; ! static PyObject *unicodestr; ! /* XXX As soon as we have a tp_unicode slot, we should ! check this before trying the __unicode__ ! method. */ ! if (unicodestr == NULL) { ! unicodestr= PyString_InternFromString( ! "__unicode__"); ! if (unicodestr == NULL) return NULL; } ! func = PyObject_GetAttr(v, unicodestr); ! if (func != NULL) { res = PyEval_CallObject(func, (PyObject *)NULL); Py_DECREF(func); } + else { + PyErr_Clear(); + if (v->ob_type->tp_str != NULL) + res = (*v->ob_type->tp_str)(v); + else + res = PyObject_Repr(v); + } } if (res == NULL) return NULL; if (!PyUnicode_Check(res)) { ! PyObject *str; ! str = PyUnicode_FromEncodedObject(res, NULL, "strict"); Py_DECREF(res); if (str) Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.118 retrieving revision 2.119 diff -C2 -d -r2.118 -r2.119 *** unicodeobject.c 2001/10/05 20:51:39 2.118 --- unicodeobject.c 2001/10/19 02:01:31 2.119 *************** *** 396,399 **** --- 396,411 ---- PyObject *PyUnicode_FromObject(register PyObject *obj) { + /* XXX Perhaps we should make this API an alias of + PyObject_Unicode() instead ?! */ + if (PyUnicode_CheckExact(obj)) { + Py_INCREF(obj); + return obj; + } + if (PyUnicode_Check(obj)) { + /* For a Unicode subtype that's not a Unicode object, + return a true Unicode object with the same data. */ + return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj), + PyUnicode_GET_SIZE(obj)); + } return PyUnicode_FromEncodedObject(obj, NULL, "strict"); } *************** *** 407,411 **** int owned = 0; PyObject *v; - int reclevel; if (obj == NULL) { --- 419,422 ---- *************** *** 414,473 **** } ! /* Coerce object */ ! for (reclevel = 0; reclevel < 2; reclevel++) { if (PyUnicode_Check(obj)) { if (encoding) { PyErr_SetString(PyExc_TypeError, "decoding Unicode is not supported"); ! goto onError; ! } ! if (PyUnicode_CheckExact(obj)) { ! Py_INCREF(obj); ! v = obj; } ! else { ! /* For a subclass of unicode, return a true unicode object ! with the same string value. */ ! v = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj), ! PyUnicode_GET_SIZE(obj)); } ! goto done; } ! else if (PyString_Check(obj)) { s = PyString_AS_STRING(obj); len = PyString_GET_SIZE(obj); - break; - } - else { - PyObject *w; - - /* Try char buffer interface */ - if (PyObject_AsCharBuffer(obj, &s, &len)) - PyErr_Clear(); - else - break; - - /* Mimic the behaviour of str(object) if everything else - fails (see PyObject_Str()); this also covers instances - which implement __str__. */ - if (obj->ob_type->tp_str == NULL) - w = PyObject_Repr(obj); - else - w = (*obj->ob_type->tp_str)(obj); - if (w == NULL) - goto onError; - if (owned) { - Py_DECREF(obj); } ! obj = w; ! owned = 1; ! } ! } ! ! if (s == NULL) { PyErr_Format(PyExc_TypeError, ! "coercing to Unicode: __str__ recursion limit exceeded " ! "(last type: %.80s)", obj->ob_type->tp_name); goto onError; --- 425,465 ---- } ! #if 0 ! /* For b/w compatibility we also accept Unicode objects provided ! that no encodings is given and then redirect to PyObject_Unicode() ! which then applies the additional logic for Unicode subclasses. ! ! NOTE: This API should really only be used for object which ! represent *encoded* Unicode ! + */ if (PyUnicode_Check(obj)) { if (encoding) { PyErr_SetString(PyExc_TypeError, "decoding Unicode is not supported"); ! return NULL; } ! return PyObject_Unicode(obj); } ! #else ! if (PyUnicode_Check(obj)) { ! PyErr_SetString(PyExc_TypeError, ! "decoding Unicode is not supported"); ! return NULL; } ! #endif ! ! /* Coerce object */ ! if (PyString_Check(obj)) { s = PyString_AS_STRING(obj); len = PyString_GET_SIZE(obj); } ! else if (PyObject_AsCharBuffer(obj, &s, &len)) { ! /* Overwrite the error message with something more useful in ! case of a TypeError. */ ! if (PyErr_ExceptionMatches(PyExc_TypeError)) PyErr_Format(PyExc_TypeError, ! "coercing to Unicode: need string or buffer, " ! "%.80s found", obj->ob_type->tp_name); goto onError; *************** *** 482,486 **** v = PyUnicode_Decode(s, len, encoding, errors); - done: if (owned) { Py_DECREF(obj); --- 474,477 ---- *************** *** 5654,5657 **** --- 5645,5651 ---- if (x == NULL) return (PyObject *)_PyUnicode_New(0); + if (encoding == NULL && errors == NULL) + return PyObject_Unicode(x); + else return PyUnicode_FromEncodedObject(x, encoding, errors); } From gvanrossum@users.sourceforge.net Fri Oct 19 03:05:37 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 18 Oct 2001 19:05:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.287,1.288 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv10004 Modified Files: NEWS Log Message: Note the Unicode changes from SF patch #470578. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.287 retrieving revision 1.288 diff -C2 -d -r1.287 -r1.288 *** NEWS 2001/10/19 01:31:59 1.287 --- NEWS 2001/10/19 02:05:35 1.288 *************** *** 1,4 **** What's New in Python 2.2b1? ! Release date: 28-Sep-2100 =========================== --- 1,4 ---- What's New in Python 2.2b1? ! Release date: 19-Oct-2001 =========================== *************** *** 41,44 **** --- 41,49 ---- proxy reference has been fixed. + - unicode(obj) now behaves more like str(obj), accepting arbitrary + objects, and calling a __unicode__ method if it exists. + unicode(obj, encoding) and unicode(obj, encoding, errors) still + require an 8-bit string argument. + Extension modules *************** *** 131,134 **** --- 136,142 ---- tested on Linux and Windows; other platforms please beware (and report any bugs or strange behavior). + + - PyUnicode_FromEncodedObject() no longer accepts Unicode objects as + input. New platforms From jhylton@users.sourceforge.net Fri Oct 19 04:40:21 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 18 Oct 2001 20:40:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.288,1.289 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv24791 Modified Files: NEWS Log Message: Add entry for RAND_xxx() functions in socket module. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.288 retrieving revision 1.289 diff -C2 -d -r1.288 -r1.289 *** NEWS 2001/10/19 02:05:35 1.288 --- NEWS 2001/10/19 03:40:19 1.289 *************** *** 71,74 **** --- 71,79 ---- of memory to use for the uncompressed data. + - optional SSL support in the socket module now exports OpenSSL + functions RAND_add(), RAND_egd(), and RAND_status(). These calls + are useful on platforms like Solaris where OpenSSL does not + automatically seed its PRNG. + Library From bwarsaw@users.sourceforge.net Fri Oct 19 05:06:41 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 18 Oct 2001 21:06:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email Generator.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv28744 Modified Files: Generator.py Log Message: Another merge from mimelib: _handle_multipart(): If there is an epilogue and the epilogue does not itself start with a newline, add a newline before writing the epilogue. Closes SF bug #472481. Index: Generator.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Generator.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Generator.py 2001/10/17 20:51:42 1.5 --- Generator.py 2001/10/19 04:06:39 1.6 *************** *** 274,277 **** --- 274,279 ---- # Write out any epilogue if msg.epilogue is not None: + if not msg.epilogue.startswith('\n'): + print >> self._fp self._fp.write(msg.epilogue) From bwarsaw@users.sourceforge.net Fri Oct 19 05:07:29 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 18 Oct 2001 21:07:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/data msg_21.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/data In directory usw-pr-cvs1:/tmp/cvs-serv28907/Lib/test/data Added Files: msg_21.txt Log Message: Another email package test file --- NEW FILE: msg_21.txt --- From: aperson@dom.ain To: bperson@dom.ain Subject: Test Content-Type: multipart/mixed; boundary="BOUNDARY" MIME message --BOUNDARY Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit One --BOUNDARY Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Two --BOUNDARY-- End of MIME message From bwarsaw@users.sourceforge.net Fri Oct 19 05:09:01 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 18 Oct 2001 21:09:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_email.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv29156 Modified Files: test_email.py Log Message: Another merge from mimelib: TestMIMEMessage.test_epilogue(), TestIdempotent.test_preamble_epilogue(): Test cases for SF bug #472481. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_email.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_email.py 2001/10/18 21:57:37 1.12 --- test_email.py 2001/10/19 04:08:59 1.13 *************** *** 27,30 **** --- 27,31 ---- from test_support import findfile + NL = '\n' EMPTYSTRING = '' *************** *** 697,700 **** --- 698,723 ---- '<002001c144a6$8752e060$56104586@oxy.edu>') + def test_epilogue(self): + fp = openfile('msg_21.txt') + try: + text = fp.read() + finally: + fp.close() + msg = Message() + msg['From'] = 'aperson@dom.ain' + msg['To'] = 'bperson@dom.ain' + msg['Subject'] = 'Test' + msg.preamble = 'MIME message\n' + msg.epilogue = 'End of MIME message\n' + msg1 = MIMEText('One') + msg2 = MIMEText('Two') + msg.add_header('Content-Type', 'multipart/mixed', boundary='BOUNDARY') + msg.add_payload(msg1) + msg.add_payload(msg2) + sfp = StringIO() + g = Generator(sfp) + g(msg) + self.assertEqual(sfp.getvalue(), text) + *************** *** 759,762 **** --- 782,789 ---- def test_dsn(self): msg, text = self._msgobj('msg_16.txt') + self._idempotent(msg, text) + + def test_preamble_epilogue(self): + msg, text = self._msgobj('msg_21.txt') self._idempotent(msg, text) From bwarsaw@users.sourceforge.net Fri Oct 19 05:34:45 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 18 Oct 2001 21:34:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib emailmessage.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv978 Modified Files: emailmessage.tex Log Message: Added a note about the somewhat kludgey behavior of the message epilogue, based on the discussion in this SF bug report: https://sourceforge.net/tracker/index.php?func=detail&aid=472481&group_id=25568&atid=384678 Index: emailmessage.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailmessage.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** emailmessage.tex 2001/09/26 22:21:52 1.2 --- emailmessage.tex 2001/10/19 04:34:42 1.3 *************** *** 391,393 **** --- 391,403 ---- attribute, except that it contains text that appears between the last boundary and the end of the message. + + One note: when generating the flat text for a \mimetype{multipart} + message that has no \var{epilogue} (using the standard + \class{Generator} class), no newline is added after the closing + boundary line. If the message object has an \var{epilogue} and its + value does not start with a newline, a newline is printed after the + closing boundary. This seems a little clumsy, but it makes the most + practical sense. The upshot is that if you want to ensure that a + newline get printed after your closing \mimetype{multipart} boundary, + set the \var{epilogue} to the empty string. \end{datadesc} From bwarsaw@users.sourceforge.net Fri Oct 19 05:36:42 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 18 Oct 2001 21:36:42 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv1254 Modified Files: pep-0101.txt Log Message: Get rid of the note about verifications -- they've already been done. Index: pep-0101.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0101.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pep-0101.txt 2001/09/28 17:16:35 1.6 --- pep-0101.txt 2001/10/19 04:36:40 1.7 *************** *** 19,26 **** the steps needed to make a Python release. - (Note: These steps were recorded during the Python 2.2a2 release - done by Barry and Guido. It will be checked for accuracy with the - subsequent release, to be done by Barry.) - How to Make A Release --- 19,22 ---- From bwarsaw@users.sourceforge.net Fri Oct 19 06:35:42 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 18 Oct 2001 22:35:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.289,1.290 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv9267 Modified Files: NEWS Log Message: Last minute updates for changes since 2.2a4. Unless Fred wants to add anything about the hotshot profiler, this file is ready for the 2.2b1 Windows build. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.289 retrieving revision 1.290 diff -C2 -d -r1.289 -r1.290 *** NEWS 2001/10/19 03:40:19 1.289 --- NEWS 2001/10/19 05:35:40 1.290 *************** *** 39,43 **** - Weak reference objects are now part of the core and offers a C API. A bug which could allow a core dump when binary operations involved ! proxy reference has been fixed. - unicode(obj) now behaves more like str(obj), accepting arbitrary --- 39,44 ---- - Weak reference objects are now part of the core and offers a C API. A bug which could allow a core dump when binary operations involved ! proxy reference has been fixed. weekref.ReferenceError is now a ! built-in exception. - unicode(obj) now behaves more like str(obj), accepting arbitrary *************** *** 46,49 **** --- 47,61 ---- require an 8-bit string argument. + - isinstance() now allows any object as the first argument and a + class, a type or something with a __bases__ tuple attribute for the + second argument. The second argument may also be a tuple of a + class, type, or something with __bases__, in which case isinstance() + will return true if the first argument is an instance of any of the + things contained in the second argument tuple. E.g. + + isinstance(x, (A, B)) + + returns true if x is an instance of A or B. + Extension modules *************** *** 74,78 **** functions RAND_add(), RAND_egd(), and RAND_status(). These calls are useful on platforms like Solaris where OpenSSL does not ! automatically seed its PRNG. Library --- 86,94 ---- functions RAND_add(), RAND_egd(), and RAND_status(). These calls are useful on platforms like Solaris where OpenSSL does not ! automatically seed its PRNG. Also, the keyfile and certfile ! arguments to socket.ssl() are now optional. ! ! - posixmodule (and by extension, the os module on POSIX platforms) now ! exports O_LARGEFILE, O_DIRECT, O_DIRECTORY, and O_NOFOLLOW. Library *************** *** 115,118 **** --- 131,147 ---- finish_request() returns. (Not when it errors out though.) + - The nntplib module's NNTP.body() method has grown a `file' argument + to allow saving the message body to a file. + + - The email package has added a class email.Parser.HeaderParser which + only parses headers and does not recurse into the message's body. + Also, the module/class MIMEAudio has been added for representing + audio data (contributed by Anthony Baxter). + + - ftplib should be able to handle files > 2GB. + + - ConfigParser.getboolean() now also interprets TRUE, FALSE, YES, NO, + ON, and OFF. + Tools/Demos *************** *** 121,125 **** --- 150,160 ---- http://PyDNS.SourceForge.net. + - The freeze tool has been made more robust, and two new options have + been added: -X and -E. + Build + + - configure will use CXX in LINKCC if CXX is used to build main() and + the system requires to link a C++ main using the C++ compiler. C API From bwarsaw@users.sourceforge.net Fri Oct 19 06:43:51 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 18 Oct 2001 22:43:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include patchlevel.h,2.55,2.55.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv10418 Modified Files: Tag: r22b1-branch patchlevel.h Log Message: Bump the version number to 2.2b1 Index: patchlevel.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/patchlevel.h,v retrieving revision 2.55 retrieving revision 2.55.2.1 diff -C2 -d -r2.55 -r2.55.2.1 *** patchlevel.h 2001/09/28 17:15:23 2.55 --- patchlevel.h 2001/10/19 05:43:49 2.55.2.1 *************** *** 23,31 **** #define PY_MINOR_VERSION 2 #define PY_MICRO_VERSION 0 ! #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA ! #define PY_RELEASE_SERIAL 4 /* Version as a string */ ! #define PY_VERSION "2.2a4+" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. --- 23,31 ---- #define PY_MINOR_VERSION 2 #define PY_MICRO_VERSION 0 ! #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA ! #define PY_RELEASE_SERIAL 1 /* Version as a string */ ! #define PY_VERSION "2.2b1" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From theller@users.sourceforge.net Fri Oct 19 09:07:21 2001 From: theller@users.sourceforge.net (Thomas Heller) Date: Fri, 19 Oct 2001 01:07:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils __init__.py,1.19,1.19.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory usw-pr-cvs1:/tmp/cvs-serv5796 Modified Files: Tag: release21-maint __init__.py Log Message: The version number 1.0.2pre doesn't conform to the strict versioning guidelines in distutils/version, resulting in failure when trying to use distutils to install 4Suite (and perhaps other modules). Change it to 1.0.2. This finally really fixes Bug #417796. Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/__init__.py,v retrieving revision 1.19 retrieving revision 1.19.2.1 diff -C2 -d -r1.19 -r1.19.2.1 *** __init__.py 2001/03/16 21:00:18 1.19 --- __init__.py 2001/10/19 08:07:19 1.19.2.1 *************** *** 11,13 **** __revision__ = "$Id$" ! __version__ = "1.0.2pre" --- 11,13 ---- __revision__ = "$Id$" ! __version__ = "1.0.2" From mal@lemburg.com Fri Oct 19 09:48:33 2001 From: mal@lemburg.com (M.-A. Lemburg) Date: Fri, 19 Oct 2001 10:48:33 +0200 Subject: [Python-checkins] CVS: python/dist/src/Include unicodeobject.h,2.35,2.36 References: Message-ID: <3BCFE8E1.4E3666B4@lemburg.com> Guido van Rossum wrote: > > Update of /cvsroot/python/python/dist/src/Include > In directory usw-pr-cvs1:/tmp/cvs-serv8577/Include > > Modified Files: > unicodeobject.h > Log Message: > SF patch #470578: Fixes to synchronize unicode() and str() > > [Marc-Andre didn't have time to check this in before the deadline. I > hope this is OK, Marc-Andre! You can still make changes and commit > them on the trunk after the branch has been made, but then please mail > Barry a context diff if you want the change to be merged into the > 2.2b1 release branch. GvR] Thanks Guido ! I'll write the tests and docs for this today and send the diffs to Barry. -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Consulting & Company: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/ From lemburg@users.sourceforge.net Fri Oct 19 13:02:30 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Fri, 19 Oct 2001 05:02:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_unicode,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv29027/Lib/test/output Modified Files: test_unicode Log Message: Additional test and documentation for the unicode() changes. This patch should also be applied to the 2.2b1 trunk. Index: test_unicode =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_unicode,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_unicode 2001/09/20 17:22:58 1.12 --- test_unicode 2001/10/19 12:02:28 1.13 *************** *** 3,6 **** --- 3,7 ---- Testing Unicode contains method... done. Testing Unicode formatting strings... done. + Testing builtin unicode()... done. Testing builtin codecs... done. Testing standard mapping codecs... 0-127... 128-255... done. From lemburg@users.sourceforge.net Fri Oct 19 13:02:30 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Fri, 19 Oct 2001 05:02:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_unicode.py,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv29027/Lib/test Modified Files: test_unicode.py Log Message: Additional test and documentation for the unicode() changes. This patch should also be applied to the 2.2b1 trunk. Index: test_unicode.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** test_unicode.py 2001/10/04 05:36:56 1.41 --- test_unicode.py 2001/10/19 12:02:28 1.42 *************** *** 390,393 **** --- 390,454 ---- print 'done.' + print 'Testing builtin unicode()...', + + # unicode(obj) tests (this maps to PyObject_Unicode() at C level) + + verify(unicode(u'unicode remains unicode') == u'unicode remains unicode') + + class UnicodeSubclass(unicode): + pass + + verify(unicode(UnicodeSubclass('unicode subclass becomes unicode')) + == u'unicode subclass becomes unicode') + + verify(unicode('strings are converted to unicode') + == u'strings are converted to unicode') + + class UnicodeCompat: + def __init__(self, x): + self.x = x + def __unicode__(self): + return self.x + + verify(unicode(UnicodeCompat('__unicode__ compatible objects are recognized')) + == u'__unicode__ compatible objects are recognized') + + class StringCompat: + def __init__(self, x): + self.x = x + def __str__(self): + return self.x + + verify(unicode(StringCompat('__str__ compatible objects are recognized')) + == u'__str__ compatible objects are recognized') + + # unicode(obj) is compatible to str(): + + o = StringCompat('unicode(obj) is compatible to str()') + verify(unicode(o) == u'unicode(obj) is compatible to str()') + verify(str(o) == 'unicode(obj) is compatible to str()') + + for obj in (123, 123.45, 123L): + verify(unicode(obj) == unicode(str(obj))) + + # unicode(obj, encoding, error) tests (this maps to + # PyUnicode_FromEncodedObject() at C level) + + try: + unicode(u'decoding unicode is not supported', 'utf-8', 'strict') + except TypeError: + pass + else: + raise TestFailed, "decoding unicode should NOT be supported" + + verify(unicode('strings are decoded to unicode', 'utf-8', 'strict') + == u'strings are decoded to unicode') + + verify(unicode(buffer('character buffers are decoded to unicode'), + 'utf-8', 'strict') + == u'character buffers are decoded to unicode') + + print 'done.' + # Test builtin codecs print 'Testing builtin codecs...', *************** *** 438,466 **** # UTF8_ERROR cases in PyUnicode_DecodeUTF8 - - verify(unicode('hello','ascii') == u'hello') verify(unicode('hello','utf-8') == u'hello') verify(unicode('hello','utf8') == u'hello') verify(unicode('hello','latin-1') == u'hello') - - # Compatibility to str(): - class String: - x = '' - def __str__(self): - return self.x - - o = String() - - o.x = 'abc' - verify(unicode(o) == u'abc') - verify(str(o) == 'abc') - - o.x = u'abc' - verify(unicode(o) == u'abc') - verify(str(o) == 'abc') - - for obj in (123, 123.45, 123L): - verify(unicode(obj) == unicode(str(obj))) # Error handling --- 499,506 ---- From lemburg@users.sourceforge.net Fri Oct 19 13:02:31 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Fri, 19 Oct 2001 05:02:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.290,1.291 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv29027/Misc Modified Files: NEWS Log Message: Additional test and documentation for the unicode() changes. This patch should also be applied to the 2.2b1 trunk. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.290 retrieving revision 1.291 diff -C2 -d -r1.290 -r1.291 *** NEWS 2001/10/19 05:35:40 1.290 --- NEWS 2001/10/19 12:02:28 1.291 *************** *** 45,49 **** objects, and calling a __unicode__ method if it exists. unicode(obj, encoding) and unicode(obj, encoding, errors) still ! require an 8-bit string argument. - isinstance() now allows any object as the first argument and a --- 45,49 ---- objects, and calling a __unicode__ method if it exists. unicode(obj, encoding) and unicode(obj, encoding, errors) still ! require an 8-bit string or character buffer argument. - isinstance() now allows any object as the first argument and a From lemburg@users.sourceforge.net Fri Oct 19 13:02:30 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Fri, 19 Oct 2001 05:02:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.90,1.91 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv29027/Doc/lib Modified Files: libfuncs.tex Log Message: Additional test and documentation for the unicode() changes. This patch should also be applied to the 2.2b1 trunk. Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.90 retrieving revision 1.91 diff -C2 -d -r1.90 -r1.91 *** libfuncs.tex 2001/10/09 19:31:08 1.90 --- libfuncs.tex 2001/10/19 12:02:28 1.91 *************** *** 759,775 **** \end{funcdesc} ! \begin{funcdesc}{unicode}{string\optional{, encoding\optional{, errors}}} ! Create a Unicode string from an 8-bit string \var{string} using the ! codec for \var{encoding}. The \var{encoding} parameter is a string ! giving the name of an encoding. Error handling is done according to ! \var{errors}; this specifies the treatment of characters which are ! invalid in the input encoding. If \var{errors} is \code{'strict'} ! (the default), a \exception{ValueError} is raised on errors, while a ! value of \code{'ignore'} causes errors to be silently ignored, and a ! value of \code{'replace'} causes the official Unicode replacement ! character, \code{U+FFFD}, to be used to replace input characters ! which cannot be decoded. The default behavior is to decode UTF-8 in ! strict mode, meaning that encoding errors raise ! \exception{ValueError}. See also the \refmodule{codecs} module. \versionadded{2.0} \end{funcdesc} --- 759,789 ---- \end{funcdesc} ! \begin{funcdesc}{unicode}{object\optional{, encoding\optional{, errors}}} ! Return the Unicode string version of \var{object} using one of the ! following modes: ! ! If \var{encoding} and/or \var{errors} are given, \code{unicode()} ! will decode the object which can either be an 8-bit string or a ! character buffer using the codec for \var{encoding}. The ! \var{encoding} parameter is a string giving the name of an encoding. ! Error handling is done according to \var{errors}; this specifies the ! treatment of characters which are invalid in the input encoding. If ! \var{errors} is \code{'strict'} (the default), a ! \exception{ValueError} is raised on errors, while a value of ! \code{'ignore'} causes errors to be silently ignored, and a value of ! \code{'replace'} causes the official Unicode replacement character, ! \code{U+FFFD}, to be used to replace input characters which cannot ! be decoded. See also the \refmodule{codecs} module. ! ! If no optional parameters are given, \code{unicode()} will mimic the ! behaviour of \code{str()} except that it returns Unicode strings ! instead of 8-bit strings. More precisely, if \var{object} is an ! Unicode string or subclass it will return a Unicode string without ! any additional decoding applied. For objects which provide a ! \code{__unicode__} method, it will call this method without ! arguments to create a Unicode string. For all other objects, the ! 8-bit string version or representation is requested and then ! converted to a Unicode string using the codec for the default ! encoding in \code{'strict'} mode. \versionadded{2.0} \end{funcdesc} From lemburg@users.sourceforge.net Fri Oct 19 13:02:31 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Fri, 19 Oct 2001 05:02:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.119,2.120 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv29027/Objects Modified Files: unicodeobject.c Log Message: Additional test and documentation for the unicode() changes. This patch should also be applied to the 2.2b1 trunk. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.119 retrieving revision 2.120 diff -C2 -d -r2.119 -r2.120 *** unicodeobject.c 2001/10/19 02:01:31 2.119 --- unicodeobject.c 2001/10/19 12:02:29 2.120 *************** *** 427,432 **** #if 0 /* For b/w compatibility we also accept Unicode objects provided ! that no encodings is given and then redirect to PyObject_Unicode() ! which then applies the additional logic for Unicode subclasses. NOTE: This API should really only be used for object which --- 427,433 ---- #if 0 /* For b/w compatibility we also accept Unicode objects provided ! that no encodings is given and then redirect to ! PyObject_Unicode() which then applies the additional logic for ! Unicode subclasses. NOTE: This API should really only be used for object which From gvanrossum@users.sourceforge.net Fri Oct 19 13:30:29 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 19 Oct 2001 05:30:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.182,1.182.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv8546 Modified Files: Tag: r22b1-branch socketmodule.c Log Message: (Hopefully) fix SF bug #472675: CVS socketmodule now doesn't compile This appears to be a case of a missing \n\ in a multiline string literal. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.182 retrieving revision 1.182.2.1 diff -C2 -d -r1.182 -r1.182.2.1 *** socketmodule.c 2001/10/18 00:28:50 1.182 --- socketmodule.c 2001/10/19 12:30:26 1.182.2.1 *************** *** 2818,2822 **** static char PySSL_RAND_egd_doc[] = ! "RAND_egd(path) -> bytes \n\ Queries the entropy gather daemon (EGD) on socket path. Returns number\n\ --- 2818,2822 ---- static char PySSL_RAND_egd_doc[] = ! "RAND_egd(path) -> bytes\n\ \n\ Queries the entropy gather daemon (EGD) on socket path. Returns number\n\ From gvanrossum@users.sourceforge.net Fri Oct 19 13:40:43 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 19 Oct 2001 05:40:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.182,1.183 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv11742 Modified Files: socketmodule.c Log Message: (Hopefully) fix SF bug #472675: CVS socketmodule now doesn't compile This appears to be a case of a missing \n\ in a multiline string literal. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.182 retrieving revision 1.183 diff -C2 -d -r1.182 -r1.183 *** socketmodule.c 2001/10/18 00:28:50 1.182 --- socketmodule.c 2001/10/19 12:40:40 1.183 *************** *** 2818,2822 **** static char PySSL_RAND_egd_doc[] = ! "RAND_egd(path) -> bytes \n\ Queries the entropy gather daemon (EGD) on socket path. Returns number\n\ --- 2818,2822 ---- static char PySSL_RAND_egd_doc[] = ! "RAND_egd(path) -> bytes\n\ \n\ Queries the entropy gather daemon (EGD) on socket path. Returns number\n\ From theller@users.sourceforge.net Fri Oct 19 14:49:38 2001 From: theller@users.sourceforge.net (Thomas Heller) Date: Fri, 19 Oct 2001 06:49:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects bufferobject.c,2.15,2.16 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv1921 Modified Files: bufferobject.c Log Message: Fix for Bug #216405: use the correct base for a buffer object in _PyBuffer_FromObject. Index: bufferobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/bufferobject.c,v retrieving revision 2.15 retrieving revision 2.16 diff -C2 -d -r2.15 -r2.16 *** bufferobject.c 2001/08/24 18:34:26 2.15 --- bufferobject.c 2001/10/19 13:49:35 2.16 *************** *** 74,82 **** if ( offset + size > count ) size = count - offset; ! ! /* if the base object is another buffer, then "deref" it */ ! if ( PyBuffer_Check(base) ) base = ((PyBufferObject *)base)->b_base; ! return _PyBuffer_FromMemory(base, (char *)p + offset, size, readonly); } --- 74,84 ---- if ( offset + size > count ) size = count - offset; ! ! /* if the base object is another buffer, then "deref" it, ! * except if the base of the other buffer is NULL ! */ ! if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) base = ((PyBufferObject *)base)->b_base; ! return _PyBuffer_FromMemory(base, (char *)p + offset, size, readonly); } From gvanrossum@users.sourceforge.net Fri Oct 19 15:06:35 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 19 Oct 2001 07:06:35 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0042.txt,1.55,1.56 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv5546 Modified Files: pep-0042.txt Log Message: Buffer interface thing got fixed. Index: pep-0042.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0042.txt,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** pep-0042.txt 2001/09/05 20:18:49 1.55 --- pep-0042.txt 2001/10/19 14:06:33 1.56 *************** *** 56,67 **** http://sf.net/bugs/?func=detailbug&bug_id=115555&group_id=5470 - - The buffer interface could be smarter when a buffer object is - created that depends on another buffer object -- if the - original buffer object has no base, the depending object will - have no base either. It could be argued that the depending - object should have the original object as a base. Or not. - - http://sf.net/bugs/?func=detailbug&bug_id=116405&group_id=5470 - - Non-accidental IEEE-754 support (Infs, NaNs, settable traps, etc). Big project. --- 56,59 ---- From fdrake@acm.org Fri Oct 19 15:16:05 2001 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Fri, 19 Oct 2001 10:16:05 -0400 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.90,1.91 In-Reply-To: References: Message-ID: <15312.13733.32324.229579@grendel.zope.com> M.-A. Lemburg writes: > Additional test and documentation for the unicode() changes. > > This patch should also be applied to the 2.2b1 trunk. This missed the beta1 docs, but I'll update the devel-docs area on python.sourceforge.net sometime today. -Fred -- Fred L. Drake, Jr. PythonLabs at Zope Corporation From gvanrossum@users.sourceforge.net Fri Oct 19 15:47:49 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 19 Oct 2001 07:47:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include patchlevel.h,2.49.2.3,2.49.2.4 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv17037 Modified Files: Tag: release21-maint patchlevel.h Log Message: Add a '+' to the version to indicate this is a post-2.1.1-release CVS version. Index: patchlevel.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/patchlevel.h,v retrieving revision 2.49.2.3 retrieving revision 2.49.2.4 diff -C2 -d -r2.49.2.3 -r2.49.2.4 *** patchlevel.h 2001/07/18 19:40:14 2.49.2.3 --- patchlevel.h 2001/10/19 14:47:47 2.49.2.4 *************** *** 27,34 **** /* Version as a string */ ! #define PY_VERSION "2.1.1" /* Historic */ ! #define PATCHLEVEL "2.1.1" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. --- 27,34 ---- /* Version as a string */ ! #define PY_VERSION "2.1.1+" /* Historic */ ! #define PATCHLEVEL "2.1.1+" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From bwarsaw@users.sourceforge.net Fri Oct 19 16:04:38 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 19 Oct 2001 08:04:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_unicode,1.12,1.12.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv21381/Lib/test/output Modified Files: Tag: r22b1-branch test_unicode Log Message: Merging MAL's trunk changes into the branch: Additional test and documentation for the unicode() changes. This patch should also be applied to the 2.2b1 trunk. Index: test_unicode =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_unicode,v retrieving revision 1.12 retrieving revision 1.12.4.1 diff -C2 -d -r1.12 -r1.12.4.1 *** test_unicode 2001/09/20 17:22:58 1.12 --- test_unicode 2001/10/19 15:04:35 1.12.4.1 *************** *** 3,6 **** --- 3,7 ---- Testing Unicode contains method... done. Testing Unicode formatting strings... done. + Testing builtin unicode()... done. Testing builtin codecs... done. Testing standard mapping codecs... 0-127... 128-255... done. From bwarsaw@users.sourceforge.net Fri Oct 19 16:04:38 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 19 Oct 2001 08:04:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.290,1.290.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv21381/Misc Modified Files: Tag: r22b1-branch NEWS Log Message: Merging MAL's trunk changes into the branch: Additional test and documentation for the unicode() changes. This patch should also be applied to the 2.2b1 trunk. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.290 retrieving revision 1.290.2.1 diff -C2 -d -r1.290 -r1.290.2.1 *** NEWS 2001/10/19 05:35:40 1.290 --- NEWS 2001/10/19 15:04:36 1.290.2.1 *************** *** 45,49 **** objects, and calling a __unicode__ method if it exists. unicode(obj, encoding) and unicode(obj, encoding, errors) still ! require an 8-bit string argument. - isinstance() now allows any object as the first argument and a --- 45,49 ---- objects, and calling a __unicode__ method if it exists. unicode(obj, encoding) and unicode(obj, encoding, errors) still ! require an 8-bit string or character buffer argument. - isinstance() now allows any object as the first argument and a From bwarsaw@users.sourceforge.net Fri Oct 19 16:04:38 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 19 Oct 2001 08:04:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_unicode.py,1.41,1.41.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21381/Lib/test Modified Files: Tag: r22b1-branch test_unicode.py Log Message: Merging MAL's trunk changes into the branch: Additional test and documentation for the unicode() changes. This patch should also be applied to the 2.2b1 trunk. Index: test_unicode.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode.py,v retrieving revision 1.41 retrieving revision 1.41.2.1 diff -C2 -d -r1.41 -r1.41.2.1 *** test_unicode.py 2001/10/04 05:36:56 1.41 --- test_unicode.py 2001/10/19 15:04:35 1.41.2.1 *************** *** 390,393 **** --- 390,454 ---- print 'done.' + print 'Testing builtin unicode()...', + + # unicode(obj) tests (this maps to PyObject_Unicode() at C level) + + verify(unicode(u'unicode remains unicode') == u'unicode remains unicode') + + class UnicodeSubclass(unicode): + pass + + verify(unicode(UnicodeSubclass('unicode subclass becomes unicode')) + == u'unicode subclass becomes unicode') + + verify(unicode('strings are converted to unicode') + == u'strings are converted to unicode') + + class UnicodeCompat: + def __init__(self, x): + self.x = x + def __unicode__(self): + return self.x + + verify(unicode(UnicodeCompat('__unicode__ compatible objects are recognized')) + == u'__unicode__ compatible objects are recognized') + + class StringCompat: + def __init__(self, x): + self.x = x + def __str__(self): + return self.x + + verify(unicode(StringCompat('__str__ compatible objects are recognized')) + == u'__str__ compatible objects are recognized') + + # unicode(obj) is compatible to str(): + + o = StringCompat('unicode(obj) is compatible to str()') + verify(unicode(o) == u'unicode(obj) is compatible to str()') + verify(str(o) == 'unicode(obj) is compatible to str()') + + for obj in (123, 123.45, 123L): + verify(unicode(obj) == unicode(str(obj))) + + # unicode(obj, encoding, error) tests (this maps to + # PyUnicode_FromEncodedObject() at C level) + + try: + unicode(u'decoding unicode is not supported', 'utf-8', 'strict') + except TypeError: + pass + else: + raise TestFailed, "decoding unicode should NOT be supported" + + verify(unicode('strings are decoded to unicode', 'utf-8', 'strict') + == u'strings are decoded to unicode') + + verify(unicode(buffer('character buffers are decoded to unicode'), + 'utf-8', 'strict') + == u'character buffers are decoded to unicode') + + print 'done.' + # Test builtin codecs print 'Testing builtin codecs...', *************** *** 438,466 **** # UTF8_ERROR cases in PyUnicode_DecodeUTF8 - - verify(unicode('hello','ascii') == u'hello') verify(unicode('hello','utf-8') == u'hello') verify(unicode('hello','utf8') == u'hello') verify(unicode('hello','latin-1') == u'hello') - - # Compatibility to str(): - class String: - x = '' - def __str__(self): - return self.x - - o = String() - - o.x = 'abc' - verify(unicode(o) == u'abc') - verify(str(o) == 'abc') - - o.x = u'abc' - verify(unicode(o) == u'abc') - verify(str(o) == 'abc') - - for obj in (123, 123.45, 123L): - verify(unicode(obj) == unicode(str(obj))) # Error handling --- 499,506 ---- From bwarsaw@users.sourceforge.net Fri Oct 19 16:04:37 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 19 Oct 2001 08:04:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.90,1.90.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv21381/Doc/lib Modified Files: Tag: r22b1-branch libfuncs.tex Log Message: Merging MAL's trunk changes into the branch: Additional test and documentation for the unicode() changes. This patch should also be applied to the 2.2b1 trunk. Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.90 retrieving revision 1.90.2.1 diff -C2 -d -r1.90 -r1.90.2.1 *** libfuncs.tex 2001/10/09 19:31:08 1.90 --- libfuncs.tex 2001/10/19 15:04:35 1.90.2.1 *************** *** 759,775 **** \end{funcdesc} ! \begin{funcdesc}{unicode}{string\optional{, encoding\optional{, errors}}} ! Create a Unicode string from an 8-bit string \var{string} using the ! codec for \var{encoding}. The \var{encoding} parameter is a string ! giving the name of an encoding. Error handling is done according to ! \var{errors}; this specifies the treatment of characters which are ! invalid in the input encoding. If \var{errors} is \code{'strict'} ! (the default), a \exception{ValueError} is raised on errors, while a ! value of \code{'ignore'} causes errors to be silently ignored, and a ! value of \code{'replace'} causes the official Unicode replacement ! character, \code{U+FFFD}, to be used to replace input characters ! which cannot be decoded. The default behavior is to decode UTF-8 in ! strict mode, meaning that encoding errors raise ! \exception{ValueError}. See also the \refmodule{codecs} module. \versionadded{2.0} \end{funcdesc} --- 759,789 ---- \end{funcdesc} ! \begin{funcdesc}{unicode}{object\optional{, encoding\optional{, errors}}} ! Return the Unicode string version of \var{object} using one of the ! following modes: ! ! If \var{encoding} and/or \var{errors} are given, \code{unicode()} ! will decode the object which can either be an 8-bit string or a ! character buffer using the codec for \var{encoding}. The ! \var{encoding} parameter is a string giving the name of an encoding. ! Error handling is done according to \var{errors}; this specifies the ! treatment of characters which are invalid in the input encoding. If ! \var{errors} is \code{'strict'} (the default), a ! \exception{ValueError} is raised on errors, while a value of ! \code{'ignore'} causes errors to be silently ignored, and a value of ! \code{'replace'} causes the official Unicode replacement character, ! \code{U+FFFD}, to be used to replace input characters which cannot ! be decoded. See also the \refmodule{codecs} module. ! ! If no optional parameters are given, \code{unicode()} will mimic the ! behaviour of \code{str()} except that it returns Unicode strings ! instead of 8-bit strings. More precisely, if \var{object} is an ! Unicode string or subclass it will return a Unicode string without ! any additional decoding applied. For objects which provide a ! \code{__unicode__} method, it will call this method without ! arguments to create a Unicode string. For all other objects, the ! 8-bit string version or representation is requested and then ! converted to a Unicode string using the codec for the default ! encoding in \code{'strict'} mode. \versionadded{2.0} \end{funcdesc} From bwarsaw@users.sourceforge.net Fri Oct 19 16:04:38 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 19 Oct 2001 08:04:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.119,2.119.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv21381/Objects Modified Files: Tag: r22b1-branch unicodeobject.c Log Message: Merging MAL's trunk changes into the branch: Additional test and documentation for the unicode() changes. This patch should also be applied to the 2.2b1 trunk. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.119 retrieving revision 2.119.2.1 diff -C2 -d -r2.119 -r2.119.2.1 *** unicodeobject.c 2001/10/19 02:01:31 2.119 --- unicodeobject.c 2001/10/19 15:04:36 2.119.2.1 *************** *** 427,432 **** #if 0 /* For b/w compatibility we also accept Unicode objects provided ! that no encodings is given and then redirect to PyObject_Unicode() ! which then applies the additional logic for Unicode subclasses. NOTE: This API should really only be used for object which --- 427,433 ---- #if 0 /* For b/w compatibility we also accept Unicode objects provided ! that no encodings is given and then redirect to ! PyObject_Unicode() which then applies the additional logic for ! Unicode subclasses. NOTE: This API should really only be used for object which From gvanrossum@users.sourceforge.net Fri Oct 19 16:13:54 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 19 Oct 2001 08:13:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_profile,NONE,1.1.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv23540/test/output Added Files: Tag: release21-maint test_profile Log Message: Merge in selected changes from profile.py on the trunk. Note that this is *not* a simple-minded merge from the code on the trunk -- that does too much other stuff to be 100% safe for the 2.1.2 release (e.g. getting rid of HotProfile and OldProfile, changing some methods into global functions, a new calibration API). Add the test_profile.py module which verifies that the profiler works as expected. --- NEW FILE: test_profile --- test_profile 53 function calls in 1.000 CPU seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 1.000 1.000 :1(?) 0 0.000 0.000 profile:0(profiler) 1 0.000 0.000 1.000 1.000 profile:0(testfunc()) 1 0.400 0.400 1.000 1.000 test_profile.py:21(testfunc) 2 0.080 0.040 0.600 0.300 test_profile.py:30(helper) 4 0.116 0.029 0.120 0.030 test_profile.py:48(helper1) 8 0.312 0.039 0.400 0.050 test_profile.py:56(helper2) 8 0.064 0.008 0.080 0.010 test_profile.py:66(subhelper) 28 0.028 0.001 0.028 0.001 test_profile.py:78(__getattr__) From gvanrossum@users.sourceforge.net Fri Oct 19 16:13:53 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 19 Oct 2001 08:13:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_profile.py,NONE,1.2.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv23540/test Added Files: Tag: release21-maint test_profile.py Log Message: Merge in selected changes from profile.py on the trunk. Note that this is *not* a simple-minded merge from the code on the trunk -- that does too much other stuff to be 100% safe for the 2.1.2 release (e.g. getting rid of HotProfile and OldProfile, changing some methods into global functions, a new calibration API). Add the test_profile.py module which verifies that the profiler works as expected. --- NEW FILE: test_profile.py --- """Test suite for the profile module.""" import profile # In order to have reproducible time, we simulate a timer in the global # variable 'ticks', which represents simulated time in milliseconds. # (We can't use a helper function increment the timer since it would be # included in the profile and would appear to consume all the time.) ticks = 0 def test_main(): global ticks ticks = 0 prof = profile.Profile(timer) prof.runctx("testfunc()", globals(), globals()) prof.print_stats() def timer(): return ticks*0.001 def testfunc(): # 1 call # 1000 ticks total: 400 ticks local, 600 ticks in subfunctions global ticks ticks += 199 helper() # 300 helper() # 300 ticks += 201 def helper(): # 2 calls # 300 ticks total: 40 ticks local, 260 ticks in subfunctions global ticks ticks += 1 helper1() # 30 ticks += 3 helper1() # 30 ticks += 6 helper2() # 50 ticks += 5 helper2() # 50 ticks += 4 helper2() # 50 ticks += 7 helper2() # 50 ticks += 14 def helper1(): # 4 calls # 30 ticks total: 29 ticks local, 1 tick in subfunctions global ticks ticks += 10 hasattr(C(), "foo") ticks += 19 def helper2(): # 8 calls # 50 ticks local: 39 ticks local, 11 ticks in subfunctions global ticks ticks += 11 hasattr(C(), "bar") # 1 ticks += 13 subhelper() # 10 ticks += 15 def subhelper(): # 8 calls # 10 ticks total: 8 ticks local, 2 ticks in subfunctions global ticks ticks += 2 for i in range(2): try: C().foo # 1 x 2 except AttributeError: ticks += 3 # 3 x 2 class C: def __getattr__(self, name): # 28 calls # 1 tick, local global ticks ticks += 1 raise AttributeError if __name__ == "__main__": test_main() From gvanrossum@users.sourceforge.net Fri Oct 19 16:13:53 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 19 Oct 2001 08:13:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.27,1.27.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv23540 Modified Files: Tag: release21-maint profile.py Log Message: Merge in selected changes from profile.py on the trunk. Note that this is *not* a simple-minded merge from the code on the trunk -- that does too much other stuff to be 100% safe for the 2.1.2 release (e.g. getting rid of HotProfile and OldProfile, changing some methods into global functions, a new calibration API). Add the test_profile.py module which verifies that the profiler works as expected. Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.27 retrieving revision 1.27.2.1 diff -C2 -d -r1.27 -r1.27.2.1 *** profile.py 2001/03/14 20:01:19 1.27 --- profile.py 2001/10/19 15:13:51 1.27.2.1 *************** *** 105,111 **** timing data for the parent frame. [ 1] = Total time spent in this frame's function, excluding time in ! subfunctions ! [ 2] = Cumulative time spent in this frame's function, including time in ! all subfunctions to this frame. [-3] = Name of the function that corresponds to this frame. [-2] = Actual frame that we correspond to (used to sync exception handling) --- 105,111 ---- timing data for the parent frame. [ 1] = Total time spent in this frame's function, excluding time in ! subfunctions (this latter is tallied in cur[2]). ! [ 2] = Total time spent in subfunctions, excluding time executing the ! frame's function (this latter is tallied in cur[1]). [-3] = Name of the function that corresponds to this frame. [-2] = Actual frame that we correspond to (used to sync exception handling) *************** *** 124,128 **** to finish of each invocation of a function, including time spent in all subfunctions. ! [5] = A dictionary indicating for each function name, the number of times it was called by us. """ --- 124,128 ---- to finish of each invocation of a function, including time spent in all subfunctions. ! [4] = A dictionary indicating for each function name, the number of times it was called by us. """ *************** *** 229,250 **** def trace_dispatch_exception(self, frame, t): rt, rtt, rct, rfn, rframe, rcur = self.cur ! if (not rframe is frame) and rcur: return self.trace_dispatch_return(rframe, t) ! return 0 def trace_dispatch_call(self, frame, t): fcode = frame.f_code fn = (fcode.co_filename, fcode.co_firstlineno, fcode.co_name) self.cur = (t, 0, 0, fn, frame, self.cur) ! if self.timings.has_key(fn): ! cc, ns, tt, ct, callers = self.timings[fn] ! self.timings[fn] = cc, ns + 1, tt, ct, callers else: ! self.timings[fn] = 0, 0, 0, 0, {} return 1 def trace_dispatch_return(self, frame, t): ! # if not frame is self.cur[-2]: raise "Bad return", self.cur[3] # Prefix "r" means part of the Returning or exiting frame --- 229,266 ---- def trace_dispatch_exception(self, frame, t): rt, rtt, rct, rfn, rframe, rcur = self.cur ! if (rframe is not frame) and rcur: return self.trace_dispatch_return(rframe, t) ! self.cur = rt, rtt+t, rct, rfn, rframe, rcur ! return 1 def trace_dispatch_call(self, frame, t): + if self.cur and frame.f_back is not self.cur[-2]: + rt, rtt, rct, rfn, rframe, rcur = self.cur + if not isinstance(rframe, Profile.fake_frame): + if rframe.f_back is not frame.f_back: + print rframe, rframe.f_back + print frame, frame.f_back + raise "Bad call", self.cur[-3] + self.trace_dispatch_return(rframe, 0) + if self.cur and frame.f_back is not self.cur[-2]: + raise "Bad call[2]", self.cur[-3] fcode = frame.f_code fn = (fcode.co_filename, fcode.co_firstlineno, fcode.co_name) self.cur = (t, 0, 0, fn, frame, self.cur) ! timings = self.timings ! if timings.has_key(fn): ! cc, ns, tt, ct, callers = timings[fn] ! timings[fn] = cc, ns + 1, tt, ct, callers else: ! timings[fn] = 0, 0, 0, 0, {} return 1 def trace_dispatch_return(self, frame, t): ! if frame is not self.cur[-2]: ! if frame is self.cur[-2].f_back: ! self.trace_dispatch_return(self.cur[-2], 0) ! else: ! raise "Bad return", self.cur[-3] # Prefix "r" means part of the Returning or exiting frame *************** *** 258,262 **** self.cur = pt, ptt+rt, pct+sft, pfn, pframe, pcur ! cc, ns, tt, ct, callers = self.timings[rfn] if not ns: ct = ct + sft --- 274,279 ---- self.cur = pt, ptt+rt, pct+sft, pfn, pframe, pcur ! timings = self.timings ! cc, ns, tt, ct, callers = timings[rfn] if not ns: ct = ct + sft *************** *** 269,273 **** else: callers[pfn] = 1 ! self.timings[rfn] = cc, ns - 1, tt+rtt, ct, callers return 1 --- 286,290 ---- else: callers[pfn] = 1 ! timings[rfn] = cc, ns - 1, tt+rtt, ct, callers return 1 From gvanrossum@users.sourceforge.net Fri Oct 19 16:17:44 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 19 Oct 2001 08:17:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.141.2.1,1.141.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv25228 Modified Files: Tag: release21-maint socketmodule.c Log Message: Fix leak in SSLread in nonblocking mode -- from SF bug #472798. (Not a merge from the code on the trunk -- the trunk has evolved perhaps too much.) Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.141.2.1 retrieving revision 1.141.2.2 diff -C2 -d -r1.141.2.1 -r1.141.2.2 *** socketmodule.c 2001/05/09 19:13:40 1.141.2.1 --- socketmodule.c 2001/10/19 15:17:42 1.141.2.2 *************** *** 2316,2319 **** --- 2316,2320 ---- break; default: + Py_DECREF(buf); return PyErr_SetFromErrno(SSLErrorObject); } From gvanrossum@users.sourceforge.net Fri Oct 19 17:05:57 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 19 Oct 2001 09:05:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_profile.py,1.2.4.1,1.2.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv4116 Modified Files: Tag: release21-maint test_profile.py Log Message: The 2.1 regrest.py doesn't have the test_main() feature yet, so always call test_main() at the end. Index: test_profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_profile.py,v retrieving revision 1.2.4.1 retrieving revision 1.2.4.2 diff -C2 -d -r1.2.4.1 -r1.2.4.2 *** test_profile.py 2001/10/19 15:13:51 1.2.4.1 --- test_profile.py 2001/10/19 16:05:55 1.2.4.2 *************** *** 83,86 **** raise AttributeError ! if __name__ == "__main__": ! test_main() --- 83,85 ---- raise AttributeError ! test_main() From montanaro@users.sourceforge.net Fri Oct 19 17:06:54 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Fri, 19 Oct 2001 09:06:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_xmlrpc.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv4409 Modified Files: test_xmlrpc.py Log Message: added tests for long ints and ints where they are > 32 bits. should have been checked in as part of patch #470254. Index: test_xmlrpc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_xmlrpc.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_xmlrpc.py 2001/10/01 17:47:44 1.1 --- test_xmlrpc.py 2001/10/19 16:06:52 1.2 *************** *** 1,2 **** --- 1,3 ---- + import sys import test_support import unittest *************** *** 5,8 **** --- 6,11 ---- alist = [{'astring': 'foo@bar.baz.spam', 'afloat': 7283.43, + 'anint': 2**20, + 'ashortlong': 2L, 'anotherlist': ['.zyx.41'], 'abase64': xmlrpclib.Binary("my dog has fleas"), *************** *** 15,18 **** --- 18,32 ---- self.assertEquals(alist, xmlrpclib.loads(xmlrpclib.dumps((alist,)))[0][0]) + + def test_dump_big_long(self): + self.assertRaises(OverflowError, xmlrpclib.dumps, (2L**99,)) + + def test_dump_bad_dict(self): + self.assertRaises(TypeError, xmlrpclib.dumps, ({(1,2,3): 1},)) + + def test_dump_big_int(self): + if sys.maxint > 2L**31-1: + self.assertRaises(OverflowError, xmlrpclib.dumps, + (int(2L**34),)) def test_main(): From fdrake@users.sourceforge.net Fri Oct 19 17:11:30 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 19 Oct 2001 09:11:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libprofile.tex,1.32.2.2,1.32.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv5679/Doc/lib Modified Files: Tag: release21-maint libprofile.tex Log Message: Add deprecations for profile.HotProfile and profile.OldProfile, since they will no longer exist in 2.2. Index: libprofile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libprofile.tex,v retrieving revision 1.32.2.2 retrieving revision 1.32.2.3 diff -C2 -d -r1.32.2.2 -r1.32.2.3 *** libprofile.tex 2001/07/02 21:22:56 1.32.2.2 --- libprofile.tex 2001/10/19 16:11:28 1.32.2.3 *************** *** 666,669 **** --- 666,671 ---- \subsection{OldProfile Class \label{profile-old}} + \deprecated{2.1.2}{This class will be removed in Python 2.2.} + The following derived profiler simulates the old style profiler, providing errant results on recursive functions. The reason for the *************** *** 727,730 **** --- 729,734 ---- \subsection{HotProfile Class \label{profile-HotProfile}} + + \deprecated{2.1.2}{This class will be removed in Python 2.2.} This profiler is the fastest derived profile example. It does not From fdrake@users.sourceforge.net Fri Oct 19 18:10:24 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 19 Oct 2001 10:10:24 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv19839 Modified Files: pep-0101.txt Log Message: Added comments about the doc packaging and the removal of the Doc/ tree from the source package. Index: pep-0101.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0101.txt,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** pep-0101.txt 2001/10/19 04:36:40 1.7 --- pep-0101.txt 2001/10/19 17:10:22 1.8 *************** *** 108,112 **** from the documentation. He does this and uploads the file to www.python.org. Then he tells Tim Peters where this file is. ! This may generate some last minute changes on the branch. - Tim Peters grabs the HTML and uses this to build the Windows --- 108,114 ---- from the documentation. He does this and uploads the file to www.python.org. Then he tells Tim Peters where this file is. ! This may generate some last minute changes on the branch. Once ! Fred is done, there can be no further checkins on the branch in ! the Doc/ directory -- not even by the RM. - Tim Peters grabs the HTML and uses this to build the Windows *************** *** 154,160 **** % cvs -d export -rr22a3 -d Python-2.2a3 python/dist/src - Generate the tarball. Note that we're not using the `z' option on the tar command because 1) that's only supported by GNU tar ! as far as we know; 2) we're going to max out the compression level, which isn't a supported option. % tar cf - Python-2.2a2 | gzip -9 > Python-2.2a2.tgz --- 156,170 ---- % cvs -d export -rr22a3 -d Python-2.2a3 python/dist/src + - Remove the documentation sources from the export; these are only + useful to people who have LaTeX and possibly several other tools + installed (how many tools are required depends on the + documentation format you want to end up with). These also add + substantially to the size of the resulting archive (almost a + megabyte for Python 2.2). + % rm -r Python-.2a3/Doc/ + - Generate the tarball. Note that we're not using the `z' option on the tar command because 1) that's only supported by GNU tar ! as far as we know, and 2) we're going to max out the compression level, which isn't a supported option. % tar cf - Python-2.2a2 | gzip -9 > Python-2.2a2.tgz From bwarsaw@users.sourceforge.net Fri Oct 19 18:12:00 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 19 Oct 2001 10:12:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include patchlevel.h,2.55,2.56 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv20215 Modified Files: patchlevel.h Log Message: Updated version numbers for post 2.2b1 development. Index: patchlevel.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/patchlevel.h,v retrieving revision 2.55 retrieving revision 2.56 diff -C2 -d -r2.55 -r2.56 *** patchlevel.h 2001/09/28 17:15:23 2.55 --- patchlevel.h 2001/10/19 17:11:58 2.56 *************** *** 23,31 **** #define PY_MINOR_VERSION 2 #define PY_MICRO_VERSION 0 ! #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA ! #define PY_RELEASE_SERIAL 4 /* Version as a string */ ! #define PY_VERSION "2.2a4+" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. --- 23,31 ---- #define PY_MINOR_VERSION 2 #define PY_MICRO_VERSION 0 ! #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA ! #define PY_RELEASE_SERIAL 1 /* Version as a string */ ! #define PY_VERSION "2.2b1+" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From mal@lemburg.com Fri Oct 19 18:16:09 2001 From: mal@lemburg.com (M.-A. Lemburg) Date: Fri, 19 Oct 2001 19:16:09 +0200 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.90,1.91 References: <15312.13733.32324.229579@grendel.zope.com> Message-ID: <3BD05FD9.6E5EC5CF@lemburg.com> "Fred L. Drake, Jr." wrote: > > M.-A. Lemburg writes: > > Additional test and documentation for the unicode() changes. > > > > This patch should also be applied to the 2.2b1 trunk. > > This missed the beta1 docs, but I'll update the devel-docs area on > python.sourceforge.net sometime today. Thanks ! -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Consulting & Company: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/ From fdrake@users.sourceforge.net Fri Oct 19 18:22:31 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 19 Oct 2001 10:22:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libsocket.tex,1.55,1.56 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv23912/lib Modified Files: libsocket.tex Log Message: When stating that some parameters to makefile() are similar to the open() parameters, given a hyperlink to the right part of the documentation to make it easier to look those up. Also, refer to the file() function/ constructor instead of open() now that that is where the actual docs for those parameters live. This closes SF bug #472004. Index: libsocket.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsocket.tex,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** libsocket.tex 2001/10/11 16:17:22 1.55 --- libsocket.tex 2001/10/19 17:22:29 1.56 *************** *** 453,457 **** \index{I/O control!buffering}The optional \var{mode} and \var{bufsize} arguments are interpreted the same way as by the ! built-in \function{open()} function. \end{methoddesc} --- 453,458 ---- \index{I/O control!buffering}The optional \var{mode} and \var{bufsize} arguments are interpreted the same way as by the ! built-in \function{file()} function; see ``Built-in Functions'' ! (section \ref{built-in-funcs}) for more information. \end{methoddesc} From tim_one@users.sourceforge.net Fri Oct 19 18:55:33 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 19 Oct 2001 10:55:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.291,1.292 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv32586/python/Misc Modified Files: NEWS Log Message: The usual post-release fiddling. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.291 retrieving revision 1.292 diff -C2 -d -r1.291 -r1.292 *** NEWS 2001/10/19 12:02:28 1.291 --- NEWS 2001/10/19 17:55:30 1.292 *************** *** 1,2 **** --- 1,27 ---- + What's New in Python 2.2b2? + XXX Planned XXX Release date: 14-Nov-2001 + =========================== + + Type/class unification and new-style classes + + Core and builtins + + Extension modules + + Library + + Tools/Demos + + Build + + C API + + New platforms + + Tests + + Windows + + What's New in Python 2.2b1? Release date: 19-Oct-2001 From tim_one@users.sourceforge.net Fri Oct 19 18:55:33 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 19 Oct 2001 10:55:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild python20.wse,1.94,1.95 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv32586/python/PCbuild Modified Files: python20.wse Log Message: The usual post-release fiddling. Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.94 retrieving revision 1.95 diff -C2 -d -r1.94 -r1.95 *** python20.wse 2001/10/13 00:26:25 1.94 --- python20.wse 2001/10/19 17:55:30 1.95 *************** *** 2,6 **** item: Global Version=8.14 ! Title=Python 2.2 beta 1 Flags=00010100 Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 --- 2,6 ---- item: Global Version=8.14 ! Title=Python 2.2 beta 2 Flags=00010100 Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 *************** *** 19,25 **** Patch Threshold=85 Patch Memory=4000 ! EXE Filename=Python-2.2b1.exe Dialogs Version=8 ! Version File=2.2b1 Version Description=Python Programming Language Version Copyright=©2001 Python Software Foundation --- 19,25 ---- Patch Threshold=85 Patch Memory=4000 ! EXE Filename=Python-2.2b2.exe Dialogs Version=8 ! Version File=2.2b2 Version Description=Python Programming Language Version Copyright=©2001 Python Software Foundation *************** *** 65,69 **** item: Set Variable Variable=PYVER_STRING ! Value=2.2b1 end item: Remark --- 65,69 ---- item: Set Variable Variable=PYVER_STRING ! Value=2.2b2 end item: Remark From gvanrossum@users.sourceforge.net Fri Oct 19 19:17:02 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 19 Oct 2001 11:17:02 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0253.txt,1.17,1.18 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv5306 Modified Files: pep-0253.txt Log Message: Update open issues a bit. Index: pep-0253.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0253.txt,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** pep-0253.txt 2001/09/21 07:56:16 1.17 --- pep-0253.txt 2001/10/19 18:17:00 1.18 *************** *** 891,901 **** - built-in names for built-in types (object, int, str, list etc.) ! - __dict__ and dictoffset - __slots__ - - - __dynamic__ ! - the HEAPTYPE and DYNAMICTYPE flag bits - GC support --- 891,899 ---- - built-in names for built-in types (object, int, str, list etc.) ! - __dict__ and __dictoffset__ - __slots__ ! - the HEAPTYPE flag bit - GC support *************** *** 910,928 **** - open issues: - - - performance - - - pickling, __reduce__ - - - do we need __coerce__, __del__? - - - should we return to the old __getattr__ semantics, and - introduce a new name (__getallattr__?) for the new semantics? - or introduce a new name (__getattrhook__?) for the old - semantics? ! - whether __dynamic__ should be default ! - assignment to __class__, __dict__, __bases__ - inconsistent naming --- 908,915 ---- - open issues: ! - do we need __del__? ! - assignment to __dict__, __bases__ - inconsistent naming *************** *** 939,945 **** A prototype implementation of this PEP (and for PEP 252) is ! available from CVS, and in the series of Python 2.2 alpha releases. ! For some examples of the features described here, see the file ! Lib/test/test_descr.py and the extension module Modules/xxsubtype.c. --- 926,933 ---- A prototype implementation of this PEP (and for PEP 252) is ! available from CVS, and in the series of Python 2.2 alpha and beta ! releases. For some examples of the features described here, see ! the file Lib/test/test_descr.py and the extension module ! Modules/xxsubtype.c. From fdrake@users.sourceforge.net Fri Oct 19 22:07:28 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 19 Oct 2001 14:07:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/isilo - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Doc/isilo In directory usw-pr-cvs1:/tmp/cvs-serv11528/isilo Log Message: Directory /cvsroot/python/python/dist/src/Doc/isilo added to the repository From fdrake@users.sourceforge.net Fri Oct 19 22:08:38 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 19 Oct 2001 14:08:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/perl isilo.perl,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory usw-pr-cvs1:/tmp/cvs-serv11795/perl Added Files: isilo.perl Log Message: Support for the iSilo conversion. --- NEW FILE: isilo.perl --- package main; $USING_STYLES = 0; $NO_NAVIGATION = 1; $INDEX_COLUMNS = 1; $MODULE_INDEX_COLUMNS = 1; sub child_line { return ''; } 1; # stupid perl... From fdrake@users.sourceforge.net Fri Oct 19 22:09:21 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 19 Oct 2001 14:09:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/isilo .cvsignore,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/isilo In directory usw-pr-cvs1:/tmp/cvs-serv11982/isilo Added Files: .cvsignore Log Message: Hush up CVS. --- NEW FILE: .cvsignore --- api doc ext lib mac ref tut dist inst python-*.pdb From fdrake@users.sourceforge.net Fri Oct 19 22:13:00 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 19 Oct 2001 14:13:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile,1.227,1.228 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv12726 Modified Files: Makefile Log Message: Additional rules to support the iSilo conversion. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile,v retrieving revision 1.227 retrieving revision 1.228 diff -C2 -d -r1.227 -r1.228 *** Makefile 2001/10/18 18:46:22 1.227 --- Makefile 2001/10/19 21:12:57 1.228 *************** *** 77,80 **** --- 77,83 ---- --up-title "Python Documentation Index" \ --global-module-index "../modindex.html" + MKISILOHTML=$(PYTHON) tools/mkhowto --html --about html/stdabout.dat \ + --l2h-init perl/isilo.perl --numeric --split 1 + MKISILO= iSilo386 -U -y -rCR -d0 MKPDF= $(PYTHON) ../tools/mkhowto --paper=$(PAPER) --pdf MKPS= $(PYTHON) ../tools/mkhowto --paper=$(PAPER) --ps *************** *** 127,131 **** # are directories with matching names: .PHONY: api doc ext lib mac ref tut inst dist ! .PHONY: html info --- 130,134 ---- # are directories with matching names: .PHONY: api doc ext lib mac ref tut inst dist ! .PHONY: html info isilo *************** *** 291,294 **** --- 294,395 ---- + # The iSilo format is used by the iSilo document reader for PalmOS devices. + + ISILOINDEXFILES=isilo/api/api.html \ + isilo/doc/doc.html \ + isilo/ext/ext.html \ + isilo/lib/lib.html \ + isilo/mac/mac.html \ + isilo/ref/ref.html \ + isilo/tut/tut.html \ + isilo/inst/inst.html \ + isilo/dist/dist.html + + $(ISILOINDEXFILES): $(COMMONPERL) html/about.dat perl/isilo.perl + + isilo: isilo/python-api-$(RELEASE).pdb \ + isilo/python-doc-$(RELEASE).pdb \ + isilo/python-ext-$(RELEASE).pdb \ + isilo/python-lib-$(RELEASE).pdb \ + isilo/python-mac-$(RELEASE).pdb \ + isilo/python-ref-$(RELEASE).pdb \ + isilo/python-tut-$(RELEASE).pdb \ + isilo/python-dist-$(RELEASE).pdb \ + isilo/python-inst-$(RELEASE).pdb + + isilo/python-api-$(RELEASE).pdb: isilo/api/api.html + $(MKISILO) "-iPython/C API Reference Manual" \ + isilo/api/api.html $@ + + isilo/python-doc-$(RELEASE).pdb: isilo/doc/doc.html + $(MKISILO) "-iDocumenting Python" \ + isilo/doc/doc.html $@ + + isilo/python-ext-$(RELEASE).pdb: isilo/ext/ext.html + $(MKISILO) "-iExtending & Embedding Python" \ + isilo/ext/ext.html $@ + + isilo/python-lib-$(RELEASE).pdb: isilo/lib/lib.html + $(MKISILO) "-iPython Library Reference" \ + isilo/lib/lib.html $@ + + isilo/python-mac-$(RELEASE).pdb: isilo/mac/mac.html + $(MKISILO) "-iPython/C API Reference Manual" \ + isilo/mac/mac.html $@ + + isilo/python-ref-$(RELEASE).pdb: isilo/ref/ref.html + $(MKISILO) "-iPython Reference Manual" \ + isilo/ref/ref.html $@ + + isilo/python-tut-$(RELEASE).pdb: isilo/tut/tut.html + $(MKISILO) "-iPython Tutorial" \ + isilo/tut/tut.html $@ + + isilo/python-dist-$(RELEASE).pdb: isilo/dist/dist.html + $(MKISILO) "-iDistributing Python Modules" \ + isilo/dist/dist.html $@ + + isilo/python-inst-$(RELEASE).pdb: isilo/inst/inst.html + $(MKISILO) "-iInstalling Python Modules" \ + isilo/inst/inst.html $@ + + isilo/api/api.html: $(APIFILES) + $(MKISILOHTML) --dir isilo/api api/api.tex + + isilo/doc/doc.html: $(DOCFILES) + $(MKISILOHTML) --dir isilo/doc doc/doc.tex + + isilo/ext/ext.html: $(EXTFILES) + $(MKISILOHTML) --dir isilo/ext ext/ext.tex + + isilo/lib/lib.html: $(LIBFILES) + $(MKISILOHTML) --dir isilo/lib lib/lib.tex + + isilo/mac/mac.html: $(MACFILES) + $(MKISILOHTML) --dir isilo/mac mac/mac.tex + + isilo/ref/ref.html: $(REFFILES) + $(MKISILOHTML) --dir isilo/ref ref/ref.tex + + isilo/tut/tut.html: $(TUTFILES) + $(MKISILOHTML) --dir isilo/tut tut/tut.tex + + isilo/inst/inst.html: $(INSTFILES) perl/distutils.perl + $(MKISILOHTML) --dir isilo/inst inst/inst.tex + + isilo/dist/dist.html: $(DISTFILES) perl/distutils.perl + $(MKISILOHTML) --dir isilo/dist dist/dist.tex + + # These are useful if you need to transport the iSilo-ready HTML to + # another machine to perform the conversion: + + isilozip: isilo-html-$(RELEASE).zip + + isilo-html-$(RELEASE).zip: $(ISILOINDEXFILES) + rm -f $@ + cd isilo && \ + zip -q -9 ../$@ */*.css */*.html */*.txt + + # webchecker needs an extra flag to process the huge index from the libref WEBCHECKER=$(PYTHON) ../Tools/webchecker/webchecker.py *************** *** 383,386 **** --- 484,491 ---- zip -q -9 ../$@ *.html */*.css */*.html */*.gif */*.txt + isilo-$(RELEASE).zip: isilo + cd isilo && zip -q -9 ../$@ python-*-$(RELEASE).pdb + + # convenience targets: *************** *** 397,400 **** --- 502,506 ---- zippdf: pdf-$(PAPER)-$(RELEASE).zip ziplatex: latex-$(RELEASE).zip + zipisilo: isilo-$(RELEASE).zip zips: zippdf zipps ziphtml *************** *** 442,445 **** --- 548,554 ---- rm -rf html/api/ html/doc/ html/ext/ html/lib/ html/mac/ rm -rf html/ref/ html/tut/ html/inst/ html/dist/ + rm -rf isilo/api/ isilo/doc/ isilo/ext/ isilo/lib/ isilo/mac/ + rm -rf isilo/ref/ isilo/tut/ isilo/inst/ isilo/dist/ + rm -f isilo/python-*-$(RELEASE).pdb isilo-$(RELEASE).zip realclean distclean: clobber From fdrake@users.sourceforge.net Sat Oct 20 05:18:16 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 19 Oct 2001 21:18:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/doc doc.tex,1.55,1.56 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/doc In directory usw-pr-cvs1:/tmp/cvs-serv29407/doc Modified Files: doc.tex Log Message: Describe the content given as the parameter to the \note and \warning macros in more detail, and use them where appropriate. Index: doc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/doc/doc.tex,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** doc.tex 2001/10/09 18:01:23 1.55 --- doc.tex 2001/10/20 04:18:14 1.56 *************** *** 777,782 **** outputs, single quotes and a font change are used to indicate the file name, but no quotes are used in the HTML output. ! \strong{Warning:} The \macro{file} macro cannot be used in the ! content of a section title due to processing limitations. \end{macrodesc} --- 777,782 ---- outputs, single quotes and a font change are used to indicate the file name, but no quotes are used in the HTML output. ! \warning{The \macro{file} macro cannot be used in the ! content of a section title due to processing limitations.} \end{macrodesc} *************** *** 785,790 **** be used in conjunction with tables if a column will only contain file or directory names. ! \strong{Warning:} The \macro{filenq} macro cannot be used in the ! content of a section title due to processing limitations. \end{macrodesc} --- 785,790 ---- be used in conjunction with tables if a column will only contain file or directory names. ! \warning{The \macro{filenq} macro cannot be used in the ! content of a section title due to processing limitations.} \end{macrodesc} *************** *** 865,869 **** note pertains to. This should be the last thing in the paragraph as the end of the note is not visually marked in ! any way. \end{macrodesc} --- 865,870 ---- note pertains to. This should be the last thing in the paragraph as the end of the note is not visually marked in ! any way. The content of \var{text} should be written in ! complete sentences and include all appropriate punctuation. \end{macrodesc} *************** *** 1002,1008 **** be very aware of when using whatever bit of API the warning pertains to. This should be the last thing in the paragraph as ! the end of the warning is not visually marked in any way. This ! differs from \macro{note} in that it is recommended over ! \macro{note} for information regarding security. \end{macrodesc} --- 1003,1011 ---- be very aware of when using whatever bit of API the warning pertains to. This should be the last thing in the paragraph as ! the end of the warning is not visually marked in any way. The ! content of \var{text} should be written in complete sentences ! and include all appropriate punctuation. This differs from ! \macro{note} in that it is recommended over \macro{note} for ! information regarding security. \end{macrodesc} *************** *** 1328,1333 **** \var{key} if necessary. In the HTML and PDF conversions, the module name will be a hyperlink to the referred-to module. ! \strong{Note:} The module must be documented in the same ! document (the corresponding \macro{declaremodule} is required). \end{macrodesc} --- 1331,1336 ---- \var{key} if necessary. In the HTML and PDF conversions, the module name will be a hyperlink to the referred-to module. ! \note{The module must be documented in the same ! document (the corresponding \macro{declaremodule} is required).} \end{macrodesc} From fdrake@users.sourceforge.net Sat Oct 20 05:19:52 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 19 Oct 2001 21:19:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs license.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv29618/texinputs Modified Files: license.tex Log Message: Use the \note and \warning macros where appropriate. Index: license.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/license.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** license.tex 2001/07/17 23:08:24 1.2 --- license.tex 2001/10/20 04:19:50 1.3 *************** *** 37,45 **** \end{tablev} ! \strong{Note:} GPL-compatible doesn't mean that we're distributing Python under the GPL. All Python licenses, unlike the GPL, let you distribute a modified version without making your changes open source. The GPL-compatible licenses make it possible to combine Python with ! other software that is released under the GPL; the others don't. Thanks to the many outside volunteers who have worked under Guido's --- 37,45 ---- \end{tablev} ! \note{GPL-compatible doesn't mean that we're distributing Python under the GPL. All Python licenses, unlike the GPL, let you distribute a modified version without making your changes open source. The GPL-compatible licenses make it possible to combine Python with ! other software that is released under the GPL; the others don't.} Thanks to the many outside volunteers who have worked under Guido's From fdrake@users.sourceforge.net Sat Oct 20 05:19:53 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 19 Oct 2001 21:19:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/mac libctb.tex,1.17,1.18 libmacfs.tex,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/mac In directory usw-pr-cvs1:/tmp/cvs-serv29618/mac Modified Files: libctb.tex libmacfs.tex Log Message: Use the \note and \warning macros where appropriate. Index: libctb.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/mac/libctb.tex,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** libctb.tex 2001/09/11 20:18:04 1.17 --- libctb.tex 2001/10/20 04:19:50 1.18 *************** *** 66,72 **** completion. ! \emph{Note:} for reasons beyond my understanding the callback routine is currently never called. You are advised against using asynchronous ! calls for the time being. \end{memberdesc} --- 66,72 ---- completion. ! \note{For reasons beyond my understanding, the callback routine is currently never called. You are advised against using asynchronous ! calls for the time being.} \end{memberdesc} Index: libmacfs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/mac/libmacfs.tex,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** libmacfs.tex 2000/10/14 04:45:22 1.25 --- libmacfs.tex 2001/10/20 04:19:50 1.26 *************** *** 21,26 **** Standard File package can also be found there. ! \strong{Note:} A module, \refmodule{macfsn}, is auto-imported to replace ! StandardFile calls in macfs with NavServices calls. \begin{funcdesc}{FSSpec}{file} --- 21,26 ---- Standard File package can also be found there. ! \note{A module, \refmodule{macfsn}, is auto-imported to replace ! StandardFile calls in \module{macfs} with NavServices calls.} \begin{funcdesc}{FSSpec}{file} From fdrake@users.sourceforge.net Sat Oct 20 05:19:53 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 19 Oct 2001 21:19:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref3.tex,1.75,1.76 ref7.tex,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv29618/ref Modified Files: ref3.tex ref7.tex Log Message: Use the \note and \warning macros where appropriate. Index: ref3.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v retrieving revision 1.75 retrieving revision 1.76 diff -C2 -d -r1.75 -r1.76 *** ref3.tex 2001/10/01 16:32:13 1.75 --- ref3.tex 2001/10/20 04:19:50 1.76 *************** *** 936,940 **** \code{sys.exc_traceback} or \code{sys.last_traceback}. ! \strong{Warning:} due to the precarious circumstances under which \method{__del__()} methods are invoked, exceptions that occur during their execution are ignored, and a warning is printed to \code{sys.stderr} --- 936,940 ---- \code{sys.exc_traceback} or \code{sys.last_traceback}. ! \warning{Due to the precarious circumstances under which \method{__del__()} methods are invoked, exceptions that occur during their execution are ignored, and a warning is printed to \code{sys.stderr} *************** *** 948,952 **** other references to such globals exist, this may help in assuring that imported modules are still available at the time when the ! \method{__del__()} method is called. \end{methoddesc} --- 948,952 ---- other references to such globals exist, this may help in assuring that imported modules are still available at the time when the ! \method{__del__()} method is called.} \end{methoddesc} *************** *** 1199,1205 **** (after any special interpretation of negative values), \exception{IndexError} should be raised. ! \strong{Note:} \keyword{for} loops expect that an \exception{IndexError} will be raised for illegal indexes to allow ! proper detection of the end of the sequence. \end{methoddesc} --- 1199,1205 ---- (after any special interpretation of negative values), \exception{IndexError} should be raised. ! \note{\keyword{for} loops expect that an \exception{IndexError} will be raised for illegal indexes to allow ! proper detection of the end of the sequence.} \end{methoddesc} Index: ref7.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref7.tex,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** ref7.tex 2001/07/06 22:49:53 1.28 --- ref7.tex 2001/10/20 04:19:51 1.29 *************** *** 162,166 **** \indexii{Pascal}{language} ! \strong{Warning:} There is a subtlety when the sequence is being modified by the loop (this can only occur for mutable sequences, i.e. lists). An internal counter is used to keep track of which item is used next, --- 162,166 ---- \indexii{Pascal}{language} ! \warning{There is a subtlety when the sequence is being modified by the loop (this can only occur for mutable sequences, i.e. lists). An internal counter is used to keep track of which item is used next, *************** *** 175,179 **** copy using a slice of the whole sequence, e.g., \index{loop!over mutable sequence} ! \index{mutable sequence!loop over} \begin{verbatim} --- 175,179 ---- copy using a slice of the whole sequence, e.g., \index{loop!over mutable sequence} ! \index{mutable sequence!loop over}} \begin{verbatim} From fdrake@users.sourceforge.net Sat Oct 20 05:19:52 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 19 Oct 2001 21:19:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ext extending.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ext In directory usw-pr-cvs1:/tmp/cvs-serv29618/ext Modified Files: extending.tex Log Message: Use the \note and \warning macros where appropriate. Index: extending.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/extending.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** extending.tex 2001/09/30 05:09:36 1.3 --- extending.tex 2001/10/20 04:19:50 1.4 *************** *** 385,389 **** Python source distribution. ! \strong{Note:} Removing entries from \code{sys.modules} or importing compiled modules into multiple interpreters within a process (or following a \cfunction{fork()} without an intervening --- 385,389 ---- Python source distribution. ! \note{Removing entries from \code{sys.modules} or importing compiled modules into multiple interpreters within a process (or following a \cfunction{fork()} without an intervening *************** *** 395,399 **** (\cfunction{initspam()} in the example), but will not load the module again if it was loaded from a dynamically loadable object file ! (\file{.so} on \UNIX, \file{.dll} on Windows). A more substantial example module is included in the Python source --- 395,399 ---- (\cfunction{initspam()} in the example), but will not load the module again if it was loaded from a dynamically loadable object file ! (\file{.so} on \UNIX, \file{.dll} on Windows).} A more substantial example module is included in the Python source *************** *** 829,837 **** may be nested. ! \strong{Note:} Prior to Python version 1.5.2, this format specifier only accepted a tuple containing the individual parameters, not an arbitrary sequence. Code which previously caused \exception{TypeError} to be raised here may now proceed without an ! exception. This is not expected to be a problem for existing code. \end{description} --- 829,837 ---- may be nested. ! \note{Prior to Python version 1.5.2, this format specifier only accepted a tuple containing the individual parameters, not an arbitrary sequence. Code which previously caused \exception{TypeError} to be raised here may now proceed without an ! exception. This is not expected to be a problem for existing code.} \end{description} *************** *** 951,957 **** otherwise it returns false and raises an appropriate exception. ! \strong{Note:} Nested tuples cannot be parsed when using keyword arguments! Keyword parameters passed in which are not present in the ! \var{kwlist} will cause \exception{TypeError} to be raised. Here is an example module which uses keywords, based on an example by --- 951,957 ---- otherwise it returns false and raises an appropriate exception. ! \note{Nested tuples cannot be parsed when using keyword arguments! Keyword parameters passed in which are not present in the ! \var{kwlist} will cause \exception{TypeError} to be raised.} Here is an example module which uses keywords, based on an example by From fdrake@users.sourceforge.net Sat Oct 20 05:24:12 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 19 Oct 2001 21:24:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libal.tex,1.13,1.14 libarray.tex,1.30,1.31 libcgihttp.tex,1.5,1.6 libcmpcache.tex,1.5,1.6 libcodecs.tex,1.6,1.7 libcurses.tex,1.34,1.35 libdl.tex,1.3,1.4 libfpformat.tex,1.3,1.4 libgetopt.tex,1.18,1.19 libgl.tex,1.16,1.17 libhttplib.tex,1.25,1.26 libinspect.tex,1.7,1.8 liblocale.tex,1.26,1.27 libmarshal.tex,1.20,1.21 liboperator.tex,1.20,1.21 libpanel.tex,1.11,1.12 libpickle.tex,1.29,1.30 libposix.tex,1.58,1.59 libposixfile.tex,1.23,1.24 libposixpath.tex,1.20,1.21 libpwd.tex,1.12,1.13 libre.tex,1.68,1.69 librexec.tex,1.17,1.18 libselect.tex,1.18,1.19 libsmtplib.tex,1.20,1.21 libsocket.tex,1.56,1.57 libstdtypes.tex,1.71,1.72 libstdwin.tex,1.24,1.25 libstring.tex,1.44,1.45 libsys.tex,1.53,1.54 libtabnanny.tex,1.1,1.2 libtime.tex,1.45,1.46 libunittest.tex,1.6,1.7 liburllib.tex,1.39,1.40 liburllib2.tex,1.4,1.5 libwhrandom.tex,1.14,1.15 libwinsound.tex,1.11,1.12 xmldom.tex,1.14,1.15 xmlsaxhandler.tex,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv30080/lib Modified Files: libal.tex libarray.tex libcgihttp.tex libcmpcache.tex libcodecs.tex libcurses.tex libdl.tex libfpformat.tex libgetopt.tex libgl.tex libhttplib.tex libinspect.tex liblocale.tex libmarshal.tex liboperator.tex libpanel.tex libpickle.tex libposix.tex libposixfile.tex libposixpath.tex libpwd.tex libre.tex librexec.tex libselect.tex libsmtplib.tex libsocket.tex libstdtypes.tex libstdwin.tex libstring.tex libsys.tex libtabnanny.tex libtime.tex libunittest.tex liburllib.tex liburllib2.tex libwhrandom.tex libwinsound.tex xmldom.tex xmlsaxhandler.tex Log Message: Use the \note and \warning macros where appropriate. Index: libal.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libal.tex,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** libal.tex 1999/04/22 21:23:21 1.13 --- libal.tex 2001/10/20 04:24:09 1.14 *************** *** 21,25 **** \refmodule[al-constants]{AL}\refstmodindex{AL}, see below. ! \strong{Warning:} the current version of the audio library may dump core when bad argument values are passed rather than returning an error status. Unfortunately, since the precise circumstances under which --- 21,25 ---- \refmodule[al-constants]{AL}\refstmodindex{AL}, see below. ! \warning{The current version of the audio library may dump core when bad argument values are passed rather than returning an error status. Unfortunately, since the precise circumstances under which *************** *** 27,31 **** interface can provide no protection against this kind of problems. (One example is specifying an excessive queue size --- there is no ! documented upper limit.) The module defines the following functions: --- 27,31 ---- interface can provide no protection against this kind of problems. (One example is specifying an excessive queue size --- there is no ! documented upper limit.)} The module defines the following functions: Index: libarray.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libarray.tex,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** libarray.tex 2001/08/01 16:50:49 1.30 --- libarray.tex 2001/10/20 04:24:09 1.31 *************** *** 78,87 **** length-changing operations are applied to it. ! \strong{Note:} When using array objects from code written in C or \Cpp{} (the only way to effectively make use of this information), it makes more sense to use the buffer interface supported by array objects. This method is maintained for backward compatibility and should be avoided in new code. The buffer interface is documented in ! the \citetitle[../api/newTypes.html]{Python/C API Reference Manual}. \end{methoddesc} --- 78,87 ---- length-changing operations are applied to it. ! \note{When using array objects from code written in C or \Cpp{} (the only way to effectively make use of this information), it makes more sense to use the buffer interface supported by array objects. This method is maintained for backward compatibility and should be avoided in new code. The buffer interface is documented in ! the \citetitle[../api/newTypes.html]{Python/C API Reference Manual}.} \end{methoddesc} Index: libcgihttp.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcgihttp.tex,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** libcgihttp.tex 2000/12/01 15:25:23 1.5 --- libcgihttp.tex 2001/10/20 04:24:09 1.6 *************** *** 16,21 **** run CGI scripts. ! \strong{Note:} This module is \UNIX{} dependent since it creates the ! CGI process using \function{os.fork()} and \function{os.exec()}. The \module{CGIHTTPServer} module defines the following class: --- 16,21 ---- run CGI scripts. ! \note{This module is \UNIX{} dependent since it creates the ! CGI process using \function{os.fork()} and \function{os.exec()}.} The \module{CGIHTTPServer} module defines the following class: Index: libcmpcache.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcmpcache.tex,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** libcmpcache.tex 2001/01/25 17:29:18 1.5 --- libcmpcache.tex 2001/10/20 04:24:09 1.6 *************** *** 14,21 **** difference). ! \strong{Note:} Using the \refmodule{statcache} module to provide \function{stat()} information results in trashing the cache invalidation mechanism: results are not as reliable. To ensure ``current'' results, use \function{cmp.cmp()} instead of the version defined in this module, or use \function{statcache.forget()} to ! invalidate the appropriate entries. --- 14,21 ---- difference). ! \note{Using the \refmodule{statcache} module to provide \function{stat()} information results in trashing the cache invalidation mechanism: results are not as reliable. To ensure ``current'' results, use \function{cmp.cmp()} instead of the version defined in this module, or use \function{statcache.forget()} to ! invalidate the appropriate entries.} Index: libcodecs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcodecs.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** libcodecs.tex 2001/09/19 11:33:31 1.6 --- libcodecs.tex 2001/10/20 04:24:09 1.7 *************** *** 104,111 **** a wrapped version providing transparent encoding/decoding. ! \strong{Note:} The wrapped version will only accept the object format defined by the codecs, i.e.\ Unicode objects for most built-in codecs. Output is also codec-dependent and will usually be Unicode as ! well. \var{encoding} specifies the encoding which is to be used for the --- 104,111 ---- a wrapped version providing transparent encoding/decoding. ! \note{The wrapped version will only accept the object format defined by the codecs, i.e.\ Unicode objects for most built-in codecs. Output is also codec-dependent and will usually be Unicode as ! well.} \var{encoding} specifies the encoding which is to be used for the *************** *** 336,340 **** decoded data. ! Note: Unlike the \method{readlines()} method, this method inherits the line breaking knowledge from the underlying stream's \method{readline()} method -- there is currently no support for line --- 336,340 ---- decoded data. ! Unlike the \method{readlines()} method, this method inherits the line breaking knowledge from the underlying stream's \method{readline()} method -- there is currently no support for line Index: libcurses.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcurses.tex,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** libcurses.tex 2001/07/12 02:09:51 1.34 --- libcurses.tex 2001/10/20 04:24:09 1.35 *************** *** 50,56 **** \end{excdesc} ! \strong{Note:} Whenever \var{x} or \var{y} arguments to a function or a method are optional, they default to the current cursor location. ! Whenever \var{attr} is optional, it defaults to \constant{A_NORMAL}. The module \module{curses} defines the following functions: --- 50,56 ---- \end{excdesc} ! \note{Whenever \var{x} or \var{y} arguments to a function or a method are optional, they default to the current cursor location. ! Whenever \var{attr} is optional, it defaults to \constant{A_NORMAL}.} The module \module{curses} defines the following functions: *************** *** 517,522 **** \begin{funcdesc}{ungetch}{ch} Push \var{ch} so the next \method{getch()} will return it. ! \strong{Note:} only one \var{ch} can be pushed before \method{getch()} ! is called. \end{funcdesc} --- 517,522 ---- \begin{funcdesc}{ungetch}{ch} Push \var{ch} so the next \method{getch()} will return it. ! \note{Only one \var{ch} can be pushed before \method{getch()} ! is called.} \end{funcdesc} *************** *** 543,550 **** \begin{methoddesc}{addch}{\optional{y, x,} ch\optional{, attr}} ! \strong{Note:} A \emph{character} means a C character (an \ASCII{} code), rather then a Python character (a string of length 1). (This note is true whenever the documentation mentions a character.) ! The builtin \function{ord()} is handy for conveying strings to codes. Paint character \var{ch} at \code{(\var{y}, \var{x})} with attributes --- 543,550 ---- \begin{methoddesc}{addch}{\optional{y, x,} ch\optional{, attr}} ! \note{A \emph{character} means a C character (an \ASCII{} code), rather then a Python character (a string of length 1). (This note is true whenever the documentation mentions a character.) ! The builtin \function{ord()} is handy for conveying strings to codes.} Paint character \var{ch} at \code{(\var{y}, \var{x})} with attributes *************** *** 615,621 **** raised. ! \strong{Note:} A \code{0} value for any parameter will cause the default character to be used for that parameter. Keyword parameters ! can \emph{not} be used. The defaults are listed in this table: \begin{tableiii}{l|l|l}{var}{Parameter}{Description}{Default value} --- 615,621 ---- raised. ! \note{A \code{0} value for any parameter will cause the default character to be used for that parameter. Keyword parameters ! can \emph{not} be used. The defaults are listed in this table:} \begin{tableiii}{l|l|l}{var}{Parameter}{Description}{Default value} *************** *** 1183,1188 **** is no graphic available, curses falls back on a crude printable ASCII approximation. ! \strong{Note:} These are available only after \function{initscr()} has ! been called. \begin{longtableii}{l|l}{code}{ACS code}{Meaning} --- 1183,1188 ---- is no graphic available, curses falls back on a crude printable ASCII approximation. ! \note{These are available only after \function{initscr()} has ! been called.} \begin{longtableii}{l|l}{code}{ACS code}{Meaning} Index: libdl.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdl.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** libdl.tex 2000/12/01 15:25:23 1.3 --- libdl.tex 2001/10/20 04:24:09 1.4 *************** *** 11,20 **** the program to call arbitrary functions in such a library. ! \strong{Note:} This module will not work unless ! \begin{verbatim} ! sizeof(int) == sizeof(long) == sizeof(char *) ! \end{verbatim} If this is not the case, \exception{SystemError} will be raised on ! import. The \module{dl} module defines the following function: --- 11,18 ---- the program to call arbitrary functions in such a library. ! \note{This module will not work unless ! \code{sizeof(int) == sizeof(long) == sizeof(char *)} If this is not the case, \exception{SystemError} will be raised on ! import.} The \module{dl} module defines the following function: Index: libfpformat.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfpformat.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** libfpformat.tex 2000/12/01 15:25:23 1.3 --- libfpformat.tex 2001/10/20 04:24:09 1.4 *************** *** 9,14 **** The \module{fpformat} module defines functions for dealing with floating point numbers representations in 100\% pure ! Python. \strong{Note:} This module is unneeded: everything here could ! be done via the \code{\%} string interpolation operator. The \module{fpformat} module defines the following functions and an --- 9,14 ---- The \module{fpformat} module defines functions for dealing with floating point numbers representations in 100\% pure ! Python. \note{This module is unneeded: everything here could ! be done via the \code{\%} string interpolation operator.} The \module{fpformat} module defines the following functions and an Index: libgetopt.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libgetopt.tex,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** libgetopt.tex 2001/04/18 03:18:57 1.18 --- libgetopt.tex 2001/10/20 04:24:09 1.19 *************** *** 26,32 **** \cfunction{getopt()} uses). ! \strong{Note:} Unlike GNU \cfunction{getopt()}, after a non-option argument, all further arguments are considered also non-options. ! This is similar to the way non-GNU \UNIX{} systems work. \var{long_options}, if specified, must be a list of strings with the --- 26,32 ---- \cfunction{getopt()} uses). ! \note{Unlike GNU \cfunction{getopt()}, after a non-option argument, all further arguments are considered also non-options. ! This is similar to the way non-GNU \UNIX{} systems work.} \var{long_options}, if specified, must be a list of strings with the Index: libgl.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libgl.tex,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** libgl.tex 2001/09/06 19:23:03 1.16 --- libgl.tex 2001/10/20 04:24:09 1.17 *************** *** 11,19 **** It is available only on Silicon Graphics machines. ! \strong{Warning:} ! Some illegal calls to the GL library cause the Python interpreter to dump ! core. In particular, the use of most GL calls is unsafe before the first ! window is opened. The module is too large to document here in its entirety, but the --- 11,18 ---- It is available only on Silicon Graphics machines. ! \warning{Some illegal calls to the GL library cause the Python ! interpreter to dump core. In particular, the use of most GL calls is unsafe before the first ! window is opened.} The module is too large to document here in its entirety, but the Index: libhttplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libhttplib.tex,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** libhttplib.tex 2001/09/25 16:32:02 1.25 --- libhttplib.tex 2001/10/20 04:24:09 1.26 *************** *** 10,16 **** HTTP and HTTPS protocols. It is normally not used directly --- the module \refmodule{urllib}\refstmodindex{urllib} uses it to handle URLs ! that use HTTP and HTTPS. \strong{Note:} HTTPS support is only available if the \refmodule{socket} module was compiled with SSL ! support. The module defines one class, \class{HTTP}: --- 10,16 ---- HTTP and HTTPS protocols. It is normally not used directly --- the module \refmodule{urllib}\refstmodindex{urllib} uses it to handle URLs ! that use HTTP and HTTPS. \note{HTTPS support is only available if the \refmodule{socket} module was compiled with SSL ! support.} The module defines one class, \class{HTTP}: Index: libinspect.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libinspect.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** libinspect.tex 2001/10/18 14:26:08 1.7 --- libinspect.tex 2001/10/20 04:24:09 1.8 *************** *** 273,277 **** context to return, which are centered around the current line. ! \strong{Warning:} Keeping references to frame objects, as found in the first element of the frame records these functions return, can cause your program to create reference cycles. Once a reference cycle --- 273,277 ---- context to return, which are centered around the current line. ! \warning{Keeping references to frame objects, as found in the first element of the frame records these functions return, can cause your program to create reference cycles. Once a reference cycle *************** *** 281,285 **** created, it is important to ensure they are explicitly broken to avoid the delayed destruction of objects and increased memory consumption ! which occurs. \begin{funcdesc}{getframeinfo}{frame\optional{, context}} --- 281,285 ---- created, it is important to ensure they are explicitly broken to avoid the delayed destruction of objects and increased memory consumption ! which occurs.} \begin{funcdesc}{getframeinfo}{frame\optional{, context}} Index: liblocale.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liblocale.tex,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** liblocale.tex 2001/09/27 04:16:27 1.26 --- liblocale.tex 2001/10/20 04:24:09 1.27 *************** *** 299,306 **** \begin{datadesc}{DAY_1 ... DAY_7} ! Return name of the n-th day of the week. \strong{Warning:} this follows the US convention of \constant{DAY_1} being Sunday, not the international convention (ISO 8601) that Monday is the first day of ! the week. \end{datadesc} --- 299,306 ---- \begin{datadesc}{DAY_1 ... DAY_7} ! Return name of the n-th day of the week. \warning{This follows the US convention of \constant{DAY_1} being Sunday, not the international convention (ISO 8601) that Monday is the first day of ! the week.} \end{datadesc} *************** *** 328,334 **** Return a regular expression that can be used with the regex function to recognize a positive response to a yes/no question. ! \strong{Warning:} the expression is in the syntax suitable for the \cfunction{regex()} function from the C library, which might differ ! from the syntax used in \refmodule{re}. \end{datadesc} --- 328,334 ---- Return a regular expression that can be used with the regex function to recognize a positive response to a yes/no question. ! \warning{The expression is in the syntax suitable for the \cfunction{regex()} function from the C library, which might differ ! from the syntax used in \refmodule{re}.} \end{datadesc} Index: libmarshal.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libmarshal.tex,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** libmarshal.tex 2001/09/14 20:40:13 1.20 --- libmarshal.tex 2001/10/20 04:24:09 1.21 *************** *** 73,79 **** in binary mode (\code{'rb'} or \code{'r+b'}). ! \strong{Warning:} If an object containing an unsupported type was marshalled with \function{dump()}, \function{load()} will substitute ! \code{None} for the unmarshallable type. \end{funcdesc} --- 73,79 ---- in binary mode (\code{'rb'} or \code{'r+b'}). ! \warning{If an object containing an unsupported type was marshalled with \function{dump()}, \function{load()} will substitute ! \code{None} for the unmarshallable type.} \end{funcdesc} Index: liboperator.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liboperator.tex,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** liboperator.tex 2001/08/10 15:55:09 1.20 --- liboperator.tex 2001/10/20 04:24:09 1.21 *************** *** 221,227 **** The \module{operator} module also defines a few predicates to test the ! type of objects. \strong{Note:} Be careful not to misinterpret the results of these functions; only \function{isCallable()} has any ! measure of reliability with instance objects. For example: \begin{verbatim} --- 221,227 ---- The \module{operator} module also defines a few predicates to test the ! type of objects. \note{Be careful not to misinterpret the results of these functions; only \function{isCallable()} has any ! measure of reliability with instance objects. For example:} \begin{verbatim} *************** *** 246,253 **** Returns true if the object \var{o} supports the mapping interface. This is true for dictionaries and all instance objects. ! \strong{Warning:} There is no reliable way to test if an instance supports the complete mapping protocol since the interface itself is ill-defined. This makes this test less useful than it otherwise might ! be. \end{funcdesc} --- 246,253 ---- Returns true if the object \var{o} supports the mapping interface. This is true for dictionaries and all instance objects. ! \warning{There is no reliable way to test if an instance supports the complete mapping protocol since the interface itself is ill-defined. This makes this test less useful than it otherwise might ! be.} \end{funcdesc} *************** *** 255,262 **** Returns true if the object \var{o} represents a number. This is true for all numeric types implemented in C, and for all instance objects. ! \strong{Warning:} There is no reliable way to test if an instance supports the complete numeric interface since the interface itself is ill-defined. This makes this test less useful than it otherwise might ! be. \end{funcdesc} --- 255,262 ---- Returns true if the object \var{o} represents a number. This is true for all numeric types implemented in C, and for all instance objects. ! \warning{There is no reliable way to test if an instance supports the complete numeric interface since the interface itself is ill-defined. This makes this test less useful than it otherwise might ! be.} \end{funcdesc} *************** *** 264,271 **** Returns true if the object \var{o} supports the sequence protocol. This returns true for all objects which define sequence methods in C, ! and for all instance objects. \strong{Warning:} There is no reliable way to test if an instance supports the complete sequence interface since the interface itself is ill-defined. This makes this test less ! useful than it otherwise might be. \end{funcdesc} --- 264,271 ---- Returns true if the object \var{o} supports the sequence protocol. This returns true for all objects which define sequence methods in C, ! and for all instance objects. \warning{There is no reliable way to test if an instance supports the complete sequence interface since the interface itself is ill-defined. This makes this test less ! useful than it otherwise might be.} \end{funcdesc} Index: libpanel.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libpanel.tex,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** libpanel.tex 2001/07/14 02:50:55 1.11 --- libpanel.tex 2001/10/20 04:24:09 1.12 *************** *** 26,35 **** \end{funcdesc} ! \strong{Warning:} ! the Python interpreter will dump core if you don't create a GL window ! before calling \code{panel.mkpanel()} or ! \code{panel.defpanellist()}. \section{\module{panelparser} --- --- 26,34 ---- \end{funcdesc} ! \warning{The Python interpreter will dump core if you don't create a ! GL window before calling \code{panel.mkpanel()} or ! \code{panel.defpanellist()}.} \section{\module{panelparser} --- *************** *** 70,77 **** \code{pnl.dopanel()}. ! \strong{Warning:} ! the Python interpreter will dump core if you don't create a GL window ! before calling ! \code{pnl.mkpanel()}. The module is too large to document here in its entirety. --- 69,74 ---- \code{pnl.dopanel()}. ! \warning{The Python interpreter will dump core if you don't create a ! GL window before calling \code{pnl.mkpanel()}.} The module is too large to document here in its entirety. Index: libpickle.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libpickle.tex,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** libpickle.tex 2001/09/25 16:29:17 1.29 --- libpickle.tex 2001/10/20 04:24:09 1.30 *************** *** 31,35 **** ! \strong{Note:} The \module{pickle} module is rather slow. A reimplementation of the same algorithm in C, which is up to 1000 times faster, is available as the --- 31,35 ---- ! \note{The \module{pickle} module is rather slow. A reimplementation of the same algorithm in C, which is up to 1000 times faster, is available as the *************** *** 37,41 **** interface except that \class{Pickler} and \class{Unpickler} are factory functions, not classes (so they cannot be used as base classes ! for inheritance). Although the \module{pickle} module can use the built-in module --- 37,41 ---- interface except that \class{Pickler} and \class{Unpickler} are factory functions, not classes (so they cannot be used as base classes ! for inheritance).} Although the \module{pickle} module can use the built-in module *************** *** 111,119 **** When a pickled class instance is unpickled, its \method{__init__()} method ! is normally \emph{not} invoked. \strong{Note:} This is a deviation from previous versions of this module; the change was introduced in ! Python 1.5b2. The reason for the change is that in many cases it is desirable to have a constructor that requires arguments; it is a ! (minor) nuisance to have to provide a \method{__getinitargs__()} method. If it is desirable that the \method{__init__()} method be called on --- 111,119 ---- When a pickled class instance is unpickled, its \method{__init__()} method ! is normally \emph{not} invoked. \note{This is a deviation from previous versions of this module; the change was introduced in ! Python 1.5. The reason for the change is that in many cases it is desirable to have a constructor that requires arguments; it is a ! (minor) nuisance to have to provide a \method{__getinitargs__()} method.} If it is desirable that the \method{__init__()} method be called on Index: libposix.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libposix.tex,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -d -r1.58 -r1.59 *** libposix.tex 2001/06/22 16:01:20 1.58 --- libposix.tex 2001/10/20 04:24:09 1.59 *************** *** 86,94 **** \function{popen()}. ! \strong{Note:} The \refmodule{os} module provides an alternate implementation of \code{environ} which updates the environment on modification. Note also that updating \code{os.environ} will render this dictionary obsolete. Use of the \refmodule{os} for this is ! recommended over direct access to the \module{posix} module. \end{datadesc} --- 86,94 ---- \function{popen()}. ! \note{The \refmodule{os} module provides an alternate implementation of \code{environ} which updates the environment on modification. Note also that updating \code{os.environ} will render this dictionary obsolete. Use of the \refmodule{os} for this is ! recommended over direct access to the \module{posix} module.} \end{datadesc} Index: libposixfile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libposixfile.tex,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** libposixfile.tex 1999/04/21 21:15:35 1.23 --- libposixfile.tex 2001/10/20 04:24:09 1.24 *************** *** 12,19 **** \indexii{\POSIX{}}{file object} ! \strong{Note:} This module will become obsolete in a future release. The locking operation that it provides is done better and more portably by the \function{fcntl.lockf()} call.% ! \withsubitem{(in module fcntl)}{\ttindex{lockf()}} This module implements some additional functionality over the built-in --- 12,19 ---- \indexii{\POSIX{}}{file object} ! \note{This module will become obsolete in a future release. The locking operation that it provides is done better and more portably by the \function{fcntl.lockf()} call.% ! \withsubitem{(in module fcntl)}{\ttindex{lockf()}}} This module implements some additional functionality over the built-in Index: libposixpath.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libposixpath.tex,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** libposixpath.tex 2001/09/28 16:14:18 1.20 --- libposixpath.tex 2001/10/20 04:24:09 1.21 *************** *** 8,14 **** \index{path!operations} ! \strong{Warning:} On Windows, many of these functions do not properly support UNC pathnames. \function{splitunc()} and \function{ismount()} ! do handle them correctly. --- 8,14 ---- \index{path!operations} ! \warning{On Windows, many of these functions do not properly support UNC pathnames. \function{splitunc()} and \function{ismount()} ! do handle them correctly.} Index: libpwd.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libpwd.tex,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** libpwd.tex 2000/04/03 20:13:54 1.12 --- libpwd.tex 2001/10/20 04:24:09 1.13 *************** *** 25,29 **** \exception{KeyError} is raised if the entry asked for cannot be found. ! \strong{Note:} In traditional \UNIX{} the field \code{pw_passwd} usually contains a password encrypted with a DES derived algorithm (see module \refmodule{crypt}\refbimodindex{crypt}). However most modern unices --- 25,29 ---- \exception{KeyError} is raised if the entry asked for cannot be found. ! \note{In traditional \UNIX{} the field \code{pw_passwd} usually contains a password encrypted with a DES derived algorithm (see module \refmodule{crypt}\refbimodindex{crypt}). However most modern unices *************** *** 31,35 **** field \code{pw_passwd} only contains a asterisk (\code{'*'}) or the letter \character{x} where the encrypted password is stored in a file ! \file{/etc/shadow} which is not world readable. It defines the following items: --- 31,35 ---- field \code{pw_passwd} only contains a asterisk (\code{'*'}) or the letter \character{x} where the encrypted password is stored in a file ! \file{/etc/shadow} which is not world readable.} It defines the following items: Index: libre.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libre.tex,v retrieving revision 1.68 retrieving revision 1.69 diff -C2 -d -r1.68 -r1.69 *** libre.tex 2001/10/05 20:06:47 1.68 --- libre.tex 2001/10/20 04:24:09 1.69 *************** *** 483,488 **** match. ! \strong{Note:} If you want to locate a match anywhere in ! \var{string}, use \method{search()} instead. \end{funcdesc} --- 483,488 ---- match. ! \note{If you want to locate a match anywhere in ! \var{string}, use \method{search()} instead.} \end{funcdesc} *************** *** 619,624 **** match. ! \strong{Note:} If you want to locate a match anywhere in ! \var{string}, use \method{search()} instead. The optional second parameter \var{pos} gives an index in the string --- 619,624 ---- match. ! \note{If you want to locate a match anywhere in ! \var{string}, use \method{search()} instead.} The optional second parameter \var{pos} gives an index in the string Index: librexec.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/librexec.tex,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** librexec.tex 2001/07/14 02:50:55 1.17 --- librexec.tex 2001/10/20 04:24:09 1.18 *************** *** 16,23 **** can subclass \class{RExec} to add or remove capabilities as desired. ! \emph{Note:} The \class{RExec} class can prevent code from performing unsafe operations like reading or writing disk files, or using TCP/IP sockets. However, it does not protect against code using extremely ! large amounts of memory or processor time. \begin{classdesc}{RExec}{\optional{hooks\optional{, verbose}}} --- 16,23 ---- can subclass \class{RExec} to add or remove capabilities as desired. ! \note{The \class{RExec} class can prevent code from performing unsafe operations like reading or writing disk files, or using TCP/IP sockets. However, it does not protect against code using extremely ! large amounts of memory or processor time.} \begin{classdesc}{RExec}{\optional{hooks\optional{, verbose}}} Index: libselect.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libselect.tex,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** libselect.tex 2001/07/11 18:48:39 1.18 --- libselect.tex 2001/10/20 04:24:09 1.19 *************** *** 59,66 **** an appropriate \method{fileno()} method (that really returns a file descriptor, not just a random integer). ! \strong{Note:}\index{WinSock} File objects on Windows are not ! acceptable, but sockets are. On Windows, the underlying ! \cfunction{select()} function is provided by the WinSock library, and ! does not handle file desciptors that don't originate from WinSock. \end{funcdesc} --- 59,66 ---- an appropriate \method{fileno()} method (that really returns a file descriptor, not just a random integer). ! \note{File objects on Windows are not acceptable, but sockets ! are.\index{WinSock} On Windows, the underlying \cfunction{select()} ! function is provided by the WinSock library, and does not handle file ! desciptors that don't originate from WinSock.} \end{funcdesc} Index: libsmtplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsmtplib.tex,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** libsmtplib.tex 2001/09/14 17:48:41 1.20 --- libsmtplib.tex 2001/10/20 04:24:09 1.21 *************** *** 100,109 **** Connect to a host on a given port. The defaults are to connect to the local host at the standard SMTP port (25). - If the hostname ends with a colon (\character{:}) followed by a number, that suffix will be stripped off and the number interpreted as the port number to use. ! ! Note: This method is automatically invoked by the constructor if a host is specified during instantiation. \end{methoddesc} --- 100,107 ---- Connect to a host on a given port. The defaults are to connect to the local host at the standard SMTP port (25). If the hostname ends with a colon (\character{:}) followed by a number, that suffix will be stripped off and the number interpreted as the port number to use. ! This method is automatically invoked by the constructor if a host is specified during instantiation. \end{methoddesc} *************** *** 158,162 **** an SMTP error code of 400 or greater and an error string. ! Note: many sites disable SMTP \samp{VRFY} in order to foil spammers. \end{methoddesc} --- 156,160 ---- an SMTP error code of 400 or greater and an error string. ! \note{Many sites disable SMTP \samp{VRFY} in order to foil spammers.} \end{methoddesc} *************** *** 200,206 **** \method{data} to send the message.) ! \strong{Note:} The \var{from_addr} and \var{to_addrs} parameters are used to construct the message envelope used by the transport agents. ! The \class{SMTP} does not modify the message headers in any way. If there has been no previous \samp{EHLO} or \samp{HELO} command this --- 198,204 ---- \method{data} to send the message.) ! \note{The \var{from_addr} and \var{to_addrs} parameters are used to construct the message envelope used by the transport agents. ! The \class{SMTP} does not modify the message headers in any way.} If there has been no previous \samp{EHLO} or \samp{HELO} command this Index: libsocket.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsocket.tex,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -d -r1.56 -r1.57 *** libsocket.tex 2001/10/19 17:22:29 1.56 --- libsocket.tex 2001/10/20 04:24:09 1.57 *************** *** 272,276 **** success, a new \class{SSLObject} is returned. ! \strong{Warning:} This does not do any certificate verification! \end{funcdesc} --- 272,276 ---- success, a new \class{SSLObject} is returned. ! \warning{This does not do any certificate verification!} \end{funcdesc} *************** *** 374,381 **** Bind the socket to \var{address}. The socket must not already be bound. (The format of \var{address} depends on the address family --- see ! 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} --- 374,381 ---- Bind the socket to \var{address}. The socket must not already be bound. (The format of \var{address} depends on the address family --- see ! above.) \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} *************** *** 389,396 **** Connect to a remote socket at \var{address}. (The format of \var{address} depends on the address family --- see ! 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} --- 389,396 ---- Connect to a remote socket at \var{address}. (The format of \var{address} depends on the address family --- see ! above.) \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} *************** *** 402,409 **** operation succeeded, otherwise the value of the \cdata{errno} variable. This is useful, e.g., for asynchronous connects. ! \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} --- 402,409 ---- operation succeeded, otherwise the value of the \cdata{errno} variable. This is useful, e.g., for asynchronous connects. ! \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: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.71 retrieving revision 1.72 diff -C2 -d -r1.71 -r1.72 *** libstdtypes.tex 2001/09/29 01:08:19 1.71 --- libstdtypes.tex 2001/10/20 04:24:09 1.72 *************** *** 1216,1221 **** \begin{methoddesc}[file]{isatty}{} Return true if the file is connected to a tty(-like) device, else ! false. \strong{Note:} If a file-like object is not associated ! with a real file, this method should \emph{not} be implemented. \end{methoddesc} --- 1216,1221 ---- \begin{methoddesc}[file]{isatty}{} Return true if the file is connected to a tty(-like) device, else ! false. \note{If a file-like object is not associated ! with a real file, this method should \emph{not} be implemented.} \end{methoddesc} *************** *** 1228,1234 **** interfaces that use file descriptors, such as the \refmodule{fcntl}\refbimodindex{fcntl} module or ! \function{os.read()} and friends. \strong{Note:} File-like objects which do not have a real file descriptor should \emph{not} provide ! this method! \end{methoddesc} --- 1228,1234 ---- interfaces that use file descriptors, such as the \refmodule{fcntl}\refbimodindex{fcntl} module or ! \function{os.read()} and friends. \note{File-like objects which do not have a real file descriptor should \emph{not} provide ! this method!} \end{methoddesc} *************** *** 1259,1265 **** newline) and an incomplete line may be returned. An empty string is returned when \EOF{} is hit ! immediately. Note: Unlike \code{stdio}'s \cfunction{fgets()}, the returned string contains null characters (\code{'\e 0'}) if they ! occurred in the input. \end{methoddesc} --- 1259,1265 ---- newline) and an incomplete line may be returned. An empty string is returned when \EOF{} is hit ! immediately. \note{Unlike \code{stdio}'s \cfunction{fgets()}, the returned string contains null characters (\code{'\e 0'}) if they ! occurred in the input.} \end{methoddesc} *************** *** 1308,1312 **** \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. --- 1308,1312 ---- \begin{methoddesc}[file]{write}{str} ! Write a string to the file. There is no return value. Due to buffering, the string may not actually show up in the file until the \method{flush()} or \method{close()} method is called. *************** *** 1360,1366 **** implemented in C will have to provide a writable \member{softspace} attribute. ! \strong{Note:} This attribute is not used to control the \keyword{print} statement, but to allow the implementation of ! \keyword{print} to keep track of its internal state. \end{memberdesc} --- 1360,1366 ---- implemented in C will have to provide a writable \member{softspace} attribute. ! \note{This attribute is not used to control the \keyword{print} statement, but to allow the implementation of ! \keyword{print} to keep track of its internal state.} \end{memberdesc} Index: libstdwin.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdwin.tex,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** libstdwin.tex 2001/07/14 02:50:55 1.24 --- libstdwin.tex 2001/10/20 04:24:09 1.25 *************** *** 5,9 **** on the Macintosh. See CWI report CS-R8817. ! \strong{Warning:} Using STDWIN is not recommended for new applications. It has never been ported to Microsoft Windows or Windows NT, and for X11 or the Macintosh it lacks important --- 5,9 ---- on the Macintosh. See CWI report CS-R8817. ! \warning{Using STDWIN is not recommended for new applications. It has never been ported to Microsoft Windows or Windows NT, and for X11 or the Macintosh it lacks important *************** *** 13,17 **** \UNIX{} under X11, native Xt with Motif or Athena widgets for \UNIX{} under X11, Win32 for Windows and Windows NT, and a collection of ! native toolkit interfaces for the Macintosh. --- 13,17 ---- \UNIX{} under X11, native Xt with Motif or Athena widgets for \UNIX{} under X11, Win32 for Windows and Windows NT, and a collection of ! native toolkit interfaces for the Macintosh.} *************** *** 176,181 **** Note: normally, menus are created locally; see the window method \method{menucreate()} below. ! \strong{Warning:} the menu only appears in a window as long as the object ! returned by this call exists. \end{funcdesc} --- 176,181 ---- Note: normally, menus are created locally; see the window method \method{menucreate()} below. ! \warning{The menu only appears in a window as long as the object ! returned by this call exists.} \end{funcdesc} *************** *** 338,343 **** only in this window). Methods of menu objects are described below. ! \strong{Warning:} the menu only appears as long as the object ! returned by this call exists. \end{methoddesc} --- 338,343 ---- only in this window). Methods of menu objects are described below. ! \warning{The menu only appears as long as the object ! returned by this call exists.} \end{methoddesc} Index: libstring.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstring.tex,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** libstring.tex 2001/07/20 18:38:26 1.44 --- libstring.tex 2001/10/20 04:24:09 1.45 *************** *** 101,109 **** \function{float()}\bifuncindex{float} when passed a string. ! \strong{Note:} When passing in a string, values for NaN\index{NaN} and Infinity\index{Infinity} may be returned, depending on the underlying C library. The specific set of strings accepted which cause these values to be returned depends entirely on the C library ! and is known to vary. \end{funcdesc} --- 101,109 ---- \function{float()}\bifuncindex{float} when passed a string. ! \note{When passing in a string, values for NaN\index{NaN} and Infinity\index{Infinity} may be returned, depending on the underlying C library. The specific set of strings accepted which cause these values to be returned depends entirely on the C library ! and is known to vary.} \end{funcdesc} *************** *** 195,202 **** in \var{to}; \var{from} and \var{to} must have the same length. ! \strong{Warning:} don't use strings derived from \constant{lowercase} and \constant{uppercase} as arguments; in some locales, these don't have the same length. For case conversions, always use ! \function{lower()} and \function{upper()}. \end{funcdesc} --- 195,202 ---- in \var{to}; \var{from} and \var{to} must have the same length. ! \warning{Don't use strings derived from \constant{lowercase} and \constant{uppercase} as arguments; in some locales, these don't have the same length. For case conversions, always use ! \function{lower()} and \function{upper()}.} \end{funcdesc} Index: libsys.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsys.tex,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -d -r1.53 -r1.54 *** libsys.tex 2001/10/16 14:54:22 1.53 --- libsys.tex 2001/10/20 04:24:09 1.54 *************** *** 100,104 **** originally occurred. \obindex{traceback} ! \strong{Warning:} assigning the \var{traceback} return value to a local variable in a function that is handling an exception will cause a circular reference. This will prevent anything referenced --- 100,104 ---- originally occurred. \obindex{traceback} ! \warning{Assigning the \var{traceback} return value to a local variable in a function that is handling an exception will cause a circular reference. This will prevent anything referenced *************** *** 110,114 **** to delete it after use (best done with a \keyword{try} ... \keyword{finally} statement) or to call \function{exc_info()} in ! a function that does not itself handle an exception. \end{funcdesc} --- 110,114 ---- to delete it after use (best done with a \keyword{try} ... \keyword{finally} statement) or to call \function{exc_info()} in ! a function that does not itself handle an exception.} \end{funcdesc} *************** *** 170,176 **** function may be installed in this way; to allow multiple functions which will be called at termination, use the \refmodule{atexit} ! module. Note: the exit function is not called when the program is killed by a signal, when a Python fatal internal error is detected, ! or when \code{os._exit()} is called. \end{datadesc} --- 170,176 ---- function may be installed in this way; to allow multiple functions which will be called at termination, use the \refmodule{atexit} ! module. \note{The exit function is not called when the program is killed by a signal, when a Python fatal internal error is detected, ! or when \code{os._exit()} is called.} \end{datadesc} Index: libtabnanny.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtabnanny.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** libtabnanny.tex 2000/02/23 15:44:08 1.1 --- libtabnanny.tex 2001/10/20 04:24:09 1.2 *************** *** 15,20 **** \function{check()} described below. ! \strong{Warning:} The API provided by this module is likely to change ! in future releases; such changes may not be backward compatible. \begin{funcdesc}{check}{file_or_dir} --- 15,20 ---- \function{check()} described below. ! \warning{The API provided by this module is likely to change ! in future releases; such changes may not be backward compatible.} \begin{funcdesc}{check}{file_or_dir} Index: libtime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtime.tex,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** libtime.tex 2001/08/22 12:44:27 1.45 --- libtime.tex 2001/10/20 04:24:09 1.46 *************** *** 121,126 **** or \function{localtime()} to a 24-character string of the following form: \code{'Sun Jun 20 23:21:05 1993'}. If \var{tuple} is not provided, the ! current time as returned by \function{localtime()} is used. Note: unlike ! the C function of the same name, there is no trailing newline. \versionchanged[Allowed \var{tuple} to be omitted]{2.1} \end{funcdesc} --- 121,127 ---- or \function{localtime()} to a 24-character string of the following form: \code{'Sun Jun 20 23:21:05 1993'}. If \var{tuple} is not provided, the ! current time as returned by \function{localtime()} is used. ! \note{Unlike the C function of the same name, there is no trailing ! newline.} \versionchanged[Allowed \var{tuple} to be omitted]{2.1} \end{funcdesc} *************** *** 277,284 **** does not provide sufficient information to constrain the result. ! \strong{Note:} This function relies entirely on the underlying platform's C library for the date parsing, and some of these libraries are buggy. There's nothing to be done about this short of a new, ! portable implementation of \cfunction{strptime()}. Availability: Most modern \UNIX{} systems. --- 278,285 ---- does not provide sufficient information to constrain the result. ! \note{This function relies entirely on the underlying platform's C library for the date parsing, and some of these libraries are buggy. There's nothing to be done about this short of a new, ! portable implementation of \cfunction{strptime()}.} Availability: Most modern \UNIX{} systems. Index: libunittest.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libunittest.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** libunittest.tex 2001/09/06 15:51:56 1.6 --- libunittest.tex 2001/10/20 04:24:09 1.7 *************** *** 346,352 **** \end{verbatim} ! \strong{Note:} PyUnit supports the use of \exception{AssertionError} as an indicator of test failure, but does not recommend it. Future ! versions may treat \exception{AssertionError} differently. --- 346,352 ---- \end{verbatim} ! \note{PyUnit supports the use of \exception{AssertionError} as an indicator of test failure, but does not recommend it. Future ! versions may treat \exception{AssertionError} differently.} *************** *** 709,718 **** method defined for the class. ! \strong{Warning:} While using a hierarchy of \class{Testcase}-derived classes can be convenient in sharing fixtures and helper functions, defining test methods on base classes that are not intended to be instantiated directly does not play well with this method. Doing so, however, can be useful when the ! fixtures are different and defined in subclasses. \end{methoddesc} --- 709,718 ---- method defined for the class. ! \warning{While using a hierarchy of \class{Testcase}-derived classes can be convenient in sharing fixtures and helper functions, defining test methods on base classes that are not intended to be instantiated directly does not play well with this method. Doing so, however, can be useful when the ! fixtures are different and defined in subclasses.} \end{methoddesc} Index: liburllib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liburllib.tex,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** liburllib.tex 2001/08/23 13:38:15 1.39 --- liburllib.tex 2001/10/20 04:24:09 1.40 *************** *** 214,223 **** \class{URLopener}. ! \strong{Note:} When performing basic authentication, a \class{FancyURLopener} instance calls its \method{prompt_user_passwd()} method. The default implementation asks the users for the required information on the controlling terminal. A subclass may override this method to support more appropriate behavior ! if needed. \end{classdesc} --- 214,223 ---- \class{URLopener}. ! \note{When performing basic authentication, a \class{FancyURLopener} instance calls its \method{prompt_user_passwd()} method. The default implementation asks the users for the required information on the controlling terminal. A subclass may override this method to support more appropriate behavior ! if needed.} \end{classdesc} Index: liburllib2.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liburllib2.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** liburllib2.tex 2001/07/05 21:14:03 1.4 --- liburllib2.tex 2001/10/20 04:24:09 1.5 *************** *** 392,397 **** \subsection{HTTPRedirectHandler Objects \label{http-redirect-handler}} ! \strong{Note:} 303 redirection is not supported by this version of ! \module{urllib2}. \begin{methoddesc}[HTTPRedirectHandler]{http_error_301}{req, --- 392,397 ---- \subsection{HTTPRedirectHandler Objects \label{http-redirect-handler}} ! \note{303 redirection is not supported by this version of ! \module{urllib2}.} \begin{methoddesc}[HTTPRedirectHandler]{http_error_301}{req, Index: libwhrandom.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libwhrandom.tex,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** libwhrandom.tex 2001/02/03 01:12:44 1.14 --- libwhrandom.tex 2001/10/20 04:24:09 1.15 *************** *** 7,14 **** \deprecated{2.1}{Use \refmodule{random} instead.} ! \strong{Note:} This module was an implementation detail of the \refmodule{random} module in releases of Python prior to 2.1. It is no longer used. Please do not use this module directly; use ! \refmodule{random} instead. This module implements a Wichmann-Hill pseudo-random number generator --- 7,14 ---- \deprecated{2.1}{Use \refmodule{random} instead.} ! \note{This module was an implementation detail of the \refmodule{random} module in releases of Python prior to 2.1. It is no longer used. Please do not use this module directly; use ! \refmodule{random} instead.} This module implements a Wichmann-Hill pseudo-random number generator Index: libwinsound.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libwinsound.tex,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** libwinsound.tex 2001/02/23 19:10:41 1.11 --- libwinsound.tex 2001/10/20 04:24:09 1.12 *************** *** 22,29 **** sound should last. If the system is not able to beep the speaker, \exception{RuntimeError} is raised. ! \strong{Note:} Under Windows 95 and 98, the Windows \cfunction{Beep()} function exists but is useless (it ignores its arguments). In that case Python simulates it via direct port manipulation (added in version ! 2.1). It's unknown whether that will work on all systems. \versionadded{1.6} \end{funcdesc} --- 22,29 ---- sound should last. If the system is not able to beep the speaker, \exception{RuntimeError} is raised. ! \note{Under Windows 95 and 98, the Windows \cfunction{Beep()} function exists but is useless (it ignores its arguments). In that case Python simulates it via direct port manipulation (added in version ! 2.1). It's unknown whether that will work on all systems.} \versionadded{1.6} \end{funcdesc} *************** *** 86,92 **** image of a WAV file, as a string. ! \strong{Note:} This module does not support playing from a memory image asynchronously, so a combination of this flag and ! \constant{SND_ASYNC} will raise \exception{RuntimeError}. \end{datadesc} --- 86,92 ---- image of a WAV file, as a string. ! \note{This module does not support playing from a memory image asynchronously, so a combination of this flag and ! \constant{SND_ASYNC} will raise \exception{RuntimeError}.} \end{datadesc} Index: xmldom.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/xmldom.tex,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** xmldom.tex 2001/06/23 16:23:47 1.14 --- xmldom.tex 2001/10/20 04:24:09 1.15 *************** *** 275,283 **** same node). ! \strong{Note:} This is based on a proposed DOM Level 3 API which is still in the ``working draft'' stage, but this particular interface appears uncontroversial. Changes from the W3C will not necessarily affect this method in the Python DOM interface (though any new W3C ! API for this would also be supported). \end{methoddesc} --- 275,283 ---- same node). ! \note{This is based on a proposed DOM Level 3 API which is still in the ``working draft'' stage, but this particular interface appears uncontroversial. Changes from the W3C will not necessarily affect this method in the Python DOM interface (though any new W3C ! API for this would also be supported).} \end{methoddesc} *************** *** 620,629 **** \end{memberdesc} ! \strong{Note:} The use of a \class{CDATASection} node does not indicate that the node represents a complete CDATA marked section, only that the content of the node was part of a CDATA section. A single CDATA section may be represented by more than one node in the document tree. There is no way to determine whether two adjacent ! \class{CDATASection} nodes represent different CDATA marked sections. --- 620,629 ---- \end{memberdesc} ! \note{The use of a \class{CDATASection} node does not indicate that the node represents a complete CDATA marked section, only that the content of the node was part of a CDATA section. A single CDATA section may be represented by more than one node in the document tree. There is no way to determine whether two adjacent ! \class{CDATASection} nodes represent different CDATA marked sections.} Index: xmlsaxhandler.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/xmlsaxhandler.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** xmlsaxhandler.tex 2000/12/19 04:07:54 1.4 --- xmlsaxhandler.tex 2001/10/20 04:24:09 1.5 *************** *** 264,268 **** \code{expat} reader module produces always Unicode strings. ! \strong{Note:} The earlier SAX 1 interface provided by the Python XML Special Interest Group used a more Java-like interface for this method. Since most parsers used from Python did not take advantage --- 264,268 ---- \code{expat} reader module produces always Unicode strings. ! \note{The earlier SAX 1 interface provided by the Python XML Special Interest Group used a more Java-like interface for this method. Since most parsers used from Python did not take advantage *************** *** 270,274 **** it. To convert old code to the new interface, use \var{content} instead of slicing content with the old \var{offset} and ! \var{length} parameters. \end{methoddesc} --- 270,274 ---- it. To convert old code to the new interface, use \var{content} instead of slicing content with the old \var{offset} and ! \var{length} parameters.} \end{methoddesc} From gvanrossum@users.sourceforge.net Sat Oct 20 15:27:58 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 20 Oct 2001 07:27:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Parser parsetok.c,2.27,2.28 Message-ID: Update of /cvsroot/python/python/dist/src/Parser In directory usw-pr-cvs1:/tmp/cvs-serv5547 Modified Files: parsetok.c Log Message: Patch from SF bug #472956: UMR when there is a syntax error (Neal Norwitz) perrdetail.token is unitialized when there is a syntax error in a file. Index: parsetok.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/parsetok.c,v retrieving revision 2.27 retrieving revision 2.28 diff -C2 -d -r2.27 -r2.28 *** parsetok.c 2001/07/17 16:53:11 2.27 --- parsetok.c 2001/10/20 14:27:56 2.28 *************** *** 15,18 **** --- 15,19 ---- /* Forward */ static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int); + static void initerr(perrdetail *err_ret); /* Parse input coming from a string. Return error code, print some errors. */ *************** *** 29,39 **** struct tok_state *tok; ! err_ret->error = E_OK; ! err_ret->filename = NULL; ! err_ret->lineno = 0; ! err_ret->offset = 0; ! err_ret->text = NULL; ! err_ret->token = -1; ! err_ret->expected = -1; if ((tok = PyTokenizer_FromString(s)) == NULL) { --- 30,34 ---- struct tok_state *tok; ! initerr(err_ret); if ((tok = PyTokenizer_FromString(s)) == NULL) { *************** *** 69,77 **** struct tok_state *tok; ! err_ret->error = E_OK; ! err_ret->filename = filename; ! err_ret->lineno = 0; ! err_ret->offset = 0; ! err_ret->text = NULL; if ((tok = PyTokenizer_FromFile(fp, ps1, ps2)) == NULL) { --- 64,68 ---- struct tok_state *tok; ! initerr(err_ret); if ((tok = PyTokenizer_FromFile(fp, ps1, ps2)) == NULL) { *************** *** 185,187 **** --- 176,190 ---- return n; + } + + static void + initerr(perrdetail *err_ret) + { + err_ret->error = E_OK; + err_ret->filename = NULL; + err_ret->lineno = 0; + err_ret->offset = 0; + err_ret->text = NULL; + err_ret->token = -1; + err_ret->expected = -1; } From gvanrossum@users.sourceforge.net Sat Oct 20 15:21:47 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 20 Oct 2001 07:21:47 -0700 Subject: [Python-checkins] CVS: python/dist/src Makefile.pre.in,1.64,1.65 configure,1.266,1.267 configure.in,1.274,1.275 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv4398 Modified Files: Makefile.pre.in configure configure.in Log Message: Patch from SF bug #473150: configure weaknesses on HP-UX (Michael Piotrowski) 1. configure doesn't handle HP-UX release numbers (e.g., B.11.00), resulting in MACHDEP = "hpuxB". 2. After checking for wchar.h, configure doesn't include it when checking the size of wchar_t. (Python 2.2b1 on HP-UX 11.00) Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.64 retrieving revision 1.65 diff -C2 -d -r1.64 -r1.65 *** Makefile.pre.in 2001/10/18 20:34:24 1.64 --- Makefile.pre.in 2001/10/20 14:21:44 1.65 *************** *** 301,306 **** sharedmods: $(PYTHON) case $$MAKEFLAGS in \ ! *-s*) CC='$(CC)' LDSHARED='$(LDSHARED)' ./$(PYTHON) -E $(srcdir)/setup.py -q build;; \ ! *) CC='$(CC)' LDSHARED='$(LDSHARED)' ./$(PYTHON) -E $(srcdir)/setup.py build;; \ esac --- 301,306 ---- sharedmods: $(PYTHON) case $$MAKEFLAGS in \ ! *-s*) CC='$(CC)' LDSHARED='$(LDSHARED)' OPT='$(OPT)' ./$(PYTHON) -E $(srcdir)/setup.py -q build;; \ ! *) CC='$(CC)' LDSHARED='$(LDSHARED)' OPT='$(OPT)' ./$(PYTHON) -E $(srcdir)/setup.py build;; \ esac Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.266 retrieving revision 1.267 diff -C2 -d -r1.266 -r1.267 *** configure 2001/10/19 01:31:59 1.266 --- configure 2001/10/20 14:21:44 1.267 *************** *** 637,641 **** tr -d '/ ' | tr '[A-Z]' '[a-z]'` ac_md_release=`echo $ac_sys_release | ! tr -d '/ ' | sed 's/\..*//'` MACHDEP="$ac_md_system$ac_md_release" --- 637,641 ---- tr -d '/ ' | tr '[A-Z]' '[a-z]'` ac_md_release=`echo $ac_sys_release | ! tr -d '/ ' | sed 's/^[A-Z]\.//' | sed 's/\..*//'` MACHDEP="$ac_md_system$ac_md_release" Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.274 retrieving revision 1.275 diff -C2 -d -r1.274 -r1.275 *** configure.in 2001/10/19 01:31:59 1.274 --- configure.in 2001/10/20 14:21:44 1.275 *************** *** 64,68 **** tr -d '[/ ]' | tr '[[A-Z]]' '[[a-z]]'` ac_md_release=`echo $ac_sys_release | ! tr -d '[/ ]' | sed 's/\..*//'` MACHDEP="$ac_md_system$ac_md_release" --- 64,68 ---- tr -d '[/ ]' | tr '[[A-Z]]' '[[a-z]]'` ac_md_release=`echo $ac_sys_release | ! tr -d '[/ ]' | sed 's/^[[A-Z]]\.//' | sed 's/\..*//'` MACHDEP="$ac_md_system$ac_md_release" *************** *** 1835,1839 **** if test "$wchar_h" = yes then ! AC_CHECK_SIZEOF(wchar_t, 4) fi --- 1835,1839 ---- if test "$wchar_h" = yes then ! AC_CHECK_SIZEOF(wchar_t, 4, [#include ]) fi From gvanrossum@users.sourceforge.net Sat Oct 20 15:21:47 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 20 Oct 2001 07:21:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.128,1.129 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv4398/Misc Modified Files: ACKS Log Message: Patch from SF bug #473150: configure weaknesses on HP-UX (Michael Piotrowski) 1. configure doesn't handle HP-UX release numbers (e.g., B.11.00), resulting in MACHDEP = "hpuxB". 2. After checking for wchar.h, configure doesn't include it when checking the size of wchar_t. (Python 2.2b1 on HP-UX 11.00) Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.128 retrieving revision 1.129 diff -C2 -d -r1.128 -r1.129 *** ACKS 2001/10/19 01:51:11 1.128 --- ACKS 2001/10/20 14:21:45 1.129 *************** *** 327,330 **** --- 327,331 ---- Dan Pierson François Pinard + Michael Piotrowski John Popplewell Amrit Prem From akuchling@users.sourceforge.net Sat Oct 20 17:05:54 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Sat, 20 Oct 2001 09:05:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _cursesmodule.c,2.56,2.57 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv22149 Modified Files: _cursesmodule.c Log Message: Add two forgotten 'break' statements Allow passing strings to the .border() method Correct some error messages ("1 or 4" -> "1 to 4") Bump version number Tweak code formatting Update my e-mail address Index: _cursesmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_cursesmodule.c,v retrieving revision 2.56 retrieving revision 2.57 diff -C2 -d -r2.56 -r2.57 *** _cursesmodule.c 2001/10/13 09:00:42 2.56 --- _cursesmodule.c 2001/10/20 16:05:52 2.57 *************** *** 9,13 **** * Copyright 1996,1997 by Oliver Andrich, Koblenz, Germany. * ! * Tidied for Python 1.6, and currently maintained by AMK (amk1@bigfoot.com) * * Permission is hereby granted, free of charge, to any person obtaining --- 9,14 ---- * Copyright 1996,1997 by Oliver Andrich, Koblenz, Germany. * ! * Tidied for Python 1.6, and currently maintained by ! * . * * Permission is hereby granted, free of charge, to any person obtaining *************** *** 96,100 **** /* Release Number */ ! char *PyCursesVersion = "2.1"; /* Includes */ --- 97,101 ---- /* Release Number */ ! char *PyCursesVersion = "2.2"; /* Includes */ *************** *** 389,393 **** break; default: ! PyErr_SetString(PyExc_TypeError, "addch requires 1 or 4 arguments"); return NULL; } --- 390,394 ---- break; default: ! PyErr_SetString(PyExc_TypeError, "addch requires 1 to 4 arguments"); return NULL; } *************** *** 561,570 **** PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args) { ! chtype ls, rs, ts, bs, tl, tr, bl, br; ! ls = rs = ts = bs = tl = tr = bl = br = 0; ! if (!PyArg_Parse(args,"|llllllll;ls,rs,ts,bs,tl,tr,bl,br", ! &ls, &rs, &ts, &bs, &tl, &tr, &bl, &br)) return NULL; ! wborder(self->win, ls, rs, ts, bs, tl, tr, bl, br); Py_INCREF(Py_None); return Py_None; --- 562,591 ---- PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args) { ! PyObject *temp[8]; ! chtype ch[8]; ! int i; ! ! /* Clear the array of parameters */ ! for(i=0; i<8; i++) { ! temp[i] = NULL; ! ch[i] = 0; ! } ! ! if (!PyArg_ParseTuple(args,"|OOOOOOOO;ls,rs,ts,bs,tl,tr,bl,br", ! &temp[0], &temp[1], &temp[2], &temp[3], ! &temp[4], &temp[5], &temp[6], &temp[7])) return NULL; ! ! for(i=0; i<8; i++) { ! if (temp[i] != NULL && !PyCurses_ConvertToChtype(temp[i], &ch[i])) { ! PyErr_Format(PyExc_TypeError, ! "argument %i must be a ch or an int", i+1); ! return NULL; ! } ! } ! ! wborder(self->win, ! ch[0], ch[1], ch[2], ch[3], ! ch[4], ch[5], ch[6], ch[7]); Py_INCREF(Py_None); return Py_None; *************** *** 835,840 **** return NULL; code = wmove(self->win, y, x); default: ! PyErr_SetString(PyExc_TypeError, "hline requires 2 or 5 arguments"); return NULL; } --- 856,862 ---- return NULL; code = wmove(self->win, y, x); + break; default: ! PyErr_SetString(PyExc_TypeError, "hline requires 2 to 5 arguments"); return NULL; } *************** *** 1361,1366 **** return NULL; code = wmove(self->win, y, x); default: ! PyErr_SetString(PyExc_TypeError, "vline requires 2 or 5 arguments"); return NULL; } --- 1383,1389 ---- return NULL; code = wmove(self->win, y, x); + break; default: ! PyErr_SetString(PyExc_TypeError, "vline requires 2 to 5 arguments"); return NULL; } *************** *** 1432,1437 **** /* Backward compatibility alias -- remove in Python 2.1 */ {"nooutrefresh", (PyCFunction)PyCursesWindow_NoOutRefresh}, ! {"overlay", (PyCFunction)PyCursesWindow_Overlay, METH_VARARGS}, ! {"overwrite", (PyCFunction)PyCursesWindow_Overwrite, METH_VARARGS}, {"putwin", (PyCFunction)PyCursesWindow_PutWin}, {"redrawln", (PyCFunction)PyCursesWindow_RedrawLine}, --- 1455,1461 ---- /* Backward compatibility alias -- remove in Python 2.1 */ {"nooutrefresh", (PyCFunction)PyCursesWindow_NoOutRefresh}, ! {"overlay", (PyCFunction)PyCursesWindow_Overlay, METH_VARARGS}, ! {"overwrite", (PyCFunction)PyCursesWindow_Overwrite, ! METH_VARARGS}, {"putwin", (PyCFunction)PyCursesWindow_PutWin}, {"redrawln", (PyCFunction)PyCursesWindow_RedrawLine}, *************** *** 1456,1460 **** {"untouchwin", (PyCFunction)PyCursesWindow_untouchwin}, {"vline", (PyCFunction)PyCursesWindow_Vline}, ! {NULL, NULL} /* sentinel */ }; --- 1480,1484 ---- {"untouchwin", (PyCFunction)PyCursesWindow_untouchwin}, {"vline", (PyCFunction)PyCursesWindow_Vline}, ! {NULL, NULL} /* sentinel */ }; *************** *** 2445,2449 **** {"savetty", (PyCFunction)PyCurses_savetty}, {"setsyx", (PyCFunction)PyCurses_setsyx}, ! {"setupterm", (PyCFunction)PyCurses_setupterm, METH_VARARGS|METH_KEYWORDS}, {"start_color", (PyCFunction)PyCurses_Start_Color}, {"termattrs", (PyCFunction)PyCurses_termattrs}, --- 2469,2474 ---- {"savetty", (PyCFunction)PyCurses_savetty}, {"setsyx", (PyCFunction)PyCurses_setsyx}, ! {"setupterm", (PyCFunction)PyCurses_setupterm, ! METH_VARARGS|METH_KEYWORDS}, {"start_color", (PyCFunction)PyCurses_Start_Color}, {"termattrs", (PyCFunction)PyCurses_termattrs}, *************** *** 2457,2461 **** {"ungetch", (PyCFunction)PyCurses_UngetCh}, {"use_env", (PyCFunction)PyCurses_Use_Env}, ! {NULL, NULL} /* sentinel */ }; --- 2482,2486 ---- {"ungetch", (PyCFunction)PyCurses_UngetCh}, {"use_env", (PyCFunction)PyCurses_Use_Env}, ! {NULL, NULL} /* sentinel */ }; From akuchling@users.sourceforge.net Sat Oct 20 17:07:43 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Sat, 20 Oct 2001 09:07:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libcurses.tex,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv23294 Modified Files: libcurses.tex Log Message: Update description of border() Index: libcurses.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcurses.tex,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** libcurses.tex 2001/10/20 04:24:09 1.35 --- libcurses.tex 2001/10/20 16:07:41 1.36 *************** *** 611,617 **** Draw a border around the edges of the window. Each parameter specifies the character to use for a specific part of the border; see the table ! below for more details. The characters must be specified as integers; ! using one-character strings will cause \exception{TypeError} to be ! raised. \note{A \code{0} value for any parameter will cause the --- 611,616 ---- Draw a border around the edges of the window. Each parameter specifies the character to use for a specific part of the border; see the table ! below for more details. The characters can be specified as integers ! or as one-character strings. \note{A \code{0} value for any parameter will cause the From effbot@users.sourceforge.net Sat Oct 20 18:48:49 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Sat, 20 Oct 2001 10:48:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.67,2.68 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv8184/Modules Modified Files: _sre.c Log Message: rewrote the pattern.split method in C also restored SRE Unicode support for 1.6/2.0/2.1 Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.67 retrieving revision 2.68 diff -C2 -d -r2.67 -r2.68 *** _sre.c 2001/10/18 19:30:11 2.67 --- _sre.c 2001/10/20 17:48:46 2.68 *************** *** 34,37 **** --- 34,38 ---- * 2001-09-18 fl added _getliteral helper * 2001-10-18 fl fixed group reset issue (from Matthew Mueller) + * 2001-10-20 fl added split primitive; reenable unicode for 1.6/2.0/2.1 * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. *************** *** 66,77 **** #undef VERBOSE ! #if PY_VERSION_HEX >= 0x01060000 && defined(Py_USING_UNICODE) /* defining this enables unicode support (default under 1.6a1 and later) */ #define HAVE_UNICODE #endif /* -------------------------------------------------------------------- */ /* optional features */ /* prevent run-away recursion (bad patterns on long strings) */ --- 67,83 ---- #undef VERBOSE ! #if PY_VERSION_HEX >= 0x01060000 ! #if PY_VERSION_HEX < 0x02020000 || defined(Py_USING_UNICODE) /* defining this enables unicode support (default under 1.6a1 and later) */ #define HAVE_UNICODE #endif + #endif /* -------------------------------------------------------------------- */ /* optional features */ + /* test: define to use sre._split helper instead of C code */ + #undef USE_PYTHON_SPLIT + /* prevent run-away recursion (bad patterns on long strings) */ *************** *** 1489,1493 **** LOCAL(PyObject*) ! state_getslice(SRE_STATE* state, int index, PyObject* string) { int i, j; --- 1495,1499 ---- LOCAL(PyObject*) ! state_getslice(SRE_STATE* state, int index, PyObject* string, int empty) { int i, j; *************** *** 1496,1500 **** if (string == Py_None || !state->mark[index] || !state->mark[index+1]) { ! i = j = 0; } else { i = ((char*)state->mark[index] - (char*)state->beginning) / --- 1502,1512 ---- if (string == Py_None || !state->mark[index] || !state->mark[index+1]) { ! if (empty) ! /* want empty string */ ! i = j = 0; ! else { ! Py_INCREF(Py_None); ! return Py_None; ! } } else { i = ((char*)state->mark[index] - (char*)state->beginning) / *************** *** 1783,1786 **** --- 1795,1799 ---- } + #if defined(USE_PYTHON_SPLIT) static PyObject* pattern_split(PatternObject* self, PyObject* args, PyObject* kw) *************** *** 1799,1802 **** --- 1812,1816 ---- ); } + #endif static PyObject* *************** *** 1806,1810 **** PyObject* list; int status; ! int i; PyObject* string; --- 1820,1824 ---- PyObject* list; int status; ! int i, b, e; PyObject* string; *************** *** 1843,1857 **** switch (self->groups) { case 0: ! item = PySequence_GetSlice( ! string, ! ((char*) state.start - (char*) state.beginning) / ! state.charsize, ! ((char*) state.ptr - (char*) state.beginning) / ! state.charsize); if (!item) goto error; break; case 1: ! item = state_getslice(&state, 1, string); if (!item) goto error; --- 1857,1870 ---- switch (self->groups) { case 0: ! b = ((char*) state.start - (char*) state.beginning) / ! state.charsize; ! e = ((char*) state.ptr - (char*) state.beginning) / ! state.charsize; ! item = PySequence_GetSlice(string, b, e); if (!item) goto error; break; case 1: ! item = state_getslice(&state, 1, string, 1); if (!item) goto error; *************** *** 1862,1866 **** goto error; for (i = 0; i < self->groups; i++) { ! PyObject* o = state_getslice(&state, i+1, string); if (!o) { Py_DECREF(item); --- 1875,1879 ---- goto error; for (i = 0; i < self->groups; i++) { ! PyObject* o = state_getslice(&state, i+1, string, 1); if (!o) { Py_DECREF(item); *************** *** 1903,1906 **** --- 1916,2030 ---- } + + #if !defined(USE_PYTHON_SPLIT) + static PyObject* + pattern_split(PatternObject* self, PyObject* args, PyObject* kw) + { + SRE_STATE state; + PyObject* list; + PyObject* item; + int status; + int n; + int i, b, e; + int g; + + PyObject* string; + int maxsplit = 0; + static char* kwlist[] = { "source", "maxsplit", NULL }; + if (!PyArg_ParseTupleAndKeywords(args, kw, "O|i:split", kwlist, + &string, &maxsplit)) + return NULL; + + string = state_init(&state, self, string, 0, INT_MAX); + if (!string) + return NULL; + + list = PyList_New(0); + + i = n = 0; + + while (maxsplit == 0 || n < maxsplit) { + + state_reset(&state); + + state.ptr = state.start; + + if (state.charsize == 1) { + status = sre_search(&state, PatternObject_GetCode(self)); + } else { + #if defined(HAVE_UNICODE) + status = sre_usearch(&state, PatternObject_GetCode(self)); + #endif + } + + if (status > 0) { + + if (state.start == state.ptr) { + if (i >= state.endpos) + break; + /* skip one character */ + state.start = (void*) ((char*) state.ptr + state.charsize); + continue; + } + + b = ((char*) state.start - (char*) state.beginning) / + state.charsize; + e = ((char*) state.ptr - (char*) state.beginning) / + state.charsize; + + /* get segment before this match */ + item = PySequence_GetSlice(string, i, b); + if (!item) + goto error; + status = PyList_Append(list, item); + Py_DECREF(item); + if (status < 0) + goto error; + + for (g = 0; g < self->groups; g++) { + item = state_getslice(&state, g+1, string, 0); + if (!item) + goto error; + status = PyList_Append(list, item); + Py_DECREF(item); + if (status < 0) + goto error; + } + + i = e; + n = n + 1; + + state.start = state.ptr; + + } else { + + if (status == 0) + break; + + pattern_error(status); + goto error; + + } + } + + /* get segment following last match */ + item = PySequence_GetSlice(string, i, state.endpos); + if (!item) + goto error; + status = PyList_Append(list, item); + Py_DECREF(item); + if (status < 0) + goto error; + + state_fini(&state); + return list; + + error: + Py_DECREF(list); + state_fini(&state); + return NULL; + + } + #endif static PyObject* From gvanrossum@users.sourceforge.net Sun Oct 21 01:44:33 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 20 Oct 2001 17:44:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include descrobject.h,2.6,2.7 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv25887/Include Modified Files: descrobject.h Log Message: Big internal change that should have no external effects: unify the 'slotdef' structure typedef and 'struct wrapperbase'. By adding the wrapper docstrings to the slotdef structure, the slotdefs array can serve as the data structure that drives add_operators(); the wrapper descriptor contains a pointer to slotdef structure. This replaces lots of custom code from add_operators() by a loop over the slotdefs array, and does away with all the tab_xxx tables. Index: descrobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/descrobject.h,v retrieving revision 2.6 retrieving revision 2.7 diff -C2 -d -r2.6 -r2.7 *** descrobject.h 2001/10/03 12:09:29 2.6 --- descrobject.h 2001/10/21 00:44:31 2.7 *************** *** 17,22 **** --- 17,25 ---- struct wrapperbase { char *name; + int offset; + void *function; wrapperfunc wrapper; char *doc; + PyObject *name_strobj; }; From gvanrossum@users.sourceforge.net Sun Oct 21 01:44:33 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 20 Oct 2001 17:44:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.109,2.110 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv25887/Objects Modified Files: typeobject.c Log Message: Big internal change that should have no external effects: unify the 'slotdef' structure typedef and 'struct wrapperbase'. By adding the wrapper docstrings to the slotdef structure, the slotdefs array can serve as the data structure that drives add_operators(); the wrapper descriptor contains a pointer to slotdef structure. This replaces lots of custom code from add_operators() by a loop over the slotdefs array, and does away with all the tab_xxx tables. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.109 retrieving revision 2.110 diff -C2 -d -r2.109 -r2.110 *** typeobject.c 2001/10/18 15:49:21 2.109 --- typeobject.c 2001/10/21 00:44:31 2.110 *************** *** 1894,1902 **** } - static struct wrapperbase tab_len[] = { - {"__len__", (wrapperfunc)wrap_inquiry, "x.__len__() <==> len(x)"}, - {0} - }; - static PyObject * wrap_binaryfunc(PyObject *self, PyObject *args, void *wrapped) --- 1894,1897 ---- *************** *** 1942,1969 **** } - #undef BINARY - #define BINARY(NAME, OP) \ - static struct wrapperbase tab_##NAME[] = { \ - {"__" #NAME "__", \ - (wrapperfunc)wrap_binaryfunc_l, \ - "x.__" #NAME "__(y) <==> " #OP}, \ - {"__r" #NAME "__", \ - (wrapperfunc)wrap_binaryfunc_r, \ - "y.__r" #NAME "__(x) <==> " #OP}, \ - {0} \ - } - - BINARY(add, "x+y"); - BINARY(sub, "x-y"); - BINARY(mul, "x*y"); - BINARY(div, "x/y"); - BINARY(mod, "x%y"); - BINARY(divmod, "divmod(x,y)"); - BINARY(lshift, "x<>y"); - BINARY(and, "x&y"); - BINARY(xor, "x^y"); - BINARY(or, "x|y"); - static PyObject * wrap_coercefunc(PyObject *self, PyObject *args, void *wrapped) --- 1937,1940 ---- *************** *** 1993,2005 **** } - static struct wrapperbase tab_coerce[] = { - {"__coerce__", (wrapperfunc)wrap_coercefunc, - "x.__coerce__(y) <==> coerce(x, y)"}, - {0} - }; - - BINARY(floordiv, "x//y"); - BINARY(truediv, "x/y # true division"); - static PyObject * wrap_ternaryfunc(PyObject *self, PyObject *args, void *wrapped) --- 1964,1967 ---- *************** *** 2030,2056 **** } - #undef TERNARY - #define TERNARY(NAME, OP) \ - static struct wrapperbase tab_##NAME[] = { \ - {"__" #NAME "__", \ - (wrapperfunc)wrap_ternaryfunc, \ - "x.__" #NAME "__(y, z) <==> " #OP}, \ - {"__r" #NAME "__", \ - (wrapperfunc)wrap_ternaryfunc_r, \ - "y.__r" #NAME "__(x, z) <==> " #OP}, \ - {0} \ - } - - TERNARY(pow, "(x**y) % z"); - - #undef UNARY - #define UNARY(NAME, OP) \ - static struct wrapperbase tab_##NAME[] = { \ - {"__" #NAME "__", \ - (wrapperfunc)wrap_unaryfunc, \ - "x.__" #NAME "__() <==> " #OP}, \ - {0} \ - } - static PyObject * wrap_unaryfunc(PyObject *self, PyObject *args, void *wrapped) --- 1992,1995 ---- *************** *** 2063,2116 **** } - UNARY(neg, "-x"); - UNARY(pos, "+x"); - UNARY(abs, "abs(x)"); - UNARY(nonzero, "x != 0"); - UNARY(invert, "~x"); - UNARY(int, "int(x)"); - UNARY(long, "long(x)"); - UNARY(float, "float(x)"); - UNARY(oct, "oct(x)"); - UNARY(hex, "hex(x)"); - - #undef IBINARY - #define IBINARY(NAME, OP) \ - static struct wrapperbase tab_##NAME[] = { \ - {"__" #NAME "__", \ - (wrapperfunc)wrap_binaryfunc, \ - "x.__" #NAME "__(y) <==> " #OP}, \ - {0} \ - } - - IBINARY(iadd, "x+=y"); - IBINARY(isub, "x-=y"); - IBINARY(imul, "x*=y"); - IBINARY(idiv, "x/=y"); - IBINARY(imod, "x%=y"); - IBINARY(ilshift, "x<<=y"); - IBINARY(irshift, "x>>=y"); - IBINARY(iand, "x&=y"); - IBINARY(ixor, "x^=y"); - IBINARY(ior, "x|=y"); - IBINARY(ifloordiv, "x//=y"); - IBINARY(itruediv, "x/=y # true division"); - - #undef ITERNARY - #define ITERNARY(NAME, OP) \ - static struct wrapperbase tab_##NAME[] = { \ - {"__" #NAME "__", \ - (wrapperfunc)wrap_ternaryfunc, \ - "x.__" #NAME "__(y) <==> " #OP}, \ - {0} \ - } - - ITERNARY(ipow, "x = (x**y) % z"); - - static struct wrapperbase tab_getitem[] = { - {"__getitem__", (wrapperfunc)wrap_binaryfunc, - "x.__getitem__(y) <==> x[y]"}, - {0} - }; - static PyObject * wrap_intargfunc(PyObject *self, PyObject *args, void *wrapped) --- 2002,2005 ---- *************** *** 2124,2143 **** } - static struct wrapperbase tab_mul_int[] = { - {"__mul__", (wrapperfunc)wrap_intargfunc, "x.__mul__(n) <==> x*n"}, - {"__rmul__", (wrapperfunc)wrap_intargfunc, "x.__rmul__(n) <==> n*x"}, - {0} - }; - - static struct wrapperbase tab_concat[] = { - {"__add__", (wrapperfunc)wrap_binaryfunc, "x.__add__(y) <==> x+y"}, - {0} - }; - - static struct wrapperbase tab_imul_int[] = { - {"__imul__", (wrapperfunc)wrap_intargfunc, "x.__imul__(n) <==> x*=n"}, - {0} - }; - static int getindex(PyObject *self, PyObject *arg) --- 2013,2016 ---- *************** *** 2179,2188 **** } - static struct wrapperbase tab_getitem_int[] = { - {"__getitem__", (wrapperfunc)wrap_sq_item, - "x.__getitem__(i) <==> x[i]"}, - {0} - }; - static PyObject * wrap_intintargfunc(PyObject *self, PyObject *args, void *wrapped) --- 2052,2055 ---- *************** *** 2196,2205 **** } - static struct wrapperbase tab_getslice[] = { - {"__getslice__", (wrapperfunc)wrap_intintargfunc, - "x.__getslice__(i, j) <==> x[i:j]"}, - {0} - }; - static PyObject * wrap_sq_setitem(PyObject *self, PyObject *args, void *wrapped) --- 2063,2066 ---- *************** *** 2240,2251 **** } - static struct wrapperbase tab_setitem_int[] = { - {"__setitem__", (wrapperfunc)wrap_sq_setitem, - "x.__setitem__(i, y) <==> x[i]=y"}, - {"__delitem__", (wrapperfunc)wrap_sq_delitem, - "x.__delitem__(y) <==> del x[y]"}, - {0} - }; - static PyObject * wrap_intintobjargproc(PyObject *self, PyObject *args, void *wrapped) --- 2101,2104 ---- *************** *** 2279,2290 **** } - static struct wrapperbase tab_setslice[] = { - {"__setslice__", (wrapperfunc)wrap_intintobjargproc, - "x.__setslice__(i, j, y) <==> x[i:j]=y"}, - {"__delslice__", (wrapperfunc)wrap_delslice, - "x.__delslice__(i, j) <==> del x[i:j]"}, - {0} - }; - /* XXX objobjproc is a misnomer; should be objargpred */ static PyObject * --- 2132,2135 ---- *************** *** 2303,2312 **** } - static struct wrapperbase tab_contains[] = { - {"__contains__", (wrapperfunc)wrap_objobjproc, - "x.__contains__(y) <==> y in x"}, - {0} - }; - static PyObject * wrap_objobjargproc(PyObject *self, PyObject *args, void *wrapped) --- 2148,2151 ---- *************** *** 2341,2352 **** } - static struct wrapperbase tab_setitem[] = { - {"__setitem__", (wrapperfunc)wrap_objobjargproc, - "x.__setitem__(y, z) <==> x[y]=z"}, - {"__delitem__", (wrapperfunc)wrap_delitem, - "x.__delitem__(y) <==> del x[y]"}, - {0} - }; - static PyObject * wrap_cmpfunc(PyObject *self, PyObject *args, void *wrapped) --- 2180,2183 ---- *************** *** 2374,2395 **** } - static struct wrapperbase tab_cmp[] = { - {"__cmp__", (wrapperfunc)wrap_cmpfunc, - "x.__cmp__(y) <==> cmp(x,y)"}, - {0} - }; - - static struct wrapperbase tab_repr[] = { - {"__repr__", (wrapperfunc)wrap_unaryfunc, - "x.__repr__() <==> repr(x)"}, - {0} - }; - - static struct wrapperbase tab_getattr[] = { - {"__getattribute__", (wrapperfunc)wrap_binaryfunc, - "x.__getattribute__('name') <==> x.name"}, - {0} - }; - static PyObject * wrap_setattr(PyObject *self, PyObject *args, void *wrapped) --- 2205,2208 ---- *************** *** 2424,2435 **** } - static struct wrapperbase tab_setattr[] = { - {"__setattr__", (wrapperfunc)wrap_setattr, - "x.__setattr__('name', value) <==> x.name = value"}, - {"__delattr__", (wrapperfunc)wrap_delattr, - "x.__delattr__('name') <==> del x.name"}, - {0} - }; - static PyObject * wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped) --- 2237,2240 ---- *************** *** 2446,2455 **** } - static struct wrapperbase tab_hash[] = { - {"__hash__", (wrapperfunc)wrap_hashfunc, - "x.__hash__() <==> hash(x)"}, - {0} - }; - static PyObject * wrap_call(PyObject *self, PyObject *args, void *wrapped) --- 2251,2254 ---- *************** *** 2461,2476 **** } - static struct wrapperbase tab_call[] = { - {"__call__", (wrapperfunc)wrap_call, - "x.__call__(...) <==> x(...)"}, - {0} - }; - - static struct wrapperbase tab_str[] = { - {"__str__", (wrapperfunc)wrap_unaryfunc, - "x.__str__() <==> str(x)"}, - {0} - }; - static PyObject * wrap_richcmpfunc(PyObject *self, PyObject *args, void *wrapped, int op) --- 2260,2263 ---- *************** *** 2499,2522 **** RICHCMP_WRAPPER(ge, Py_GE) - #undef RICHCMP_ENTRY - #define RICHCMP_ENTRY(NAME, EXPR) \ - {"__" #NAME "__", (wrapperfunc)richcmp_##NAME, \ - "x.__" #NAME "__(y) <==> " EXPR} - - static struct wrapperbase tab_richcmp[] = { - RICHCMP_ENTRY(lt, "xy"), - RICHCMP_ENTRY(ge, "x>=y"), - {0} - }; - - static struct wrapperbase tab_iter[] = { - {"__iter__", (wrapperfunc)wrap_unaryfunc, "x.__iter__() <==> iter(x)"}, - {0} - }; - static PyObject * wrap_next(PyObject *self, PyObject *args, void *wrapped) --- 2286,2289 ---- *************** *** 2533,2542 **** } - static struct wrapperbase tab_next[] = { - {"next", (wrapperfunc)wrap_next, - "x.next() -> the next value, or raise StopIteration"}, - {0} - }; - static PyObject * wrap_descr_get(PyObject *self, PyObject *args, void *wrapped) --- 2300,2303 ---- *************** *** 2551,2560 **** } - static struct wrapperbase tab_descr_get[] = { - {"__get__", (wrapperfunc)wrap_descr_get, - "descr.__get__(obj, type) -> value"}, - {0} - }; - static PyObject * wrap_descr_set(PyObject *self, PyObject *args, void *wrapped) --- 2312,2315 ---- *************** *** 2573,2582 **** } - static struct wrapperbase tab_descr_set[] = { - {"__set__", (wrapperfunc)wrap_descr_set, - "descr.__set__(obj, value)"}, - {0} - }; - static PyObject * wrap_init(PyObject *self, PyObject *args, void *wrapped) --- 2328,2331 ---- *************** *** 2591,2601 **** } - static struct wrapperbase tab_init[] = { - {"__init__", (wrapperfunc)wrap_init, - "x.__init__(...) initializes x; " - "see x.__class__.__doc__ for signature"}, - {0} - }; - static PyObject * tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds) --- 2340,2343 ---- *************** *** 2674,2816 **** } - static int - add_wrappers(PyTypeObject *type, struct wrapperbase *wraps, void *wrapped) - { - PyObject *dict = type->tp_dict; - - for (; wraps->name != NULL; wraps++) { - PyObject *descr; - if (PyDict_GetItemString(dict, wraps->name)) - continue; - descr = PyDescr_NewWrapper(type, wraps, wrapped); - if (descr == NULL) - return -1; - if (PyDict_SetItemString(dict, wraps->name, descr) < 0) - return -1; - Py_DECREF(descr); - } - return 0; - } - - /* This function is called by PyType_Ready() to populate the type's - dictionary with method descriptors for function slots. For each - function slot (like tp_repr) that's defined in the type, one or - more corresponding descriptors are added in the type's tp_dict - dictionary under the appropriate name (like __repr__). Some - function slots cause more than one descriptor to be added (for - example, the nb_add slot adds both __add__ and __radd__ - descriptors) and some function slots compete for the same - descriptor (for example both sq_item and mp_subscript generate a - __getitem__ descriptor). This only adds new descriptors and - doesn't overwrite entries in tp_dict that were previously - defined. The descriptors contain a reference to the C function - they must call, so that it's safe if they are copied into a - subtype's __dict__ and the subtype has a different C function in - its slot -- calling the method defined by the descriptor will call - the C function that was used to create it, rather than the C - function present in the slot when it is called. (This is important - because a subtype may have a C function in the slot that calls the - method from the dictionary, and we want to avoid infinite recursion - here.) */ - - static int - add_operators(PyTypeObject *type) - { - PySequenceMethods *sq; - PyMappingMethods *mp; - PyNumberMethods *nb; - - #undef ADD - #define ADD(SLOT, TABLE) \ - if (SLOT) { \ - if (add_wrappers(type, TABLE, (void *)(SLOT)) < 0) \ - return -1; \ - } - - if ((sq = type->tp_as_sequence) != NULL) { - ADD(sq->sq_length, tab_len); - ADD(sq->sq_concat, tab_concat); - ADD(sq->sq_repeat, tab_mul_int); - ADD(sq->sq_item, tab_getitem_int); - ADD(sq->sq_slice, tab_getslice); - ADD(sq->sq_ass_item, tab_setitem_int); - ADD(sq->sq_ass_slice, tab_setslice); - ADD(sq->sq_contains, tab_contains); - ADD(sq->sq_inplace_concat, tab_iadd); - ADD(sq->sq_inplace_repeat, tab_imul_int); - } - - if ((mp = type->tp_as_mapping) != NULL) { - if (sq->sq_length == NULL) - ADD(mp->mp_length, tab_len); - ADD(mp->mp_subscript, tab_getitem); - ADD(mp->mp_ass_subscript, tab_setitem); - } - - if ((nb = type->tp_as_number) != NULL) { - ADD(nb->nb_add, tab_add); - ADD(nb->nb_subtract, tab_sub); - ADD(nb->nb_multiply, tab_mul); - ADD(nb->nb_divide, tab_div); - ADD(nb->nb_remainder, tab_mod); - ADD(nb->nb_divmod, tab_divmod); - ADD(nb->nb_power, tab_pow); - ADD(nb->nb_negative, tab_neg); - ADD(nb->nb_positive, tab_pos); - ADD(nb->nb_absolute, tab_abs); - ADD(nb->nb_nonzero, tab_nonzero); - ADD(nb->nb_invert, tab_invert); - ADD(nb->nb_lshift, tab_lshift); - ADD(nb->nb_rshift, tab_rshift); - ADD(nb->nb_and, tab_and); - ADD(nb->nb_xor, tab_xor); - ADD(nb->nb_or, tab_or); - ADD(nb->nb_coerce, tab_coerce); - ADD(nb->nb_int, tab_int); - ADD(nb->nb_long, tab_long); - ADD(nb->nb_float, tab_float); - ADD(nb->nb_oct, tab_oct); - ADD(nb->nb_hex, tab_hex); - ADD(nb->nb_inplace_add, tab_iadd); - ADD(nb->nb_inplace_subtract, tab_isub); - ADD(nb->nb_inplace_multiply, tab_imul); - ADD(nb->nb_inplace_divide, tab_idiv); - ADD(nb->nb_inplace_remainder, tab_imod); - ADD(nb->nb_inplace_power, tab_ipow); - ADD(nb->nb_inplace_lshift, tab_ilshift); - ADD(nb->nb_inplace_rshift, tab_irshift); - ADD(nb->nb_inplace_and, tab_iand); - ADD(nb->nb_inplace_xor, tab_ixor); - ADD(nb->nb_inplace_or, tab_ior); - if (type->tp_flags & Py_TPFLAGS_HAVE_CLASS) { - ADD(nb->nb_floor_divide, tab_floordiv); - ADD(nb->nb_true_divide, tab_truediv); - ADD(nb->nb_inplace_floor_divide, tab_ifloordiv); - ADD(nb->nb_inplace_true_divide, tab_itruediv); - } - } - - ADD(type->tp_getattro, tab_getattr); - ADD(type->tp_setattro, tab_setattr); - ADD(type->tp_compare, tab_cmp); - ADD(type->tp_repr, tab_repr); - ADD(type->tp_hash, tab_hash); - ADD(type->tp_call, tab_call); - ADD(type->tp_str, tab_str); - ADD(type->tp_richcompare, tab_richcmp); - ADD(type->tp_iter, tab_iter); - ADD(type->tp_iternext, tab_next); - ADD(type->tp_descr_get, tab_descr_get); - ADD(type->tp_descr_set, tab_descr_set); - ADD(type->tp_init, tab_init); - - if (type->tp_new != NULL) { - if (add_tp_new_wrapper(type) < 0) - return -1; - } - - return 0; - } - /* Slot wrappers that call the corresponding __foo__ slot. See comments below at override_slots() for more explanation. */ --- 2416,2419 ---- *************** *** 3572,3582 **** slots (e.g. __str__ affects tp_str as well as tp_repr). */ ! typedef struct { ! char *name; ! int offset; ! void *function; ! wrapperfunc wrapper; ! PyObject *name_strobj; ! } slotdef; #undef TPSLOT --- 3175,3179 ---- slots (e.g. __str__ affects tp_str as well as tp_repr). */ ! typedef struct wrapperbase slotdef; #undef TPSLOT *************** *** 3585,3724 **** #undef MPSLOT #undef NBSLOT #undef BINSLOT #undef RBINSLOT ! #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ! {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER} ! #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ! {NAME, offsetof(etype, SLOT), (void *)(FUNCTION), WRAPPER} ! #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ! ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER) ! #define MPSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ! ETSLOT(NAME, as_mapping.SLOT, FUNCTION, WRAPPER) ! #define NBSLOT(NAME, SLOT, FUNCTION, WRAPPER) \ ! ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER) ! #define BINSLOT(NAME, SLOT, FUNCTION) \ ! ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l) ! #define RBINSLOT(NAME, SLOT, FUNCTION) \ ! ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r) static slotdef slotdefs[] = { ! SQSLOT("__len__", sq_length, slot_sq_length, wrap_inquiry), ! SQSLOT("__add__", sq_concat, slot_sq_concat, wrap_binaryfunc), ! SQSLOT("__mul__", sq_repeat, slot_sq_repeat, wrap_intargfunc), ! SQSLOT("__rmul__", sq_repeat, slot_sq_repeat, wrap_intargfunc), ! SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item), ! SQSLOT("__getslice__", sq_slice, slot_sq_slice, wrap_intintargfunc), ! SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem), ! SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem), SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice, ! wrap_intintobjargproc), ! SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice, wrap_delslice), ! SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc), SQSLOT("__iadd__", sq_inplace_concat, slot_sq_inplace_concat, ! wrap_binaryfunc), SQSLOT("__imul__", sq_inplace_repeat, slot_sq_inplace_repeat, ! wrap_intargfunc), ! MPSLOT("__len__", mp_length, slot_mp_length, wrap_inquiry), MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, ! wrap_binaryfunc), MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript, ! wrap_objobjargproc), MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript, ! wrap_delitem), ! BINSLOT("__add__", nb_add, slot_nb_add), ! RBINSLOT("__radd__", nb_add, slot_nb_add), ! BINSLOT("__sub__", nb_subtract, slot_nb_subtract), ! RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract), ! BINSLOT("__mul__", nb_multiply, slot_nb_multiply), ! RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply), ! BINSLOT("__div__", nb_divide, slot_nb_divide), ! RBINSLOT("__rdiv__", nb_divide, slot_nb_divide), ! BINSLOT("__mod__", nb_remainder, slot_nb_remainder), ! RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder), ! BINSLOT("__divmod__", nb_divmod, slot_nb_divmod), ! RBINSLOT("__rdivmod__", nb_divmod, slot_nb_divmod), ! NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc), ! NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r), ! NBSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc), ! NBSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc), ! NBSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc), ! NBSLOT("__nonzero__", nb_nonzero, slot_nb_nonzero, wrap_unaryfunc), ! NBSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc), ! BINSLOT("__lshift__", nb_lshift, slot_nb_lshift), ! RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift), ! BINSLOT("__rshift__", nb_rshift, slot_nb_rshift), ! RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift), ! BINSLOT("__and__", nb_and, slot_nb_and), ! RBINSLOT("__rand__", nb_and, slot_nb_and), ! BINSLOT("__xor__", nb_xor, slot_nb_xor), ! RBINSLOT("__rxor__", nb_xor, slot_nb_xor), ! BINSLOT("__or__", nb_or, slot_nb_or), ! RBINSLOT("__ror__", nb_or, slot_nb_or), ! NBSLOT("__coerce__", nb_coerce, slot_nb_coerce, wrap_coercefunc), ! NBSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc), ! NBSLOT("__long__", nb_long, slot_nb_long, wrap_unaryfunc), ! NBSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc), ! NBSLOT("__oct__", nb_oct, slot_nb_oct, wrap_unaryfunc), ! NBSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc), ! NBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, ! wrap_binaryfunc), ! NBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract, ! wrap_binaryfunc), ! NBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply, ! wrap_binaryfunc), ! NBSLOT("__idiv__", nb_inplace_divide, slot_nb_inplace_divide, ! wrap_binaryfunc), ! NBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder, ! wrap_binaryfunc), ! NBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power, ! wrap_ternaryfunc), ! NBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift, ! wrap_binaryfunc), ! NBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift, ! wrap_binaryfunc), ! NBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and, ! wrap_binaryfunc), ! NBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor, ! wrap_binaryfunc), ! NBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or, ! wrap_binaryfunc), ! BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide), ! RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide), ! BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide), ! RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide), ! NBSLOT("__ifloordiv__", nb_inplace_floor_divide, ! slot_nb_inplace_floor_divide, wrap_binaryfunc), ! NBSLOT("__itruediv__", nb_inplace_true_divide, ! slot_nb_inplace_true_divide, wrap_binaryfunc), ! TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc), ! TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc), ! TPSLOT("__cmp__", tp_compare, _PyObject_SlotCompare, wrap_cmpfunc), ! TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc), ! TPSLOT("__call__", tp_call, slot_tp_call, wrap_call), TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, ! wrap_binaryfunc), ! TPSLOT("__getattribute__", tp_getattr, NULL, NULL), ! TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL), ! TPSLOT("__getattr__", tp_getattr, NULL, NULL), ! TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr), ! TPSLOT("__setattr__", tp_setattr, NULL, NULL), ! TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr), ! TPSLOT("__delattr__", tp_setattr, NULL, NULL), ! TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt), ! TPSLOT("__le__", tp_richcompare, slot_tp_richcompare, richcmp_le), ! TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq), ! TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne), ! TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt), ! TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge), ! TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc), ! TPSLOT("next", tp_iternext, slot_tp_iternext, wrap_next), ! TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get), ! TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set), ! TPSLOT("__init__", tp_init, slot_tp_init, wrap_init), ! TPSLOT("__new__", tp_new, slot_tp_new, NULL), {NULL} }; --- 3182,3388 ---- #undef MPSLOT #undef NBSLOT + #undef UNSLOT + #undef IBSLOT #undef BINSLOT #undef RBINSLOT ! #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ! {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, DOC} ! #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ! {NAME, offsetof(etype, SLOT), (void *)(FUNCTION), WRAPPER, DOC} ! #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ! ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER, DOC) ! #define MPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ! ETSLOT(NAME, as_mapping.SLOT, FUNCTION, WRAPPER, DOC) ! #define NBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ! ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC) ! #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ! ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ ! "x." NAME "() <==> " DOC) ! #define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ! ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ ! "x." NAME "(y) <==> x" DOC "y") ! #define BINSLOT(NAME, SLOT, FUNCTION, DOC) \ ! ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ ! "x." NAME "(y) <==> x" DOC "y") ! #define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \ ! ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ ! "x." NAME "(y) <==> y" DOC "x") static slotdef slotdefs[] = { ! SQSLOT("__len__", sq_length, slot_sq_length, wrap_inquiry, ! "x.__len__() <==> len(x)"), ! SQSLOT("__add__", sq_concat, slot_sq_concat, wrap_binaryfunc, ! "x.__add__(y) <==> x+y"), ! SQSLOT("__mul__", sq_repeat, slot_sq_repeat, wrap_intargfunc, ! "x.__mul__(n) <==> x*n"), ! SQSLOT("__rmul__", sq_repeat, slot_sq_repeat, wrap_intargfunc, ! "x.__rmul__(n) <==> n*x"), ! SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, ! "x.__getitem__(y) <==> x[y]"), ! SQSLOT("__getslice__", sq_slice, slot_sq_slice, wrap_intintargfunc, ! "x.__getslice__(i, j) <==> x[i:j]"), ! SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, ! "x.__setitem__(i, y) <==> x[i]=y"), ! SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem, ! "x.__delitem__(y) <==> del x[y]"), SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice, ! wrap_intintobjargproc, ! "x.__setslice__(i, j, y) <==> x[i:j]=y"), ! SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice, wrap_delslice, ! "x.__delslice__(i, j) <==> del x[i:j]"), ! SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc, ! "x.__contains__(y) <==> y in x"), SQSLOT("__iadd__", sq_inplace_concat, slot_sq_inplace_concat, ! wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"), SQSLOT("__imul__", sq_inplace_repeat, slot_sq_inplace_repeat, ! wrap_intargfunc, "x.__imul__(y) <==> x*=y"), ! MPSLOT("__len__", mp_length, slot_mp_length, wrap_inquiry, ! "x.__len__() <==> len(x)"), MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, ! wrap_binaryfunc, ! "x.__getitem__(y) <==> x[y]"), MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript, ! wrap_objobjargproc, ! "x.__setitem__(i, y) <==> x[i]=y"), MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript, ! wrap_delitem, ! "x.__delitem__(y) <==> del x[y]"), ! BINSLOT("__add__", nb_add, slot_nb_add, ! "+"), ! RBINSLOT("__radd__", nb_add, slot_nb_add, ! "+"), ! BINSLOT("__sub__", nb_subtract, slot_nb_subtract, ! "-"), ! RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract, ! "-"), ! BINSLOT("__mul__", nb_multiply, slot_nb_multiply, ! "*"), ! RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply, ! "*"), ! BINSLOT("__div__", nb_divide, slot_nb_divide, ! "/"), ! RBINSLOT("__rdiv__", nb_divide, slot_nb_divide, ! "/"), ! BINSLOT("__mod__", nb_remainder, slot_nb_remainder, ! "%"), ! RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder, ! "%"), ! BINSLOT("__divmod__", nb_divmod, slot_nb_divmod, ! "divmod(x, y)"), ! RBINSLOT("__rdivmod__", nb_divmod, slot_nb_divmod, ! "divmod(y, x)"), ! NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc, ! "x.__pow__(y[, z]) <==> pow(x, y[, z])"), ! NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r, ! "y.__rpow__(x[, z]) <==> pow(x, y[, z])"), ! UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-x"), ! UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+x"), ! UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc, ! "abs(x)"), ! UNSLOT("__nonzero__", nb_nonzero, slot_nb_nonzero, wrap_unaryfunc, ! "x != 0"), ! UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~x"), ! BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"), ! RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"), ! BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"), ! RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift, ">>"), ! BINSLOT("__and__", nb_and, slot_nb_and, "&"), ! RBINSLOT("__rand__", nb_and, slot_nb_and, "&"), ! BINSLOT("__xor__", nb_xor, slot_nb_xor, "^"), ! RBINSLOT("__rxor__", nb_xor, slot_nb_xor, "^"), ! BINSLOT("__or__", nb_or, slot_nb_or, "|"), ! RBINSLOT("__ror__", nb_or, slot_nb_or, "|"), ! NBSLOT("__coerce__", nb_coerce, slot_nb_coerce, wrap_coercefunc, ! "x.__coerce__(y) <==> coerce(x, y)"), ! UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, ! "int(x)"), ! UNSLOT("__long__", nb_long, slot_nb_long, wrap_unaryfunc, ! "long(x)"), ! UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, ! "float(x)"), ! UNSLOT("__oct__", nb_oct, slot_nb_oct, wrap_unaryfunc, ! "oct(x)"), ! UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc, ! "hex(x)"), ! IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, ! wrap_binaryfunc, "+"), ! IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract, ! wrap_binaryfunc, "-"), ! IBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply, ! wrap_binaryfunc, "*"), ! IBSLOT("__idiv__", nb_inplace_divide, slot_nb_inplace_divide, ! wrap_binaryfunc, "/"), ! IBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder, ! wrap_binaryfunc, "%"), ! IBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power, ! wrap_ternaryfunc, "**"), ! IBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift, ! wrap_binaryfunc, "<<"), ! IBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift, ! wrap_binaryfunc, ">>"), ! IBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and, ! wrap_binaryfunc, "&"), ! IBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor, ! wrap_binaryfunc, "^"), ! IBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or, ! wrap_binaryfunc, "|"), ! BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), ! RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), ! BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide, "/"), ! RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide, "/"), ! IBSLOT("__ifloordiv__", nb_inplace_floor_divide, ! slot_nb_inplace_floor_divide, wrap_binaryfunc, "//"), ! IBSLOT("__itruediv__", nb_inplace_true_divide, ! slot_nb_inplace_true_divide, wrap_binaryfunc, "/"), ! TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, ! "x.__str__() <==> str(x)"), ! TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc, ! "x.__repr__() <==> repr(x)"), ! TPSLOT("__cmp__", tp_compare, _PyObject_SlotCompare, wrap_cmpfunc, ! "x.__cmp__(y) <==> cmp(x,y)"), ! TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, ! "x.__hash__() <==> hash(x)"), ! TPSLOT("__call__", tp_call, slot_tp_call, wrap_call, ! "x.__call__(...) <==> x(...)"), TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, ! wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"), ! TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), ! TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""), ! TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""), ! TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr, ! "x.__setattr__('name', value) <==> x.name = value"), ! TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""), ! TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr, ! "x.__delattr__('name') <==> del x.name"), ! TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""), ! TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt, ! "x.__lt__(y) <==> x x<=y"), ! TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq, ! "x.__eq__(y) <==> x==y"), ! TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne, ! "x.__ne__(y) <==> x!=y"), ! TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt, ! "x.__gt__(y) <==> x>y"), ! TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge, ! "x.__ge__(y) <==> x>=y"), ! TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc, ! "x.__iter__() <==> iter(x)"), ! TPSLOT("next", tp_iternext, slot_tp_iternext, wrap_next, ! "x.next() -> the next value, or raise StopIteration"), ! TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get, ! "descr.__get__(obj[, type]) -> value"), ! TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, ! "descr.__set__(obj, value)"), ! TPSLOT("__init__", tp_init, slot_tp_init, wrap_init, ! "x.__init__(...) initializes x; " ! "see x.__class__.__doc__ for signature"), ! TPSLOT("__new__", tp_new, slot_tp_new, NULL, ! ""), {NULL} }; *************** *** 3942,3945 **** --- 3606,3661 ---- *ptr = generic; } + } + + /* This function is called by PyType_Ready() to populate the type's + dictionary with method descriptors for function slots. For each + function slot (like tp_repr) that's defined in the type, one or + more corresponding descriptors are added in the type's tp_dict + dictionary under the appropriate name (like __repr__). Some + function slots cause more than one descriptor to be added (for + example, the nb_add slot adds both __add__ and __radd__ + descriptors) and some function slots compete for the same + descriptor (for example both sq_item and mp_subscript generate a + __getitem__ descriptor). This only adds new descriptors and + doesn't overwrite entries in tp_dict that were previously + defined. The descriptors contain a reference to the C function + they must call, so that it's safe if they are copied into a + subtype's __dict__ and the subtype has a different C function in + its slot -- calling the method defined by the descriptor will call + the C function that was used to create it, rather than the C + function present in the slot when it is called. (This is important + because a subtype may have a C function in the slot that calls the + method from the dictionary, and we want to avoid infinite recursion + here.) */ + + static int + add_operators(PyTypeObject *type) + { + PyObject *dict = type->tp_dict; + slotdef *p; + PyObject *descr; + void **ptr; + + init_slotdefs(); + for (p = slotdefs; p->name; p++) { + if (p->wrapper == NULL) + continue; + ptr = slotptr(type, p->offset); + if (!ptr || !*ptr) + continue; + if (PyDict_GetItem(dict, p->name_strobj)) + continue; + descr = PyDescr_NewWrapper(type, p, *ptr); + if (descr == NULL) + return -1; + if (PyDict_SetItem(dict, p->name_strobj, descr) < 0) + return -1; + Py_DECREF(descr); + } + if (type->tp_new != NULL) { + if (add_tp_new_wrapper(type) < 0) + return -1; + } + return 0; } From anthonybaxter@users.sourceforge.net Sun Oct 21 06:57:30 2001 From: anthonybaxter@users.sourceforge.net (Anthony Baxter) Date: Sat, 20 Oct 2001 22:57:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.238.2.2,2.238.2.3 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv1640 Modified Files: Tag: release21-maint ceval.c Log Message: Backport fix from 2.277 - incorrectly swapped arguments to PyFrame_BlockSetup. Fixes very obscure and nasty bug. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.238.2.2 retrieving revision 2.238.2.3 diff -C2 -d -r2.238.2.2 -r2.238.2.3 *** ceval.c 2001/06/27 14:13:32 2.238.2.2 --- ceval.c 2001/10/21 05:57:28 2.238.2.3 *************** *** 2197,2202 **** /* For a continue inside a try block, don't pop the block for the loop. */ ! PyFrame_BlockSetup(f, b->b_type, b->b_level, ! b->b_handler); why = WHY_NOT; JUMPTO(PyInt_AS_LONG(retval)); --- 2197,2202 ---- /* For a continue inside a try block, don't pop the block for the loop. */ ! PyFrame_BlockSetup(f, b->b_type, b->b_handler, ! b->b_level); why = WHY_NOT; JUMPTO(PyInt_AS_LONG(retval)); From tim.one@home.com Sun Oct 21 07:56:21 2001 From: tim.one@home.com (Tim Peters) Date: Sun, 21 Oct 2001 02:56:21 -0400 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.238.2.2,2.238.2.3 In-Reply-To: Message-ID: [Anthony Baxter] > Modified Files: > Tag: release21-maint > ceval.c > Log Message: > Backport fix from 2.277 - incorrectly swapped arguments to > PyFrame_BlockSetup. > Fixes very obscure and nasty bug. Good for you, Anthony! Delighted to see it. An encouraging word: while few critical bugfixes are as short and sweet as this one, few are 10x bigger either. The profile.py fixes were complex, but I believe Guido already checked them in on this branch so you don't have to. If you're not subscribed to the checkins list, you should be, and watch the traffic. If I check in anything that I think should go in 2.1.2, I'll say "Bugfix candidate." somewhere in the checkin msg. From Anthony Baxter Sun Oct 21 08:00:03 2001 From: Anthony Baxter (Anthony Baxter) Date: Sun, 21 Oct 2001 17:00:03 +1000 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.238.2.2,2.238.2.3 In-Reply-To: Message from "Tim Peters" of "Sun, 21 Oct 2001 02:56:21 -0400." Message-ID: <200110210700.f9L704831575@mbuna.arbhome.com.au> > Good for you, Anthony! Delighted to see it. An encouraging word: while > few critical bugfixes are as short and sweet as this one, few are 10x bigger > either. The profile.py fixes were complex, but I believe Guido already > checked them in on this branch so you don't have to. *nod* I've been trawling CVS. Lotsa fun, really. > If you're not subscribed to the checkins list, you should be, and watch the > traffic. If I check in anything that I think should go in 2.1.2, I'll say > "Bugfix candidate." somewhere in the checkin msg. I noticed that. It makes life a lot nicer. (Yep, subscribed to checkins and the rest, although waiting for python-dev to get the tickbox). If I've got some doubts about a patch, I'll try to err on the side of double- checking with the original fixer first, but if anyone does see something that should, or should not, be applied, please let me know. Anthony -- Anthony Baxter It's never too late to have a happy childhood. From loewis@users.sourceforge.net Sun Oct 21 09:53:54 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 21 Oct 2001 01:53:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules pyexpat.c,2.51,2.52 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv27813 Modified Files: pyexpat.c Log Message: Change clear_handlers argument to indicate whether this is an initialization. Do not set the Expat handlers if it is. Fixes PyXML bug #473195. Index: pyexpat.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v retrieving revision 2.51 retrieving revision 2.52 diff -C2 -d -r2.51 -r2.52 *** pyexpat.c 2001/09/23 10:20:10 2.51 --- pyexpat.c 2001/10/21 08:53:52 2.52 *************** *** 291,300 **** /* Callback routines */ ! static void clear_handlers(xmlparseobject *self, int decref); static void flag_error(xmlparseobject *self) { ! clear_handlers(self, 1); } --- 291,300 ---- /* Callback routines */ ! static void clear_handlers(xmlparseobject *self, int initial); static void flag_error(xmlparseobject *self) { ! clear_handlers(self, 0); } *************** *** 1018,1022 **** return PyErr_NoMemory(); } ! clear_handlers(new_parser, 0); /* then copy handlers from self */ --- 1018,1022 ---- return PyErr_NoMemory(); } ! clear_handlers(new_parser, 1); /* then copy handlers from self */ *************** *** 1194,1198 **** return PyErr_NoMemory(); } ! clear_handlers(self, 0); return (PyObject*)self; --- 1194,1198 ---- return PyErr_NoMemory(); } ! clear_handlers(self, 1); return (PyObject*)self; *************** *** 1368,1372 **** xmlparse_clear(xmlparseobject *op) { ! clear_handlers(op, 1); return 0; } --- 1368,1372 ---- xmlparse_clear(xmlparseobject *op) { ! clear_handlers(op, 0); return 0; } *************** *** 1677,1681 **** static void ! clear_handlers(xmlparseobject *self, int decref) { int i = 0; --- 1677,1681 ---- static void ! clear_handlers(xmlparseobject *self, int initial) { int i = 0; *************** *** 1683,1693 **** for (; handler_info[i].name!=NULL; i++) { ! if (decref) { temp = self->handlers[i]; self->handlers[i] = NULL; Py_XDECREF(temp); } - self->handlers[i]=NULL; - handler_info[i].setter(self->itself, NULL); } } --- 1683,1694 ---- for (; handler_info[i].name!=NULL; i++) { ! if (initial) ! self->handlers[i]=NULL; ! else { temp = self->handlers[i]; self->handlers[i] = NULL; Py_XDECREF(temp); + handler_info[i].setter(self->itself, NULL); } } } From effbot@users.sourceforge.net Sun Oct 21 17:47:59 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Sun, 21 Oct 2001 09:47:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sre.py,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv14492/Lib Modified Files: sre.py Log Message: rewrote the pattern.sub and pattern.subn methods in C removed (conceptually flawed) getliteral helper; the new sub/subn code uses a faster code path for literal replacement strings, but doesn't (yet) look for literal patterns. added STATE_OFFSET macro, and use it to convert state.start/ptr to char indexes Index: sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** sre.py 2001/10/18 19:30:15 1.39 --- sre.py 2001/10/21 16:47:57 1.40 *************** *** 105,109 **** "UNICODE", "error" ] ! __version__ = "2.2.0" # this module works under 1.5.2 and later. don't use string methods --- 105,109 ---- "UNICODE", "error" ] ! __version__ = "2.2.1" # this module works under 1.5.2 and later. don't use string methods *************** *** 244,268 **** template = sre_parse.parse_template(template, pattern) return sre_parse.expand_template(template, match) - - def _sub(pattern, template, text, count=0): - # internal: pattern.sub implementation hook - return _subn(pattern, template, text, count, 1)[0] ! def _subn(pattern, template, text, count=0, sub=0): ! # internal: pattern.subn implementation hook if callable(template): filter = template else: template = _compile_repl(template, pattern) ! literals = template[1] ! if sub and not count: ! literal = pattern._getliteral() ! if literal and "\\" in literal: ! literal = None # may contain untranslated escapes ! if literal is not None and len(literals) == 1 and literals[0]: ! # shortcut: both pattern and string are literals ! return string.replace(text, pattern.pattern, literals[0]), 0 ! def filter(match, template=template): ! return sre_parse.expand_template(template, match) n = i = 0 s = [] --- 244,275 ---- template = sre_parse.parse_template(template, pattern) return sre_parse.expand_template(template, match) ! def _subx(pattern, template): ! # internal: pattern.sub/subn implementation helper if callable(template): filter = template else: template = _compile_repl(template, pattern) ! if not template[0] and len(template[1]) == 1: ! # literal replacement ! filter = template[1][0] ! else: ! def filter(match, template=template): ! return sre_parse.expand_template(template, match) ! return filter ! ! def _sub(pattern, template, text, count=0): ! # internal: pattern.sub implementation hook ! # FIXME: not used in SRE 2.2.1 and later; will be removed soon ! return _subn(pattern, template, text, count)[0] ! ! def _subn(pattern, template, text, count=0): ! # internal: pattern.subn implementation hook ! # FIXME: not used in SRE 2.2.1 and later; will be removed soon ! filter = _subx(pattern, template) ! if not callable(filter): ! # literal replacement ! def filter(match, literal=filter): ! return literal n = i = 0 s = [] *************** *** 287,290 **** --- 294,298 ---- def _split(pattern, text, maxsplit=0): # internal: pattern.split implementation hook + # FIXME: not used in SRE 2.2.1 and later; will be removed soon n = i = 0 s = [] From effbot@users.sourceforge.net Sun Oct 21 17:47:59 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Sun, 21 Oct 2001 09:47:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.68,2.69 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv14492/Modules Modified Files: _sre.c Log Message: rewrote the pattern.sub and pattern.subn methods in C removed (conceptually flawed) getliteral helper; the new sub/subn code uses a faster code path for literal replacement strings, but doesn't (yet) look for literal patterns. added STATE_OFFSET macro, and use it to convert state.start/ptr to char indexes Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.68 retrieving revision 2.69 diff -C2 -d -r2.68 -r2.69 *** _sre.c 2001/10/20 17:48:46 2.68 --- _sre.c 2001/10/21 16:47:57 2.69 *************** *** 32,38 **** * 2001-05-14 fl fixes for 1.5.2 * 2001-07-01 fl added BIGCHARSET support (from Martin von Loewis) - * 2001-09-18 fl added _getliteral helper * 2001-10-18 fl fixed group reset issue (from Matthew Mueller) * 2001-10-20 fl added split primitive; reenable unicode for 1.6/2.0/2.1 * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. --- 32,38 ---- * 2001-05-14 fl fixes for 1.5.2 * 2001-07-01 fl added BIGCHARSET support (from Martin von Loewis) * 2001-10-18 fl fixed group reset issue (from Matthew Mueller) * 2001-10-20 fl added split primitive; reenable unicode for 1.6/2.0/2.1 + * 2001-10-21 fl added sub/subn primitive * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. *************** *** 50,54 **** static char copyright[] = ! " SRE 2.2.0 Copyright (c) 1997-2001 by Secret Labs AB "; #include "Python.h" --- 50,54 ---- static char copyright[] = ! " SRE 2.2.1 Copyright (c) 1997-2001 by Secret Labs AB "; #include "Python.h" *************** *** 77,82 **** /* optional features */ ! /* test: define to use sre._split helper instead of C code */ #undef USE_PYTHON_SPLIT /* prevent run-away recursion (bad patterns on long strings) */ --- 77,83 ---- /* optional features */ ! /* test: define to use sre.py helpers instead of C code */ #undef USE_PYTHON_SPLIT + #undef USE_PYTHON_SUB /* prevent run-away recursion (bad patterns on long strings) */ *************** *** 1494,1497 **** --- 1495,1502 ---- } + /* calculate offset from start of string */ + #define STATE_OFFSET(state, member)\ + (((char*)(member) - (char*)(state)->beginning) / (state)->charsize) + LOCAL(PyObject*) state_getslice(SRE_STATE* state, int index, PyObject* string, int empty) *************** *** 1510,1517 **** } } else { ! i = ((char*)state->mark[index] - (char*)state->beginning) / ! state->charsize; ! j = ((char*)state->mark[index+1] - (char*)state->beginning) / ! state->charsize; } --- 1515,1520 ---- } } else { ! i = STATE_OFFSET(state, state->mark[index]); ! j = STATE_OFFSET(state, state->mark[index+1]); } *************** *** 1722,1725 **** --- 1725,1730 ---- PyObject* result; + if (!args) + return NULL; name = PyString_FromString(module); if (!name) *************** *** 1760,1763 **** --- 1765,1822 ---- static PyObject* + join(PyObject* list, PyObject* pattern) + { + /* join list elements */ + + PyObject* joiner; + #if PY_VERSION_HEX >= 0x01060000 + PyObject* function; + PyObject* args; + #endif + PyObject* result; + + switch (PyList_GET_SIZE(list)) { + case 0: + Py_DECREF(list); + return PyString_FromString(""); + case 1: + result = PyList_GET_ITEM(list, 0); + Py_INCREF(result); + Py_DECREF(list); + return result; + } + + /* two or more elements: slice out a suitable separator from the + first member, and use that to join the entire list */ + + joiner = PySequence_GetSlice(pattern, 0, 0); + if (!joiner) + return NULL; + + #if PY_VERSION_HEX >= 0x01060000 + function = PyObject_GetAttrString(joiner, "join"); + if (!function) { + Py_DECREF(joiner); + return NULL; + } + args = PyTuple_New(1); + PyTuple_SET_ITEM(args, 0, list); + result = PyObject_CallObject(function, args); + Py_DECREF(args); /* also removes list */ + Py_DECREF(function); + #else + result = call( + "string", "join", + Py_BuildValue("OO", list, joiner) + ); + #endif + Py_DECREF(joiner); + + return result; + } + + + #ifdef USE_PYTHON_SUB + static PyObject* pattern_sub(PatternObject* self, PyObject* args, PyObject* kw) { *************** *** 1776,1780 **** --- 1835,1841 ---- ); } + #endif + #ifdef USE_PYTHON_SUB static PyObject* pattern_subn(PatternObject* self, PyObject* args, PyObject* kw) *************** *** 1794,1797 **** --- 1855,1859 ---- ); } + #endif #if defined(USE_PYTHON_SPLIT) *************** *** 1852,1908 **** } ! if (status > 0) { ! ! /* don't bother to build a match object */ ! switch (self->groups) { ! case 0: ! b = ((char*) state.start - (char*) state.beginning) / ! state.charsize; ! e = ((char*) state.ptr - (char*) state.beginning) / ! state.charsize; ! item = PySequence_GetSlice(string, b, e); ! if (!item) ! goto error; ! break; ! case 1: ! item = state_getslice(&state, 1, string, 1); ! if (!item) ! goto error; break; ! default: ! item = PyTuple_New(self->groups); ! if (!item) goto error; - for (i = 0; i < self->groups; i++) { - PyObject* o = state_getslice(&state, i+1, string, 1); - if (!o) { - Py_DECREF(item); - goto error; - } - PyTuple_SET_ITEM(item, i, o); } ! break; } ! ! status = PyList_Append(list, item); ! Py_DECREF(item); ! ! if (status < 0) ! goto error; ! ! if (state.ptr == state.start) ! state.start = (void*) ((char*) state.ptr + state.charsize); ! else ! state.start = state.ptr; ! ! } else { ! ! if (status == 0) ! break; ! pattern_error(status); goto error; ! } } --- 1914,1963 ---- } ! if (status <= 0) { ! if (status == 0) break; ! pattern_error(status); ! goto error; ! } ! ! /* don't bother to build a match object */ ! switch (self->groups) { ! case 0: ! b = STATE_OFFSET(&state, state.start); ! e = STATE_OFFSET(&state, state.ptr); ! item = PySequence_GetSlice(string, b, e); ! if (!item) ! goto error; ! break; ! case 1: ! item = state_getslice(&state, 1, string, 1); ! if (!item) ! goto error; ! break; ! default: ! item = PyTuple_New(self->groups); ! if (!item) ! goto error; ! for (i = 0; i < self->groups; i++) { ! PyObject* o = state_getslice(&state, i+1, string, 1); ! if (!o) { ! Py_DECREF(item); goto error; } ! PyTuple_SET_ITEM(item, i, o); } ! break; ! } ! status = PyList_Append(list, item); ! Py_DECREF(item); ! if (status < 0) goto error; ! if (state.ptr == state.start) ! state.start = (void*) ((char*) state.ptr + state.charsize); ! else ! state.start = state.ptr; ! } *************** *** 1926,1931 **** int status; int n; ! int i, b, e; ! int g; PyObject* string; --- 1981,1986 ---- int status; int n; ! int i; ! void* last; PyObject* string; *************** *** 1942,1948 **** list = PyList_New(0); ! i = n = 0; ! while (maxsplit == 0 || n < maxsplit) { state_reset(&state); --- 1997,2004 ---- list = PyList_New(0); ! n = 0; ! last = state.start; ! while (!maxsplit || n < maxsplit) { state_reset(&state); *************** *** 1957,1978 **** #endif } - - if (status > 0) { ! if (state.start == state.ptr) { ! if (i >= state.endpos) ! break; ! /* skip one character */ ! state.start = (void*) ((char*) state.ptr + state.charsize); ! continue; ! } ! b = ((char*) state.start - (char*) state.beginning) / ! state.charsize; ! e = ((char*) state.ptr - (char*) state.beginning) / ! state.charsize; ! /* get segment before this match */ ! item = PySequence_GetSlice(string, i, b); if (!item) goto error; --- 2013,2047 ---- #endif } ! if (status <= 0) { ! if (status == 0) ! break; ! pattern_error(status); ! goto error; ! } ! ! if (state.start == state.ptr) { ! if (last == state.end) ! break; ! /* skip one character */ ! state.start = (void*) ((char*) state.ptr + state.charsize); ! continue; ! } ! /* get segment before this match */ ! item = PySequence_GetSlice( ! string, STATE_OFFSET(&state, last), ! STATE_OFFSET(&state, state.start) ! ); ! if (!item) ! goto error; ! status = PyList_Append(list, item); ! Py_DECREF(item); ! if (status < 0) ! goto error; ! /* add groups (if any) */ ! for (i = 0; i < self->groups; i++) { ! item = state_getslice(&state, i+1, string, 0); if (!item) goto error; *************** *** 1981,2009 **** if (status < 0) goto error; ! for (g = 0; g < self->groups; g++) { ! item = state_getslice(&state, g+1, string, 0); ! if (!item) ! goto error; ! status = PyList_Append(list, item); ! Py_DECREF(item); ! if (status < 0) ! goto error; ! } ! i = e; ! n = n + 1; ! state.start = state.ptr; } else { if (status == 0) break; - pattern_error(status); goto error; } } --- 2050,2192 ---- if (status < 0) goto error; + } ! n = n + 1; ! last = state.start = state.ptr; ! } + /* get segment following last match */ + item = PySequence_GetSlice( + string, STATE_OFFSET(&state, last), state.endpos + ); + if (!item) + goto error; + status = PyList_Append(list, item); + Py_DECREF(item); + if (status < 0) + goto error; + + state_fini(&state); + return list; + + error: + Py_DECREF(list); + state_fini(&state); + return NULL; + + } + #endif + + #if !defined(USE_PYTHON_SUB) + static PyObject* + pattern_subx(PatternObject* self, PyObject* template, PyObject* string, + int count, int subn) + { + SRE_STATE state; + PyObject* list; + PyObject* item; + PyObject* filter; + PyObject* args; + PyObject* match; + int status; + int n; + int i, b, e; + int filter_is_callable; + + /* call subx helper to get the filter */ + filter = call( + SRE_MODULE, "_subx", + Py_BuildValue("OO", self, template) + ); + if (!filter) + return NULL; + + filter_is_callable = PyCallable_Check(filter); + + string = state_init(&state, self, string, 0, INT_MAX); + if (!string) + return NULL; + + list = PyList_New(0); + + n = i = 0; + + while (!count || n < count) { + + state_reset(&state); + + state.ptr = state.start; + + if (state.charsize == 1) { + status = sre_search(&state, PatternObject_GetCode(self)); } else { + #if defined(HAVE_UNICODE) + status = sre_usearch(&state, PatternObject_GetCode(self)); + #endif + } + if (status <= 0) { if (status == 0) break; pattern_error(status); goto error; + } + + b = STATE_OFFSET(&state, state.start); + e = STATE_OFFSET(&state, state.ptr); + if (i < b) { + /* get segment before this match */ + item = PySequence_GetSlice(string, i, b); + if (!item) + goto error; + status = PyList_Append(list, item); + Py_DECREF(item); + if (status < 0) + goto error; + + } else if (i == b && i == e && n > 0) + /* ignore empty match on latest position */ + goto next; + + if (filter_is_callable) { + /* filter match */ + match = pattern_new_match(self, &state, 1); + if (!match) + goto error; + args = Py_BuildValue("(O)", match); + if (!args) { + Py_DECREF(args); + goto error; + } + item = PyObject_CallObject(filter, args); + Py_DECREF(args); + Py_DECREF(match); + if (!item) + goto error; + } else { + /* filter is literal string */ + item = filter; + Py_INCREF(filter); } + + /* add to list */ + status = PyList_Append(list, item); + Py_DECREF(item); + if (status < 0) + goto error; + + i = e; + n = n + 1; + + next: + /* move on */ + if (state.ptr == state.start) + state.start = (void*) ((char*) state.ptr + state.charsize); + else + state.start = state.ptr; + } *************** *** 2018,2023 **** state_fini(&state); - return list; error: Py_DECREF(list); --- 2201,2215 ---- state_fini(&state); + /* convert list to single string */ + item = join(list, self->pattern); + if (!item) + return NULL; + + if (subn) + return Py_BuildValue("Ni", item, n); + + return item; + error: Py_DECREF(list); *************** *** 2026,2029 **** --- 2218,2249 ---- } + + static PyObject* + pattern_sub(PatternObject* self, PyObject* args, PyObject* kw) + { + PyObject* template; + PyObject* string; + int count = 0; + static char* kwlist[] = { "repl", "string", "count", NULL }; + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|i:sub", kwlist, + &template, &string, &count)) + return NULL; + + return pattern_subx(self, template, string, count, 0); + } + + static PyObject* + pattern_subn(PatternObject* self, PyObject* args, PyObject* kw) + { + PyObject* template; + PyObject* string; + int count = 0; + static char* kwlist[] = { "repl", "string", "count", NULL }; + if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|i:subn", kwlist, + &template, &string, &count)) + return NULL; + + return pattern_subx(self, template, string, count, 1); + } #endif *************** *** 2085,2114 **** } - static PyObject* - pattern_getliteral(PatternObject* self, PyObject* args) - { - /* internal: if the pattern is a literal string, return that - string. otherwise, return None */ - - SRE_CODE* code; - PyObject* literal; - - if (!PyArg_ParseTuple(args, ":_getliteral")) - return NULL; - - code = PatternObject_GetCode(self); - - if (code[0] == SRE_OP_INFO && code[2] & SRE_INFO_LITERAL) { - /* FIXME: extract literal string from code buffer. we can't - use the pattern member, since it may contain untranslated - escape codes (see SF bug 449000) */ - literal = Py_None; - } else - literal = Py_None; /* no literal */ - - Py_INCREF(literal); - return literal; - } - static PyMethodDef pattern_methods[] = { {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS}, --- 2305,2308 ---- *************** *** 2121,2125 **** {"__copy__", (PyCFunction) pattern_copy, METH_VARARGS}, {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_VARARGS}, - {"_getliteral", (PyCFunction) pattern_getliteral, METH_VARARGS}, {NULL, NULL} }; --- 2315,2318 ---- From effbot@users.sourceforge.net Sun Oct 21 19:04:13 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Sun, 21 Oct 2001 11:04:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.69,2.70 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv30794/Modules Modified Files: _sre.c Log Message: sre.Scanner fixes (from Greg Chapman). also added a Scanner sanity check to the test suite. added a few missing exception checks in the _sre module Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.69 retrieving revision 2.70 diff -C2 -d -r2.69 -r2.70 *** _sre.c 2001/10/21 16:47:57 2.69 --- _sre.c 2001/10/21 18:04:11 2.70 *************** *** 1801,1804 **** --- 1801,1809 ---- } args = PyTuple_New(1); + if (!args) { + Py_DECREF(function); + Py_DECREF(joiner); + return NULL; + } PyTuple_SET_ITEM(args, 0, list); result = PyObject_CallObject(function, args); *************** *** 1897,1900 **** --- 1902,1909 ---- list = PyList_New(0); + if (!list) { + state_fini(&state); + return NULL; + } while (state.start <= state.end) { *************** *** 1996,1999 **** --- 2005,2012 ---- list = PyList_New(0); + if (!list) { + state_fini(&state); + return NULL; + } n = 0; *************** *** 2111,2114 **** --- 2124,2131 ---- list = PyList_New(0); + if (!list) { + state_fini(&state); + return NULL; + } n = i = 0; From effbot@users.sourceforge.net Sun Oct 21 19:04:13 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Sun, 21 Oct 2001 11:04:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_sre.py,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv30794/Lib/test Modified Files: test_sre.py Log Message: sre.Scanner fixes (from Greg Chapman). also added a Scanner sanity check to the test suite. added a few missing exception checks in the _sre module Index: test_sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sre.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** test_sre.py 2001/10/18 19:30:16 1.30 --- test_sre.py 2001/10/21 18:04:11 1.31 *************** *** 225,228 **** --- 225,248 ---- if verbose: + print 'Running tests on sre.Scanner' + + def s_ident(scanner, token): return token + def s_operator(scanner, token): return "op%s" % token + def s_float(scanner, token): return float(token) + def s_int(scanner, token): return int(token) + + scanner = sre.Scanner([ + (r"[a-zA-Z_]\w*", s_ident), + (r"\d+\.\d*", s_float), + (r"\d+", s_int), + (r"=|\+|-|\*|/", s_operator), + (r"\s+", None), + ]) + + # sanity check + test('scanner.scan("sum = 3*foo + 312.50 + bar")', + (['sum', 'op=', 3, 'op*', 'foo', 'op+', 312.5, 'op+', 'bar'], '')) + + if verbose: print 'Pickling a SRE_Pattern instance' From effbot@users.sourceforge.net Sun Oct 21 19:04:13 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Sun, 21 Oct 2001 11:04:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sre.py,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv30794/Lib Modified Files: sre.py Log Message: sre.Scanner fixes (from Greg Chapman). also added a Scanner sanity check to the test suite. added a few missing exception checks in the _sre module Index: sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre.py,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** sre.py 2001/10/21 16:47:57 1.40 --- sre.py 2001/10/21 18:04:11 1.41 *************** *** 331,335 **** class Scanner: ! def __init__(self, lexicon): from sre_constants import BRANCH, SUBPATTERN self.lexicon = lexicon --- 331,335 ---- class Scanner: ! def __init__(self, lexicon, flags=0): from sre_constants import BRANCH, SUBPATTERN self.lexicon = lexicon *************** *** 337,343 **** p = [] s = sre_parse.Pattern() for phrase, action in lexicon: p.append(sre_parse.SubPattern(s, [ ! (SUBPATTERN, (len(p), sre_parse.parse(phrase))), ])) p = sre_parse.SubPattern(s, [(BRANCH, (None, p))]) --- 337,344 ---- p = [] s = sre_parse.Pattern() + s.flags = flags for phrase, action in lexicon: p.append(sre_parse.SubPattern(s, [ ! (SUBPATTERN, (len(p)+1, sre_parse.parse(phrase, flags))), ])) p = sre_parse.SubPattern(s, [(BRANCH, (None, p))]) *************** *** 347,354 **** result = [] append = result.append ! match = self.scanner.match i = 0 while 1: ! m = match(string, i) if not m: break --- 348,355 ---- result = [] append = result.append ! match = self.scanner.scanner(string).match i = 0 while 1: ! m = match() if not m: break *************** *** 356,360 **** if i == j: break ! action = self.lexicon[m.lastindex][1] if callable(action): self.match = m --- 357,361 ---- if i == j: break ! action = self.lexicon[m.lastindex-1][1] if callable(action): self.match = m From tim_one@users.sourceforge.net Sun Oct 21 19:24:10 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 21 Oct 2001 11:24:10 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0006.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv2500 Modified Files: pep-0006.txt Log Message: Added Anthony Baxter as 2.1.2 Czar. Index: pep-0006.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0006.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pep-0006.txt 2001/07/05 18:50:28 1.6 --- pep-0006.txt 2001/10/21 18:24:08 1.7 *************** *** 100,103 **** --- 100,105 ---- Patch Czar History + Anthony Baxter (anthony@interlink.com.au) is the Patch Czar for 2.1.2. + Thomas Wouters (thomas@xs4all.net) is the Patch Czar for 2.1.1. From pierslauder@users.sourceforge.net Sun Oct 21 21:26:39 2001 From: pierslauder@users.sourceforge.net (Piers Lauder) Date: Sun, 21 Oct 2001 13:26:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib imaplib.py,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv28671/dist/src/Lib Modified Files: imaplib.py Log Message: fix send method not noticing when partial sends happen Index: imaplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/imaplib.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** imaplib.py 2001/10/15 13:46:10 1.35 --- imaplib.py 2001/10/21 20:26:37 1.36 *************** *** 223,227 **** def send(self, data): """Send data to remote.""" ! self.sock.send(data) --- 223,233 ---- def send(self, data): """Send data to remote.""" ! bytes = len(data) ! while bytes > 0: ! sent = self.sock.send(data) ! if sent == bytes: ! break # avoid copy ! data = data[sent:] ! bytes = bytes - sent From effbot@users.sourceforge.net Sun Oct 21 22:48:32 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Sun, 21 Oct 2001 14:48:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sre.py,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv18443/Lib Modified Files: sre.py Log Message: fixed character set description in docstring (SRE uses Python strings, not C strings) removed USE_PYTHON defines, and related sre.py helpers skip calling the subx helper if the template is callable. interestingly enough, this means that def callback(m): return literal result = pattern.sub(callback, string) is much faster than result = pattern.sub(literal, string) Index: sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** sre.py 2001/10/21 18:04:11 1.41 --- sre.py 2001/10/21 21:48:30 1.42 *************** *** 18,30 **** This module provides regular expression matching operations similar to ! those found in Perl. It's 8-bit clean: the strings being processed may ! contain both null bytes and characters whose high bit is set. Regular ! expression pattern strings may not contain null bytes, but can specify ! the null byte using the \\number notation. Characters with the high ! bit set may be included. ! Regular expressions can contain both special and ordinary ! characters. Most ordinary characters, like "A", "a", or "0", are the ! simplest regular expressions; they simply match themselves. You can concatenate ordinary characters, so last matches the string 'last'. --- 18,28 ---- This module provides regular expression matching operations similar to ! those found in Perl. It supports both 8-bit and Unicode strings; both ! the pattern and the strings being processed can contain null bytes and ! characters outside the US ASCII range. ! Regular expressions can contain both special and ordinary characters. ! Most ordinary characters, like "A", "a", or "0", are the simplest ! regular expressions; they simply match themselves. You can concatenate ordinary characters, so last matches the string 'last'. *************** *** 46,50 **** (...) Matches the RE inside the parentheses. The contents can be retrieved or matched later in the string. ! (?iLmsx) Set the I, L, M, S, or X flag for the RE (see below). (?:...) Non-grouping version of regular parentheses. (?P...) The substring matched by the group is accessible by name. --- 44,48 ---- (...) Matches the RE inside the parentheses. The contents can be retrieved or matched later in the string. ! (?iLmsux) Set the I, L, M, S, U, or X flag for the RE (see below). (?:...) Non-grouping version of regular parentheses. (?P...) The substring matched by the group is accessible by name. *************** *** 55,59 **** The special sequences consist of "\\" and a character from the list ! below. If the ordinary character is not on the list, then the resulting RE will match the second character. \number Matches the contents of the group of the same number. --- 53,57 ---- The special sequences consist of "\\" and a character from the list ! below. If the ordinary character is not on the list, then the resulting RE will match the second character. \number Matches the contents of the group of the same number. *************** *** 247,320 **** def _subx(pattern, template): # internal: pattern.sub/subn implementation helper ! if callable(template): ! filter = template ! else: ! template = _compile_repl(template, pattern) ! if not template[0] and len(template[1]) == 1: ! # literal replacement ! filter = template[1][0] ! else: ! def filter(match, template=template): ! return sre_parse.expand_template(template, match) ! return filter ! ! def _sub(pattern, template, text, count=0): ! # internal: pattern.sub implementation hook ! # FIXME: not used in SRE 2.2.1 and later; will be removed soon ! return _subn(pattern, template, text, count)[0] ! ! def _subn(pattern, template, text, count=0): ! # internal: pattern.subn implementation hook ! # FIXME: not used in SRE 2.2.1 and later; will be removed soon ! filter = _subx(pattern, template) ! if not callable(filter): # literal replacement ! def filter(match, literal=filter): ! return literal ! n = i = 0 ! s = [] ! append = s.append ! c = pattern.scanner(text) ! while not count or n < count: ! m = c.search() ! if not m: ! break ! b, e = m.span() ! if i < b: ! append(text[i:b]) ! elif i == b == e and n: ! append(text[i:b]) ! continue # ignore empty match at previous position ! append(filter(m)) ! i = e ! n = n + 1 ! append(text[i:]) ! return _join(s, text[:0]), n ! ! def _split(pattern, text, maxsplit=0): ! # internal: pattern.split implementation hook ! # FIXME: not used in SRE 2.2.1 and later; will be removed soon ! n = i = 0 ! s = [] ! append = s.append ! extend = s.extend ! c = pattern.scanner(text) ! g = pattern.groups ! while not maxsplit or n < maxsplit: ! m = c.search() ! if not m: ! break ! b, e = m.span() ! if b == e: ! if i >= len(text): ! break ! continue ! append(text[i:b]) ! if g and b != e: ! extend(list(m.groups())) ! i = e ! n = n + 1 ! append(text[i:]) ! return s # register myself for pickling --- 245,255 ---- def _subx(pattern, template): # internal: pattern.sub/subn implementation helper ! template = _compile_repl(template, pattern) ! if not template[0] and len(template[1]) == 1: # literal replacement ! return template[1][0] ! def filter(match, template=template): ! return sre_parse.expand_template(template, match) ! return filter # register myself for pickling From effbot@users.sourceforge.net Sun Oct 21 22:48:32 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Sun, 21 Oct 2001 14:48:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.70,2.71 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv18443/Modules Modified Files: _sre.c Log Message: fixed character set description in docstring (SRE uses Python strings, not C strings) removed USE_PYTHON defines, and related sre.py helpers skip calling the subx helper if the template is callable. interestingly enough, this means that def callback(m): return literal result = pattern.sub(callback, string) is much faster than result = pattern.sub(literal, string) Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.70 retrieving revision 2.71 diff -C2 -d -r2.70 -r2.71 *** _sre.c 2001/10/21 18:04:11 2.70 --- _sre.c 2001/10/21 21:48:30 2.71 *************** *** 77,84 **** /* optional features */ - /* test: define to use sre.py helpers instead of C code */ - #undef USE_PYTHON_SPLIT - #undef USE_PYTHON_SUB - /* prevent run-away recursion (bad patterns on long strings) */ --- 77,80 ---- *************** *** 1252,1255 **** --- 1248,1253 ---- state->start = ptr; state->ptr = ++ptr; + if (flags & SRE_INFO_LITERAL) + return 1; /* we got all of it */ status = SRE_MATCH(state, pattern + 2, 1); if (status != 0) *************** *** 1821,1885 **** } - - #ifdef USE_PYTHON_SUB static PyObject* - pattern_sub(PatternObject* self, PyObject* args, PyObject* kw) - { - PyObject* template; - PyObject* string; - PyObject* count = Py_False; /* zero */ - static char* kwlist[] = { "repl", "string", "count", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|O:sub", kwlist, - &template, &string, &count)) - return NULL; - - /* delegate to Python code */ - return call( - SRE_MODULE, "_sub", - Py_BuildValue("OOOO", self, template, string, count) - ); - } - #endif - - #ifdef USE_PYTHON_SUB - static PyObject* - pattern_subn(PatternObject* self, PyObject* args, PyObject* kw) - { - PyObject* template; - PyObject* string; - PyObject* count = Py_False; /* zero */ - static char* kwlist[] = { "repl", "string", "count", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|O:subn", kwlist, - &template, &string, &count)) - return NULL; - - /* delegate to Python code */ - return call( - SRE_MODULE, "_subn", - Py_BuildValue("OOOO", self, template, string, count) - ); - } - #endif - - #if defined(USE_PYTHON_SPLIT) - static PyObject* - pattern_split(PatternObject* self, PyObject* args, PyObject* kw) - { - PyObject* string; - PyObject* maxsplit = Py_False; /* zero */ - static char* kwlist[] = { "source", "maxsplit", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "O|O:split", kwlist, - &string, &maxsplit)) - return NULL; - - /* delegate to Python code */ - return call( - SRE_MODULE, "_split", - Py_BuildValue("OOO", self, string, maxsplit) - ); - } - #endif - - static PyObject* pattern_findall(PatternObject* self, PyObject* args, PyObject* kw) { --- 1819,1823 ---- *************** *** 1981,1985 **** } - #if !defined(USE_PYTHON_SPLIT) static PyObject* pattern_split(PatternObject* self, PyObject* args, PyObject* kw) --- 1919,1922 ---- *************** *** 2072,2084 **** /* get segment following last match */ ! item = PySequence_GetSlice( ! string, STATE_OFFSET(&state, last), state.endpos ! ); ! if (!item) ! goto error; ! status = PyList_Append(list, item); ! Py_DECREF(item); ! if (status < 0) ! goto error; state_fini(&state); --- 2009,2022 ---- /* get segment following last match */ ! i = STATE_OFFSET(&state, last); ! if (i < state.endpos) { ! item = PySequence_GetSlice(string, i, state.endpos); ! if (!item) ! goto error; ! status = PyList_Append(list, item); ! Py_DECREF(item); ! if (status < 0) ! goto error; ! } state_fini(&state); *************** *** 2091,2097 **** } - #endif - #if !defined(USE_PYTHON_SUB) static PyObject* pattern_subx(PatternObject* self, PyObject* template, PyObject* string, --- 2029,2033 ---- *************** *** 2109,2121 **** int filter_is_callable; ! /* call subx helper to get the filter */ ! filter = call( ! SRE_MODULE, "_subx", ! Py_BuildValue("OO", self, template) ! ); ! if (!filter) ! return NULL; ! ! filter_is_callable = PyCallable_Check(filter); string = state_init(&state, self, string, 0, INT_MAX); --- 2045,2064 ---- int filter_is_callable; ! if (PyCallable_Check(template)) { ! /* sub/subn takes either a function or a template */ ! filter = template; ! Py_INCREF(filter); ! filter_is_callable = 1; ! } else { ! /* if not callable, call the template compiler. it may return ! either a filter function or a literal string */ ! filter = call( ! SRE_MODULE, "_subx", ! Py_BuildValue("OO", self, template) ! ); ! if (!filter) ! return NULL; ! filter_is_callable = PyCallable_Check(filter); ! } string = state_init(&state, self, string, 0, INT_MAX); *************** *** 2170,2174 **** if (filter_is_callable) { ! /* filter match */ match = pattern_new_match(self, &state, 1); if (!match) --- 2113,2117 ---- if (filter_is_callable) { ! /* pass match object through filter */ match = pattern_new_match(self, &state, 1); if (!match) *************** *** 2187,2191 **** /* filter is literal string */ item = filter; ! Py_INCREF(filter); } --- 2130,2134 ---- /* filter is literal string */ item = filter; ! Py_INCREF(item); } *************** *** 2209,2224 **** /* get segment following last match */ ! item = PySequence_GetSlice(string, i, state.endpos); ! if (!item) ! goto error; ! status = PyList_Append(list, item); ! Py_DECREF(item); ! if (status < 0) ! goto error; state_fini(&state); ! /* convert list to single string */ item = join(list, self->pattern); if (!item) return NULL; --- 2152,2170 ---- /* get segment following last match */ ! if (i < state.endpos) { ! item = PySequence_GetSlice(string, i, state.endpos); ! if (!item) ! goto error; ! status = PyList_Append(list, item); ! Py_DECREF(item); ! if (status < 0) ! goto error; ! } state_fini(&state); ! /* convert list to single string (also removes list) */ item = join(list, self->pattern); + if (!item) return NULL; *************** *** 2263,2267 **** return pattern_subx(self, template, string, count, 1); } - #endif static PyObject* --- 2209,2212 ---- From nascheme@users.sourceforge.net Sun Oct 21 23:14:48 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Sun, 21 Oct 2001 15:14:48 -0700 Subject: [Python-checkins] CVS: python/dist/src setup.py,1.61,1.62 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv24271 Modified Files: setup.py Log Message: - Build dbm module using libdb1 if it's available. This fixes SF bug "[ #230075 ] dbmmodule build fails on Debian GNU/Linux unstable (Sid)". - Build bsddb module with libdb3 if it's available. It also fixes a bug that causes the build of bsddb to fail on Debian if bsddb3-dev is installed. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -d -r1.61 -r1.62 *** setup.py 2001/10/17 13:46:44 1.61 --- setup.py 2001/10/21 22:14:44 1.62 *************** *** 363,366 **** --- 363,369 ---- exts.append( Extension('dbm', ['dbmmodule.c'], libraries = ['ndbm'] ) ) + elif self.compiler.find_library_file(lib_dirs, 'db1'): + exts.append( Extension('dbm', ['dbmmodule.c'], + libraries = ['db1'] ) ) else: exts.append( Extension('dbm', ['dbmmodule.c']) ) *************** *** 385,388 **** --- 388,393 ---- if self.compiler.find_library_file(lib_dirs, 'db-3.1'): dblib = ['db-3.1'] + elif self.compiler.find_library_file(lib_dirs, 'db3'): + dblib = ['db3'] elif self.compiler.find_library_file(lib_dirs, 'db2'): dblib = ['db2'] From nascheme@users.sourceforge.net Sun Oct 21 23:24:16 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Sun, 21 Oct 2001 15:24:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules newmodule.c,2.34,2.35 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv25724/Modules Modified Files: newmodule.c Log Message: Adding missing "static" declarations (found by "make smelly"). Index: newmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/newmodule.c,v retrieving revision 2.34 retrieving revision 2.35 diff -C2 -d -r2.34 -r2.35 *** newmodule.c 2001/08/24 06:29:12 2.34 --- newmodule.c 2001/10/21 22:24:14 2.35 *************** *** 216,220 **** }; ! char new_doc[] = "Functions to create new objects used by the interpreter.\n\ \n\ --- 216,220 ---- }; ! static char new_doc[] = "Functions to create new objects used by the interpreter.\n\ \n\ From nascheme@users.sourceforge.net Sun Oct 21 23:26:04 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Sun, 21 Oct 2001 15:26:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules xxsubtype.c,2.7,2.8 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv26004/Modules Modified Files: xxsubtype.c Log Message: Adding missing "static" declarations (found by "make smelly"). Index: xxsubtype.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/xxsubtype.c,v retrieving revision 2.7 retrieving revision 2.8 diff -C2 -d -r2.7 -r2.8 *** xxsubtype.c 2001/09/20 21:45:26 2.7 --- xxsubtype.c 2001/10/21 22:26:02 2.8 *************** *** 198,202 **** }; ! PyObject * spam_bench(PyObject *self, PyObject *args) { --- 198,202 ---- }; ! static PyObject * spam_bench(PyObject *self, PyObject *args) { From nascheme@users.sourceforge.net Sun Oct 21 23:26:45 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Sun, 21 Oct 2001 15:26:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects descrobject.c,2.16,2.17 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv26106/Objects Modified Files: descrobject.c Log Message: Adding missing "static" declarations (found by "make smelly"). Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/descrobject.c,v retrieving revision 2.16 retrieving revision 2.17 diff -C2 -d -r2.16 -r2.17 *** descrobject.c 2001/10/03 12:09:30 2.16 --- descrobject.c 2001/10/21 22:26:43 2.17 *************** *** 674,678 **** } ! PyObject * proxy_str(proxyobject *pp) { --- 674,678 ---- } ! static PyObject * proxy_str(proxyobject *pp) { *************** *** 694,698 **** } ! PyTypeObject proxytype = { PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */ --- 694,698 ---- } ! static PyTypeObject proxytype = { PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */ *************** *** 828,832 **** } ! PyTypeObject wrappertype = { PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */ --- 828,832 ---- } ! static PyTypeObject wrappertype = { PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */ From nascheme@users.sourceforge.net Sun Oct 21 23:27:37 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Sun, 21 Oct 2001 15:27:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects moduleobject.c,2.39,2.40 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv26280/Objects Modified Files: moduleobject.c Log Message: Add missing "static" declarations (found by "make smelly"). Index: moduleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/moduleobject.c,v retrieving revision 2.39 retrieving revision 2.40 diff -C2 -d -r2.39 -r2.40 *** moduleobject.c 2001/10/05 20:51:39 2.39 --- moduleobject.c 2001/10/21 22:27:35 2.40 *************** *** 10,14 **** } PyModuleObject; ! PyMemberDef module_members[] = { {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, {0} --- 10,14 ---- } PyModuleObject; ! static PyMemberDef module_members[] = { {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, {0} From nascheme@users.sourceforge.net Sun Oct 21 23:29:00 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Sun, 21 Oct 2001 15:29:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.110,2.111 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv26592/Objects Modified Files: typeobject.c Log Message: Add missing "static" declarations (found by "make smelly"). Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.110 retrieving revision 2.111 diff -C2 -d -r2.110 -r2.111 *** typeobject.c 2001/10/21 00:44:31 2.110 --- typeobject.c 2001/10/21 22:28:58 2.111 *************** *** 81,85 **** } ! PyGetSetDef type_getsets[] = { {"__name__", (getter)type_name, NULL, NULL}, {"__module__", (getter)type_module, (setter)type_set_module, NULL}, --- 81,85 ---- } ! static PyGetSetDef type_getsets[] = { {"__name__", (getter)type_name, NULL, NULL}, {"__module__", (getter)type_module, (setter)type_set_module, NULL}, *************** *** 372,376 **** as lookup_method to cache the interned name string object. */ ! PyObject * call_method(PyObject *o, char *name, PyObject **nameobj, char *format, ...) { --- 372,376 ---- as lookup_method to cache the interned name string object. */ ! static PyObject * call_method(PyObject *o, char *name, PyObject **nameobj, char *format, ...) { *************** *** 408,412 **** /* Clone of call_method() that returns NotImplemented when the lookup fails. */ ! PyObject * call_maybe(PyObject *o, char *name, PyObject **nameobj, char *format, ...) { --- 408,412 ---- /* Clone of call_method() that returns NotImplemented when the lookup fails. */ ! static PyObject * call_maybe(PyObject *o, char *name, PyObject **nameobj, char *format, ...) { *************** *** 675,679 **** } ! PyGetSetDef subtype_getsets[] = { {"__dict__", subtype_dict, NULL, NULL}, {0}, --- 675,679 ---- } ! static PyGetSetDef subtype_getsets[] = { {"__dict__", subtype_dict, NULL, NULL}, {0}, From nascheme@users.sourceforge.net Sun Oct 21 23:32:07 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Sun, 21 Oct 2001 15:32:07 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.267,1.268 configure.in,1.275,1.276 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv26961 Modified Files: configure configure.in Log Message: install on HP-UX does not support the -d option. Using the install-sh instead. This fixes SF bug: [ #473491 ] "install -d" doesn't work on HP-UX. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.267 retrieving revision 1.268 diff -C2 -d -r1.267 -r1.268 *** configure 2001/10/20 14:21:44 1.267 --- configure 2001/10/21 22:32:04 1.268 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.274 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.275 [...3861 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 < *************** *** 7460,7464 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7463: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 7471,7475 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7474: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.275 retrieving revision 1.276 diff -C2 -d -r1.275 -r1.276 *** configure.in 2001/10/20 14:21:44 1.275 --- configure.in 2001/10/21 22:32:04 1.276 *************** *** 328,333 **** case $MACHDEP in ! bsdos*) ! # install -d does not work on BSDI if test -z "$INSTALL" then --- 328,333 ---- case $MACHDEP in ! bsdos*|hp*|HP*) ! # install -d does not work on BSDI or HP-UX if test -z "$INSTALL" then From pierslauder@users.sourceforge.net Sun Oct 21 23:37:30 2001 From: pierslauder@users.sourceforge.net (Piers Lauder) Date: Sun, 21 Oct 2001 15:37:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib imaplib.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv28252/dist/src/Lib Modified Files: imaplib.py Log Message: update version number Index: imaplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/imaplib.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** imaplib.py 2001/10/21 20:26:37 1.36 --- imaplib.py 2001/10/21 22:37:28 1.37 *************** *** 17,21 **** # GET/SETACL contributed by Anthony Baxter April 2001. ! __version__ = "2.47" import binascii, re, socket, time, random, sys --- 17,21 ---- # GET/SETACL contributed by Anthony Baxter April 2001. ! __version__ = "2.49" import binascii, re, socket, time, random, sys From gstein@users.sourceforge.net Sun Oct 21 23:55:39 2001 From: gstein@users.sourceforge.net (Greg Stein) Date: Sun, 21 Oct 2001 15:55:39 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0268.txt,1.5,1.6 pep-0000.txt,1.136,1.137 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv31437 Modified Files: pep-0268.txt pep-0000.txt Log Message: There is no way that #268 is going to be completed in time for Python 2.2. Move it out to a future release. Index: pep-0268.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0268.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pep-0268.txt 2001/09/11 00:34:48 1.5 --- pep-0268.txt 2001/10/21 22:55:37 1.6 *************** *** 7,11 **** Type: Standards Track Created: 20-Aug-2001 ! Python-Version: 2.2 Post-History: 21-Aug-2001 --- 7,11 ---- Type: Standards Track Created: 20-Aug-2001 ! Python-Version: 2.x Post-History: 21-Aug-2001 *************** *** 184,189 **** Reference Implementation ! reference impl will probably go into /nondist/sandbox/ until ! accepted into the main Lib directory ... --- 184,190 ---- Reference Implementation ! The actual (future/final) implementation is being developed in the ! /nondist/sandbox/Lib directory, until it is accepted and moved ! into the main Lib directory. Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.136 retrieving revision 1.137 diff -C2 -d -r1.136 -r1.137 *** pep-0000.txt 2001/10/18 18:00:50 1.136 --- pep-0000.txt 2001/10/21 22:55:37 1.137 *************** *** 62,66 **** S 265 Sorting Dictionaries by Value Griffin S 267 Optimized Access to Module Namespaces Hylton - S 268 Extended HTTP functionality and WebDAV Stein S 269 Pgen Module for Python Riehl S 270 uniq method for list objects Petrone --- 62,65 ---- *************** *** 87,90 **** --- 86,90 ---- S 254 Making Classes Look More Like Types van Rossum S 266 Optimizing Global Variable/Attribute Access Montanaro + S 268 Extended HTTP functionality and WebDAV Stein Finished PEPs (done, implemented in CVS) From gvanrossum@users.sourceforge.net Mon Oct 22 01:42:28 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 21 Oct 2001 17:42:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib imaplib.py,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv21191 Modified Files: imaplib.py Log Message: Make tabnanny happy. (Piers, please run the test suite before checking in changes. The test suite requires consistent use of spaces and tabs.) Index: imaplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/imaplib.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** imaplib.py 2001/10/21 22:37:28 1.37 --- imaplib.py 2001/10/22 00:42:26 1.38 *************** *** 223,233 **** def send(self, data): """Send data to remote.""" ! bytes = len(data) ! while bytes > 0: ! sent = self.sock.send(data) ! if sent == bytes: ! break # avoid copy ! data = data[sent:] ! bytes = bytes - sent --- 223,233 ---- def send(self, data): """Send data to remote.""" ! bytes = len(data) ! while bytes > 0: ! sent = self.sock.send(data) ! if sent == bytes: ! break # avoid copy ! data = data[sent:] ! bytes = bytes - sent From gvanrossum@users.sourceforge.net Mon Oct 22 01:43:45 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 21 Oct 2001 17:43:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include descrobject.h,2.7,2.8 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv21240/Include Modified Files: descrobject.h Log Message: Methods of built-in types now properly check for keyword arguments (formerly these were silently ignored). The only built-in methods that take keyword arguments are __call__, __init__ and __new__. Index: descrobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/descrobject.h,v retrieving revision 2.7 retrieving revision 2.8 diff -C2 -d -r2.7 -r2.8 *** descrobject.h 2001/10/21 00:44:31 2.7 --- descrobject.h 2001/10/22 00:43:43 2.8 *************** *** 15,18 **** --- 15,21 ---- void *wrapped); + typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args, + void *wrapped, PyObject *kwds); + struct wrapperbase { char *name; *************** *** 21,26 **** --- 24,33 ---- wrapperfunc wrapper; char *doc; + int flags; PyObject *name_strobj; }; + + /* Flags for above struct */ + #define PyWrapperFlag_KEYWORDS 1 /* wrapper function takes keyword args */ /* Various kinds of descriptor objects */ From gvanrossum@users.sourceforge.net Mon Oct 22 01:43:45 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 21 Oct 2001 17:43:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.91,1.92 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21240/Lib/test Modified Files: test_descr.py Log Message: Methods of built-in types now properly check for keyword arguments (formerly these were silently ignored). The only built-in methods that take keyword arguments are __call__, __init__ and __new__. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.91 retrieving revision 1.92 diff -C2 -d -r1.91 -r1.92 *** test_descr.py 2001/10/18 15:49:21 1.91 --- test_descr.py 2001/10/22 00:43:43 1.92 *************** *** 2341,2344 **** --- 2341,2352 ---- capture.close() + def kwdargs(): + if verbose: print "Testing keyword arguments to __init__, __call__..." + def f(a): return a + vereq(f.__call__(a=42), 42) + a = [] + list.__init__(a, sequence=[0, 1, 2]) + vereq(a, [0, 1, 2]) + def test_main(): class_docstrings() *************** *** 2390,2393 **** --- 2398,2402 ---- buffer_inherit() str_of_str_subclass() + kwdargs() if verbose: print "All OK" From gvanrossum@users.sourceforge.net Mon Oct 22 01:43:45 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 21 Oct 2001 17:43:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.292,1.293 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv21240/Misc Modified Files: NEWS Log Message: Methods of built-in types now properly check for keyword arguments (formerly these were silently ignored). The only built-in methods that take keyword arguments are __call__, __init__ and __new__. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.292 retrieving revision 1.293 diff -C2 -d -r1.292 -r1.293 *** NEWS 2001/10/19 17:55:30 1.292 --- NEWS 2001/10/22 00:43:43 1.293 *************** *** 5,8 **** --- 5,12 ---- Type/class unification and new-style classes + - Methods of built-in types now properly check for keyword arguments + (formerly these were silently ignored). The only built-in methods + that take keyword arguments are __call__, __init__ and __new__. + Core and builtins From gvanrossum@users.sourceforge.net Mon Oct 22 01:43:46 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 21 Oct 2001 17:43:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects descrobject.c,2.17,2.18 typeobject.c,2.111,2.112 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv21240/Objects Modified Files: descrobject.c typeobject.c Log Message: Methods of built-in types now properly check for keyword arguments (formerly these were silently ignored). The only built-in methods that take keyword arguments are __call__, __init__ and __new__. Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/descrobject.c,v retrieving revision 2.17 retrieving revision 2.18 diff -C2 -d -r2.17 -r2.18 *** descrobject.c 2001/10/21 22:26:43 2.17 --- descrobject.c 2001/10/22 00:43:43 2.18 *************** *** 806,809 **** --- 806,820 ---- PyObject *self = wp->self; + if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) { + wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper; + return (*wk)(self, args, wp->descr->d_wrapped, kwds); + } + + if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_Size(kwds) != 0)) { + PyErr_Format(PyExc_TypeError, + "wrapper %s doesn't take keyword arguments", + wp->descr->d_base->name); + return NULL; + } return (*wrapper)(self, args, wp->descr->d_wrapped); } Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.111 retrieving revision 2.112 diff -C2 -d -r2.111 -r2.112 *** typeobject.c 2001/10/21 22:28:58 2.111 --- typeobject.c 2001/10/22 00:43:43 2.112 *************** *** 2252,2261 **** static PyObject * ! wrap_call(PyObject *self, PyObject *args, void *wrapped) { ternaryfunc func = (ternaryfunc)wrapped; ! /* XXX What about keyword arguments? */ ! return (*func)(self, args, NULL); } --- 2252,2260 ---- static PyObject * ! wrap_call(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds) { ternaryfunc func = (ternaryfunc)wrapped; ! return (*func)(self, args, kwds); } *************** *** 2329,2338 **** static PyObject * ! wrap_init(PyObject *self, PyObject *args, void *wrapped) { initproc func = (initproc)wrapped; ! /* XXX What about keyword arguments? */ ! if (func(self, args, NULL) < 0) return NULL; Py_INCREF(Py_None); --- 2328,2336 ---- static PyObject * ! wrap_init(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds) { initproc func = (initproc)wrapped; ! if (func(self, args, kwds) < 0) return NULL; Py_INCREF(Py_None); *************** *** 3178,3181 **** --- 3176,3180 ---- #undef TPSLOT + #undef FLSLOT #undef ETSLOT #undef SQSLOT *************** *** 3189,3192 **** --- 3188,3194 ---- #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, DOC} + #define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \ + {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ + DOC, FLAGS} #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ {NAME, offsetof(etype, SLOT), (void *)(FUNCTION), WRAPPER, DOC} *************** *** 3347,3352 **** TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, "x.__hash__() <==> hash(x)"), ! TPSLOT("__call__", tp_call, slot_tp_call, wrap_call, ! "x.__call__(...) <==> x(...)"), TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"), --- 3349,3354 ---- TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, "x.__hash__() <==> hash(x)"), ! FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call, ! "x.__call__(...) <==> x(...)", PyWrapperFlag_KEYWORDS), TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"), *************** *** 3380,3388 **** TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, "descr.__set__(obj, value)"), ! TPSLOT("__init__", tp_init, slot_tp_init, wrap_init, "x.__init__(...) initializes x; " ! "see x.__class__.__doc__ for signature"), ! TPSLOT("__new__", tp_new, slot_tp_new, NULL, ! ""), {NULL} }; --- 3382,3390 ---- TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, "descr.__set__(obj, value)"), ! FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init, "x.__init__(...) initializes x; " ! "see x.__class__.__doc__ for signature", ! PyWrapperFlag_KEYWORDS), ! TPSLOT("__new__", tp_new, slot_tp_new, NULL, ""), {NULL} }; From akuchling@users.sourceforge.net Mon Oct 22 02:47:29 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Sun, 21 Oct 2001 18:47:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.293,1.294 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv31614 Modified Files: NEWS Log Message: Fix some typos Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.293 retrieving revision 1.294 diff -C2 -d -r1.293 -r1.294 *** NEWS 2001/10/22 00:43:43 1.293 --- NEWS 2001/10/22 01:47:26 1.294 *************** *** 68,72 **** - Weak reference objects are now part of the core and offers a C API. A bug which could allow a core dump when binary operations involved ! proxy reference has been fixed. weekref.ReferenceError is now a built-in exception. --- 68,72 ---- - Weak reference objects are now part of the core and offers a C API. A bug which could allow a core dump when binary operations involved ! proxy reference has been fixed. weakref.ReferenceError is now a built-in exception. *************** *** 280,284 **** - For new-style classes, what was previously called __getattr__ is now called __getattribute__. This method, if defined, is called for ! *every* attribute access. A new __getattr__ hook mor similar to the one in classic classes is defined which is called only if regular attribute access raises AttributeError; to catch *all* attribute --- 280,284 ---- - For new-style classes, what was previously called __getattr__ is now called __getattribute__. This method, if defined, is called for ! *every* attribute access. A new __getattr__ hook more similar to the one in classic classes is defined which is called only if regular attribute access raises AttributeError; to catch *all* attribute *************** *** 324,329 **** objects. ! - PyFile_WriteObject now passes Unicode object to the file's write ! method. As a result, all file-like object which may be the target of a print statement must support Unicode objects, i.e. they must at least convert them into ASCII strings. --- 324,329 ---- objects. ! - PyFile_WriteObject now passes Unicode objects to the file's write ! method. As a result, all file-like objects which may be the target of a print statement must support Unicode objects, i.e. they must at least convert them into ASCII strings. From gvanrossum@users.sourceforge.net Mon Oct 22 03:00:11 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 21 Oct 2001 19:00:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_funcattrs.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv1010/Lib/test Modified Files: test_funcattrs.py Log Message: Fix for SF bug #472940: can't getattr() attribute shown by dir() There really isn't a good reason for instance method objects to have their own __dict__, __doc__ and __name__ properties that just delegate the request to the function (callable); the default attribute behavior already does this. The test suite had to be fixed because the error changes from TypeError to AttributeError. Index: test_funcattrs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_funcattrs.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** test_funcattrs.py 2001/09/18 03:55:22 1.10 --- test_funcattrs.py 2001/10/22 02:00:09 1.11 *************** *** 109,114 **** try: F.a.__dict__ = (1, 2, 3) ! except TypeError: pass ! else: raise TestFailed, 'expected TypeError' F.a.im_func.__dict__ = {'one': 11, 'two': 22, 'three': 33} --- 109,114 ---- try: F.a.__dict__ = (1, 2, 3) ! except (AttributeError, TypeError): pass ! else: raise TestFailed, 'expected TypeError or AttributeError' F.a.im_func.__dict__ = {'one': 11, 'two': 22, 'three': 33} *************** *** 122,126 **** try: F.a.__dict__ = d ! except TypeError: pass else: raise TestFailed --- 122,126 ---- try: F.a.__dict__ = d ! except (AttributeError, TypeError): pass else: raise TestFailed *************** *** 219,223 **** try: setattr(obj, name, value) ! except TypeError: pass else: --- 219,223 ---- try: setattr(obj, name, value) ! except (AttributeError, TypeError): pass else: *************** *** 225,229 **** try: delattr(obj, name) ! except TypeError: pass else: --- 225,229 ---- try: delattr(obj, name) ! except (AttributeError, TypeError): pass else: From gvanrossum@users.sourceforge.net Mon Oct 22 03:00:12 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 21 Oct 2001 19:00:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects classobject.c,2.152,2.153 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv1010/Objects Modified Files: classobject.c Log Message: Fix for SF bug #472940: can't getattr() attribute shown by dir() There really isn't a good reason for instance method objects to have their own __dict__, __doc__ and __name__ properties that just delegate the request to the function (callable); the default attribute behavior already does this. The test suite had to be fixed because the error changes from TypeError to AttributeError. Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.152 retrieving revision 2.153 diff -C2 -d -r2.152 -r2.153 *** classobject.c 2001/10/17 20:26:38 2.152 --- classobject.c 2001/10/22 02:00:09 2.153 *************** *** 2020,2050 **** }; - /* __dict__, __doc__ and __name__ are retrieved from im_func */ - - static PyObject * - im_get_dict(PyMethodObject *im) - { - return PyObject_GetAttrString(im->im_func, "__dict__"); - } - - static PyObject * - im_get_doc(PyMethodObject *im) - { - return PyObject_GetAttrString(im->im_func, "__doc__"); - } - - static PyObject * - im_get_name(PyMethodObject *im) - { - return PyObject_GetAttrString(im->im_func, "__name__"); - } - - static PyGetSetDef instancemethod_getsetlist[] = { - {"__dict__", (getter)im_get_dict, NULL, "same as im_func.__dict__"}, - {"__doc__", (getter)im_get_doc, NULL, "same as im_func.__doc__"}, - {"__name__", (getter)im_get_name, NULL, "same as im_func.__name__"}, - {NULL} /* Sentinel */ - }; - /* The getattr() implementation for PyMethod objects is similar to PyObject_GenericGetAttr(), but instead of looking in __dict__ it --- 2020,2023 ---- *************** *** 2351,2355 **** 0, /* tp_methods */ instancemethod_memberlist, /* tp_members */ ! instancemethod_getsetlist, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ --- 2324,2328 ---- 0, /* tp_methods */ instancemethod_memberlist, /* tp_members */ ! 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ From akuchling@users.sourceforge.net Mon Oct 22 03:10:31 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Sun, 21 Oct 2001 19:10:31 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0247.txt,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv2895 Modified Files: pep-0247.txt Log Message: Add rationale section Index: pep-0247.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0247.txt,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** pep-0247.txt 2001/10/09 21:13:07 1.7 --- pep-0247.txt 2001/10/22 02:10:29 1.8 *************** *** 116,119 **** --- 116,137 ---- + Rationale + + The digest size is measured in bytes, not bits, even though hash + algorithm sizes are usually quoted in bits; MD5 is a 128-bit + algorithm and not a 16-byte one, for example. This is because, in + the sample code I looked at, the length in bytes is often needed + (to seek ahead or behind in a file; to compute the length of an + output string) while the length in bits is rarely used. + Therefore, the burden will fall on the few people actually needing + the size in bits, who will have to multiply digest_size by 8. + + It's been suggested that the update() method would be better named + append(). However, that method is really causing the current + state of the hashing object to be updated, and update() is already + used by the md5 and sha modules included with Python, so it seems + simplest to leave the name update() alone. + + Changes From gvanrossum@users.sourceforge.net Mon Oct 22 05:12:46 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 21 Oct 2001 21:12:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.85,2.86 stringobject.c,2.139,2.140 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv15936/Objects Modified Files: abstract.c stringobject.c Log Message: Make the error message for unsupported operand types cleaner, in response to a message by Laura Creighton on c.l.py. E.g. >>> 0+'' TypeError: unsupported operand types for +: 'int' and 'str' (previously this did not mention the operand types) >>> ''+0 TypeError: cannot concatenate 'str' and 'int' objects Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.85 retrieving revision 2.86 diff -C2 -d -r2.85 -r2.86 *** abstract.c 2001/10/18 03:18:43 2.85 --- abstract.c 2001/10/22 04:12:44 2.86 *************** *** 384,389 **** if (result == Py_NotImplemented) { Py_DECREF(Py_NotImplemented); ! PyErr_Format(PyExc_TypeError, ! "unsupported operand type(s) for %s", op_name); return NULL; } --- 384,393 ---- if (result == Py_NotImplemented) { Py_DECREF(Py_NotImplemented); ! PyErr_Format( ! PyExc_TypeError, ! "unsupported operand type(s) for %s: '%s' and '%s'", ! op_name, ! v->ob_type->tp_name, ! w->ob_type->tp_name); return NULL; } *************** *** 534,540 **** return x; } ! ! PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for %s", ! op_name); return NULL; } --- 538,557 ---- return x; } ! ! if (z == Py_None) ! PyErr_Format( ! PyExc_TypeError, ! "unsupported operand type(s) for ** or pow(): " ! "'%s' and '%s'", ! v->ob_type->tp_name, ! w->ob_type->tp_name); ! else ! PyErr_Format( ! PyExc_TypeError, ! "unsupported operand type(s) for pow(): " ! "'%s', '%s', '%s'", ! v->ob_type->tp_name, ! w->ob_type->tp_name, ! z->ob_type->tp_name); return NULL; } *************** *** 567,572 **** } else { ! PyErr_SetString(PyExc_TypeError, ! "unsupported operand types for +"); result = NULL; } --- 584,592 ---- } else { ! PyErr_Format( ! PyExc_TypeError, ! "unsupported operand types for +: '%s' and '%s'", ! v->ob_type->tp_name, ! w->ob_type->tp_name); result = NULL; } Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.139 retrieving revision 2.140 diff -C2 -d -r2.139 -r2.140 *** stringobject.c 2001/10/16 20:18:24 2.139 --- stringobject.c 2001/10/22 04:12:44 2.140 *************** *** 692,696 **** #endif PyErr_Format(PyExc_TypeError, ! "cannot add type \"%.200s\" to string", bb->ob_type->tp_name); return NULL; --- 692,696 ---- #endif PyErr_Format(PyExc_TypeError, ! "cannot concatenate 'str' and '%.200s' objects", bb->ob_type->tp_name); return NULL; From effbot@users.sourceforge.net Mon Oct 22 07:01:58 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Sun, 21 Oct 2001 23:01:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_sre.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12593/Lib/test Modified Files: test_sre.py Log Message: sre.split should return the last segment, even if empty (sorry, barry) Index: test_sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sre.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** test_sre.py 2001/10/21 18:04:11 1.31 --- test_sre.py 2001/10/22 06:01:56 1.32 *************** *** 156,159 **** --- 156,160 ---- test(r"""sre.split(r":", ":a:b::c")""", ['', 'a', 'b', '', 'c']) + test(r"""sre.split(r":+", ":a:b:::")""", ['', 'a', 'b', '']) test(r"""sre.split(r":*", ":a:b::c")""", ['', 'a', 'b', 'c']) test(r"""sre.split(r"(:*)", ":a:b::c")""", ['', ':', 'a', ':', 'b', '::', 'c']) From effbot@users.sourceforge.net Mon Oct 22 07:01:58 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Sun, 21 Oct 2001 23:01:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.71,2.72 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv12593/Modules Modified Files: _sre.c Log Message: sre.split should return the last segment, even if empty (sorry, barry) Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.71 retrieving revision 2.72 diff -C2 -d -r2.71 -r2.72 *** _sre.c 2001/10/21 21:48:30 2.71 --- _sre.c 2001/10/22 06:01:56 2.72 *************** *** 2008,2022 **** } ! /* get segment following last match */ ! i = STATE_OFFSET(&state, last); ! if (i < state.endpos) { ! item = PySequence_GetSlice(string, i, state.endpos); ! if (!item) ! goto error; ! status = PyList_Append(list, item); ! Py_DECREF(item); ! if (status < 0) ! goto error; ! } state_fini(&state); --- 2008,2021 ---- } ! /* get segment following last match (even if empty) */ ! item = PySequence_GetSlice( ! string, STATE_OFFSET(&state, last), state.endpos ! ); ! if (!item) ! goto error; ! status = PyList_Append(list, item); ! Py_DECREF(item); ! if (status < 0) ! goto error; state_fini(&state); From fdrake@users.sourceforge.net Mon Oct 22 15:18:25 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 22 Oct 2001 07:18:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libresource.tex,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv14071/lib Modified Files: libresource.tex Log Message: Clarify that the resource module does not attempt to mask platform differences by defining symbols not defined on particular platforms. This closes SF bug #473433. Index: libresource.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libresource.tex,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** libresource.tex 2001/10/04 20:40:07 1.15 --- libresource.tex 2001/10/22 14:18:23 1.16 *************** *** 68,72 **** The \UNIX{} man page for \manpage{getrlimit}{2} lists the available resources. Note that not all systems use the same symbol or same ! value to denote the same resource. \begin{datadesc}{RLIMIT_CORE} --- 68,74 ---- The \UNIX{} man page for \manpage{getrlimit}{2} lists the available resources. Note that not all systems use the same symbol or same ! value to denote the same resource. This module does not attempt to ! mask platform differences --- symbols not defined for a platform will ! not be available from this module on that platform. \begin{datadesc}{RLIMIT_CORE} From fdrake@users.sourceforge.net Mon Oct 22 15:25:14 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 22 Oct 2001 07:25:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libresource.tex,1.13,1.13.12.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv15768 Modified Files: Tag: release21-maint libresource.tex Log Message: Clarify that the resource module does not attempt to mask platform differences by defining symbols not defined on particular platforms. This closes SF bug #473433. Index: libresource.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libresource.tex,v retrieving revision 1.13 retrieving revision 1.13.12.1 diff -C2 -d -r1.13 -r1.13.12.1 *** libresource.tex 1999/03/02 17:03:40 1.13 --- libresource.tex 2001/10/22 14:25:12 1.13.12.1 *************** *** 68,72 **** The \UNIX{} man page for \manpage{getrlimit}{2} lists the available resources. Note that not all systems use the same symbol or same ! value to denote the same resource. \begin{datadesc}{RLIMIT_CORE} --- 68,74 ---- The \UNIX{} man page for \manpage{getrlimit}{2} lists the available resources. Note that not all systems use the same symbol or same ! value to denote the same resource. This module does not attempt to ! mask platform differences --- symbols not defined for a platform will ! not be available from this module on that platform. \begin{datadesc}{RLIMIT_CORE} From fdrake@users.sourceforge.net Mon Oct 22 16:07:18 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 22 Oct 2001 08:07:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools support.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools In directory usw-pr-cvs1:/tmp/cvs-serv335/tools Modified Files: support.py Log Message: Do a little bit more to try and add elements to the header, not that Mozilla 0.9.5 can make intelligent use of them. Specifically, this causes the "Acknowledgements" and "Global Module Index" pages to acquire "up" links in the Mozilla "Site Navigation Bar". This partially responds to SF bug #469772. Index: support.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/support.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** support.py 2001/02/12 15:30:22 1.3 --- support.py 2001/10/22 15:07:16 1.4 *************** *** 88,92 **** def get_header(self): ! return HEAD % self.variables def get_footer(self): --- 88,101 ---- def get_header(self): ! s = HEAD % self.variables ! if self.uplink: ! if self.uptitle: ! link = ('' ! % (self.uplink, self.uptitle)) ! else: ! link = '' % self.uplink ! repl = " %s\n" % link ! s = s.replace("", repl, 1) ! return s def get_footer(self): From akuchling@users.sourceforge.net Mon Oct 22 16:26:11 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Mon, 22 Oct 2001 08:26:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_curses.py,NONE,1.1 regrtest.py,1.61,1.62 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv6547 Modified Files: regrtest.py Added Files: test_curses.py Log Message: Patch #473187: Add a test script that exercises most of the functions in the curses module. It's not run automatically; '-u curses' must be specified as an argument to regrtest --- NEW FILE: test_curses.py --- # # Test script for the curses module # # This script doesn't actually display anything very coherent. but it # does call every method and function. # # Functions not tested: {def,reset}_{shell,prog}_mode, getch(), getstr(), # getmouse(), ungetmouse(), init_color() # import curses, sys, tempfile # Optionally test curses module. This currently requires that the # 'curses' resource be given on the regrtest command line using the -u # option. If not available, nothing after this line will be executed. import test_support test_support.requires('curses') def window_funcs(stdscr): "Test the methods of windows" win = curses.newwin(10,10) win = curses.newwin(5,5, 5,5) win2 = curses.newwin(15,15, 5,5) for meth in [stdscr.addch, stdscr.addstr]: for args in [('a'), ('a', curses.A_BOLD), (4,4, 'a'), (5,5, 'a', curses.A_BOLD)]: apply(meth, args) for meth in [stdscr.box, stdscr.clear, stdscr.clrtobot, stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch, stdscr.deleteln, stdscr.erase, stdscr.getbegyx, stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx, stdscr.getparyx, stdscr.getyx, stdscr.inch, stdscr.insertln, stdscr.instr, stdscr.is_wintouched, win.noutrefresh, stdscr.redrawwin, stdscr.refresh, stdscr.standout, stdscr.standend, stdscr.syncdown, stdscr.syncup, stdscr.touchwin, stdscr.untouchwin]: meth() stdscr.addnstr('1234', 3) stdscr.addnstr('1234', 3, curses.A_BOLD) stdscr.addnstr(4,4, '1234', 3) stdscr.addnstr(5,5, '1234', 3, curses.A_BOLD) stdscr.attron(curses.A_BOLD) stdscr.attroff(curses.A_BOLD) stdscr.attrset(curses.A_BOLD) stdscr.bkgd(' ') stdscr.bkgd(' ', curses.A_REVERSE) stdscr.bkgdset(' ') stdscr.bkgdset(' ', curses.A_REVERSE) win.border(65, 66, 67, 68, 69, 70, 71, 72) win.border('|', '!', '-', '_', '+', '\\', '#', '/') try: win.border(65, 66, 67, 68, 69, [], 71, 72) except TypeError: pass else: raise RuntimeError, "Expected win.border() to raise TypeError" stdscr.clearok(1) win4 = stdscr.derwin(2,2) win4 = stdscr.derwin(1,1, 5,5) win4.mvderwin(9,9) stdscr.echochar('a') stdscr.echochar('a', curses.A_BOLD) stdscr.hline('-', 5) stdscr.hline('-', 5, curses.A_BOLD) stdscr.hline(1,1,'-', 5) stdscr.hline(1,1,'-', 5, curses.A_BOLD) stdscr.idcok(1) stdscr.idlok(1) stdscr.immedok(1) stdscr.insch('c') stdscr.insdelln(1) stdscr.insnstr('abc', 3) stdscr.insnstr('abc', 3, curses.A_BOLD) stdscr.insnstr(5, 5, 'abc', 3) stdscr.insnstr(5, 5, 'abc', 3, curses.A_BOLD) stdscr.insstr('def') stdscr.insstr('def', curses.A_BOLD) stdscr.insstr(5, 5, 'def') stdscr.insstr(5, 5, 'def', curses.A_BOLD) stdscr.is_linetouched(0) stdscr.keypad(1) stdscr.leaveok(1) stdscr.move(3,3) win.mvwin(2,2) stdscr.nodelay(1) stdscr.notimeout(1) win2.overlay(win) win2.overwrite(win) stdscr.redrawln(1,2) stdscr.scrollok(1) stdscr.scroll() stdscr.scroll(2) stdscr.scroll(-3) stdscr.setscrreg(10,15) win3 = stdscr.subwin(10,10) win3 = stdscr.subwin(10,10, 5,5) stdscr.syncok(1) stdscr.timeout(5) stdscr.touchline(5,5) stdscr.touchline(5,5,0) stdscr.vline('a', 3) stdscr.vline('a', 3, curses.A_STANDOUT) stdscr.vline(1,1, 'a', 3) stdscr.vline(1,1, 'a', 3, curses.A_STANDOUT) if hasattr(curses, 'resize'): stdscr.resize() if hasattr(curses, 'enclose'): stdscr.enclose() def module_funcs(stdscr): "Test module-level functions" for func in [curses.baudrate, curses.beep, curses.can_change_color, curses.cbreak, curses.def_prog_mode, curses.doupdate, curses.filter, curses.flash, curses.flushinp, curses.has_colors, curses.has_ic, curses.has_il, curses.isendwin, curses.killchar, curses.longname, curses.nocbreak, curses.noecho, curses.nonl, curses.noqiflush, curses.noraw, curses.reset_prog_mode, curses.termattrs, curses.termname, curses.erasechar, curses.getsyx]: func() # Functions that actually need arguments curses.curs_set(1) curses.delay_output(1) curses.echo() ; curses.echo(1) f = tempfile.TemporaryFile() stdscr.putwin(f) f.seek(0) curses.getwin(f) f.close() curses.halfdelay(1) curses.intrflush(1) curses.meta(1) curses.napms(100) curses.newpad(50,50) win = curses.newwin(5,5) win = curses.newwin(5,5, 1,1) curses.nl() ; curses.nl(1) curses.putp('abc') curses.qiflush() curses.raw() ; curses.raw(1) curses.setsyx(5,5) curses.setupterm(fd=sys.__stdout__.fileno()) curses.tigetflag('hc') curses.tigetnum('co') curses.tigetstr('cr') curses.tparm('cr') curses.typeahead(sys.__stdin__.fileno()) curses.unctrl('a') curses.ungetch('a') curses.use_env(1) # Functions only available on a few platforms if curses.has_colors(): curses.start_color() curses.init_pair(2, 1,1) curses.color_content(1) curses.color_pair(2) curses.pair_content(curses.COLOR_PAIRS) curses.pair_number(0) if hasattr(curses, 'keyname'): curses.keyname(13) if hasattr(curses, 'has_key'): curses.has_key(13) if hasattr(curses, 'getmouse'): curses.mousemask(curses.BUTTON1_PRESSED) curses.mouseinterval(10) def main(stdscr): curses.savetty() try: module_funcs(stdscr) window_funcs(stdscr) finally: curses.resetty() if __name__ == '__main__': curses.wrapper(main) else: try: stdscr = curses.initscr() main(stdscr) finally: curses.endwin() Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -d -r1.61 -r1.62 *** regrtest.py 2001/10/18 21:57:37 1.61 --- regrtest.py 2001/10/22 15:26:09 1.62 *************** *** 37,40 **** --- 37,43 ---- only the following are defined: + curses - Tests that use curses and will modify the terminal's + state and output modes. + largefile - It is okay to run some test that may create huge files. These tests can take a long time and may consume >2GB of disk space *************** *** 119,123 **** u = [x.lower() for x in a.split(',')] for r in u: ! if r not in ('largefile', 'network'): usage(1, 'Invalid -u/--use option: %s' % a) use_resources.extend(u) --- 122,126 ---- u = [x.lower() for x in a.split(',')] for r in u: ! if r not in ('curses', 'largefile', 'network'): usage(1, 'Invalid -u/--use option: %s' % a) use_resources.extend(u) From jhylton@users.sourceforge.net Mon Oct 22 17:30:38 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Mon, 22 Oct 2001 09:30:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.158,2.159 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv31437 Modified Files: object.c Log Message: cleanup indentation Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.158 retrieving revision 2.159 diff -C2 -d -r2.158 -r2.159 *** object.c 2001/10/19 02:01:31 2.158 --- object.c 2001/10/22 16:30:36 2.159 *************** *** 733,737 **** if (PyOS_CheckStack()) { PyErr_SetString(PyExc_MemoryError, "Stack overflow"); ! return -1; } #endif --- 733,737 ---- if (PyOS_CheckStack()) { PyErr_SetString(PyExc_MemoryError, "Stack overflow"); ! return -1; } #endif From jhylton@users.sourceforge.net Mon Oct 22 17:31:42 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Mon, 22 Oct 2001 09:31:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects weakrefobject.c,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv31673 Modified Files: weakrefobject.c Log Message: Referencable is not a word, so don't use it in an error message . Index: weakrefobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/weakrefobject.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** weakrefobject.c 2001/10/18 19:21:46 1.3 --- weakrefobject.c 2001/10/22 16:31:40 1.4 *************** *** 559,563 **** if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) { PyErr_Format(PyExc_TypeError, ! "'%s' objects are not weakly referencable", ob->ob_type->tp_name); return NULL; --- 559,563 ---- if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) { PyErr_Format(PyExc_TypeError, ! "cannot create weak reference to '%s' object", ob->ob_type->tp_name); return NULL; *************** *** 603,607 **** if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) { PyErr_Format(PyExc_TypeError, ! "'%s' objects are not weakly referencable", ob->ob_type->tp_name); return NULL; --- 603,607 ---- if (!PyType_SUPPORTS_WEAKREFS(ob->ob_type)) { PyErr_Format(PyExc_TypeError, ! "cannot create weak reference to '%s' object", ob->ob_type->tp_name); return NULL; From akuchling@users.sourceforge.net Mon Oct 22 17:37:12 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Mon, 22 Oct 2001 09:37:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.294,1.295 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv1215 Modified Files: NEWS Log Message: Add curses-related news items Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.294 retrieving revision 1.295 diff -C2 -d -r1.294 -r1.295 *** NEWS 2001/10/22 01:47:26 1.294 --- NEWS 2001/10/22 16:37:10 1.295 *************** *** 13,16 **** --- 13,18 ---- Extension modules + - Various bugfixes to the curses module. + Library *************** *** 24,27 **** --- 26,32 ---- Tests + + - Added a test script for the curses module. It isn't run automatically; + regrtest.py must be run with '-u curses' to enable it. Windows From fdrake@users.sourceforge.net Mon Oct 22 17:57:51 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 22 Oct 2001 09:57:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/perl l2hinit.perl,1.55,1.56 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory usw-pr-cvs1:/tmp/cvs-serv7714/perl Modified Files: l2hinit.perl Log Message: Add better support for Mozilla's use of elements. Index: l2hinit.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/l2hinit.perl,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** l2hinit.perl 2001/08/10 20:12:09 1.55 --- l2hinit.perl 2001/10/22 16:57:49 1.56 *************** *** 34,37 **** --- 34,41 ---- $MODULE_INDEX_COLUMNS = 4; + $HAVE_MODULE_INDEX = 0; + $HAVE_GENERAL_INDEX = 0; + $HAVE_TABLE_OF_CONTENTS = 0; + # A little painful, but lets us clean up the top level directory a little, *************** *** 477,480 **** --- 481,487 ---- my $id = $global{'max_id'}; + if (/[\\]tableofcontents/) { + $HAVE_TABLE_OF_CONTENTS = 1; + } s/([\\]begin\s*$O\d+$C\s*thebibliography)/$bbl_cnt++; $1/eg; s/([\\]begin\s*$O\d+$C\s*thebibliography)/$id++; "\\bibliography$O$id$C$O$id$C $1"/geo; *************** *** 491,494 **** --- 498,506 ---- . get_my_icon('modules') . ''); + $HAVE_MODULE_INDEX = 1; + $HAVE_GENERAL_INDEX = 1; + } + elsif (scalar(@parts) == 2) { + $HAVE_GENERAL_INDEX = 1; } else { *************** *** 555,558 **** --- 567,571 ---- # doctype declaration; MSIE5 on NT4 SP4 barfs on it and drops the # content of the page. + $MY_PARTIAL_HEADER = ''; sub make_head_and_body { my($title, $body) = @_; *************** *** 580,597 **** . ($ISO_LANGUAGE ? $ISO_LANGUAGE : $isolanguage) . "\">\n"; } - $STYLESHEET = $FILE.".css" unless $STYLESHEET; if (!$charset && $CHARSET) { $charset = $CHARSET; $charset =~ s/_/\-/go; } join('', ($DOCTYPE ? $DTDcomment : '' ) ! ,"\n\n", $title, "\n" ! , &meta_information($title) ! , ($CHARSET && $HTML_VERSION ge "2.1" ? ! "\n" ! : "" ) ! , ($BASE ? "\n" : "" ) ! , "" ! , $more_links_mark ! , "\n\n"); } --- 593,628 ---- . ($ISO_LANGUAGE ? $ISO_LANGUAGE : $isolanguage) . "\">\n"; } + if ($MY_PARTIAL_HEADER eq '') { + $STYLESHEET = $FILE.".css" unless $STYLESHEET; + $MY_PARTIAL_HEADER = join('', + ($CHARSET && $HTML_VERSION ge "2.1" + ? ('\n") + : ''), + ($BASE ? "\n" : ''), + "\n", + "\n", + ($HAVE_TABLE_OF_CONTENTS + ? ('' + . "\n") + : ''), + ($HAVE_GENERAL_INDEX + ? '' + : ''), + # disable for now -- Mozilla doesn't do well with multiple indexes + # ($HAVE_MODULE_INDEX + # ? '' + # . "\n" + # : ''), + $more_links_mark); + } if (!$charset && $CHARSET) { $charset = $CHARSET; $charset =~ s/_/\-/go; } join('', ($DOCTYPE ? $DTDcomment : '' ) ! , "\n\n", $title, "\n" ! , &meta_information($title) ! , $MY_PARTIAL_HEADER ! , "\n\n"); } From jhylton@users.sourceforge.net Mon Oct 22 19:14:17 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Mon, 22 Oct 2001 11:14:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib unittest.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv26978 Modified Files: unittest.py Log Message: A few formatting nits: Don't put paren in column 0 (to please font-lock mode). Put space after comma in argument list. Index: unittest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/unittest.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** unittest.py 2001/09/06 19:13:14 1.11 --- unittest.py 2001/10/22 18:14:15 1.12 *************** *** 7,11 **** specific test cases and suites (TestCase, TestSuite etc.), and also a text-based utility class for running the tests and reporting the results ! (TextTestRunner). Simple usage: --- 7,11 ---- specific test cases and suites (TestCase, TestSuite etc.), and also a text-based utility class for running the tests and reporting the results ! (TextTestRunner). Simple usage: *************** *** 204,208 **** self.setUp() except: ! result.addError(self,self.__exc_info()) return --- 204,208 ---- self.setUp() except: ! result.addError(self, self.__exc_info()) return *************** *** 212,223 **** ok = 1 except self.failureException, e: ! result.addFailure(self,self.__exc_info()) except: ! result.addError(self,self.__exc_info()) try: self.tearDown() except: ! result.addError(self,self.__exc_info()) ok = 0 if ok: result.addSuccess(self) --- 212,223 ---- ok = 1 except self.failureException, e: ! result.addFailure(self, self.__exc_info()) except: ! result.addError(self, self.__exc_info()) try: self.tearDown() except: ! result.addError(self, self.__exc_info()) ok = 0 if ok: result.addSuccess(self) From fdrake@users.sourceforge.net Mon Oct 22 19:41:54 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 22 Oct 2001 11:41:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.295,1.296 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv3563 Modified Files: NEWS Log Message: Added two very tardy notes about the 2.2b1 release, fixed a typo. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.295 retrieving revision 1.296 diff -C2 -d -r1.295 -r1.296 *** NEWS 2001/10/22 16:37:10 1.295 --- NEWS 2001/10/22 18:41:51 1.296 *************** *** 71,75 **** example). ! - Weak reference objects are now part of the core and offers a C API. A bug which could allow a core dump when binary operations involved proxy reference has been fixed. weakref.ReferenceError is now a --- 71,75 ---- example). ! - Weak reference objects are now part of the core and offer a C API. A bug which could allow a core dump when binary operations involved proxy reference has been fixed. weakref.ReferenceError is now a *************** *** 131,134 **** --- 131,139 ---- being tested, thanks to Tim Hochberg. + - HotShot, a new profiler implemented using a C-based callback, has + been added. This substantially reduces the overhead of profiling, + but it is still quite preliminary. Support modules and + documentation will be added in upcoming releases (before 2.2 final). + - profile now produces correct output in situations where an exception raised in Python is cleared by C code (e.g. hasattr()). This used *************** *** 177,180 **** --- 182,188 ---- - ConfigParser.getboolean() now also interprets TRUE, FALSE, YES, NO, ON, and OFF. + + - xml.dom.minidom NodeList objects now support the length attribute + and item() method as required by the DOM specifications. Tools/Demos From fdrake@users.sourceforge.net Mon Oct 22 20:00:57 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 22 Oct 2001 12:00:57 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv8164 Modified Files: pep-0101.txt Log Message: Add a checklist item so that we have GNU Info documentation. Index: pep-0101.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0101.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** pep-0101.txt 2001/10/19 17:10:22 1.8 --- pep-0101.txt 2001/10/22 19:00:55 1.9 *************** *** 110,114 **** This may generate some last minute changes on the branch. Once Fred is done, there can be no further checkins on the branch in ! the Doc/ directory -- not even by the RM. - Tim Peters grabs the HTML and uses this to build the Windows --- 110,116 ---- This may generate some last minute changes on the branch. Once Fred is done, there can be no further checkins on the branch in ! the Doc/ directory -- not even by the RM. For final releases, ! Fred also sends email to Milan Zamazal for conversion to the GNU ! Info format. - Tim Peters grabs the HTML and uses this to build the Windows From tim_one@users.sourceforge.net Mon Oct 22 20:34:12 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 22 Oct 2001 12:34:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python traceback.c,2.32,2.33 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv16872/python/Python Modified Files: traceback.c Log Message: Removed two pointless and obfuscating macros. Index: traceback.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/traceback.c,v retrieving revision 2.32 retrieving revision 2.33 diff -C2 -d -r2.32 -r2.33 *** traceback.c 2000/09/01 23:29:29 2.32 --- traceback.c 2001/10/22 19:34:09 2.33 *************** *** 43,50 **** } ! #define Tracebacktype PyTraceBack_Type ! #define is_tracebackobject PyTraceBack_Check ! ! PyTypeObject Tracebacktype = { PyObject_HEAD_INIT(&PyType_Type) 0, --- 43,47 ---- } ! PyTypeObject PyTraceBack_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, *************** *** 68,77 **** { tracebackobject *tb; ! if ((next != NULL && !is_tracebackobject(next)) || frame == NULL || !PyFrame_Check(frame)) { PyErr_BadInternalCall(); return NULL; } ! tb = PyObject_NEW(tracebackobject, &Tracebacktype); if (tb != NULL) { Py_XINCREF(next); --- 65,74 ---- { tracebackobject *tb; ! if ((next != NULL && !PyTraceBack_Check(next)) || frame == NULL || !PyFrame_Check(frame)) { PyErr_BadInternalCall(); return NULL; } ! tb = PyObject_NEW(tracebackobject, &PyTraceBack_Type); if (tb != NULL) { Py_XINCREF(next); *************** *** 224,228 **** if (v == NULL) return 0; ! if (!is_tracebackobject(v)) { PyErr_BadInternalCall(); return -1; --- 221,225 ---- if (v == NULL) return 0; ! if (!PyTraceBack_Check(v)) { PyErr_BadInternalCall(); return -1; From bwarsaw@users.sourceforge.net Mon Oct 22 21:53:47 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Mon, 22 Oct 2001 13:53:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib emailutil.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv5026 Modified Files: emailutil.tex Log Message: Fixed an example in the use of email.Utils.getaddresses(). The failobj has to be a list or the `+' can fail. Index: emailutil.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailutil.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** emailutil.tex 2001/09/26 22:21:52 1.2 --- emailutil.tex 2001/10/22 20:53:45 1.3 *************** *** 41,48 **** from email.Utils import getaddresses ! tos = msg.get_all('to') ! ccs = msg.get_all('cc') ! resent_tos = msg.get_all('resent-to') ! resent_ccs = msg.get_all('resent-cc') all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs) \end{verbatim} --- 41,48 ---- from email.Utils import getaddresses ! tos = msg.get_all('to', []) ! ccs = msg.get_all('cc', []) ! resent_tos = msg.get_all('resent-to', []) ! resent_ccs = msg.get_all('resent-cc', []) all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs) \end{verbatim} From effbot@users.sourceforge.net Mon Oct 22 22:18:10 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Mon, 22 Oct 2001 14:18:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.72,2.73 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv11996/Modules Modified Files: _sre.c Log Message: another major speedup: let sre.sub/subn check for escapes in the template string, and don't call the template compiler if we can avoid it. Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.72 retrieving revision 2.73 diff -C2 -d -r2.72 -r2.73 *** _sre.c 2001/10/22 06:01:56 2.72 --- _sre.c 2001/10/22 21:18:08 2.73 *************** *** 35,38 **** --- 35,39 ---- * 2001-10-20 fl added split primitive; reenable unicode for 1.6/2.0/2.1 * 2001-10-21 fl added sub/subn primitive + * 2001-10-22 fl check for literal sub/subn templates * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. *************** *** 360,363 **** --- 361,365 ---- #define SRE_MATCH sre_match #define SRE_SEARCH sre_search + #define SRE_LITERAL_TEMPLATE sre_literal_template #if defined(HAVE_UNICODE) *************** *** 367,370 **** --- 369,373 ---- #undef SRE_RECURSIVE + #undef SRE_LITERAL_TEMPLATE #undef SRE_SEARCH #undef SRE_MATCH *************** *** 384,387 **** --- 387,391 ---- #define SRE_MATCH sre_umatch #define SRE_SEARCH sre_usearch + #define SRE_LITERAL_TEMPLATE sre_uliteral_template #endif *************** *** 1283,1286 **** --- 1287,1299 ---- } + LOCAL(int) + SRE_LITERAL_TEMPLATE(SRE_CHAR* ptr, int len) + { + /* check if given string is a literal template (i.e. no escapes) */ + while (len-- > 0) + if (*ptr++ == '\\') + return 0; + return 1; + } #if !defined(SRE_RECURSIVE) *************** *** 1389,1406 **** } ! LOCAL(PyObject*) ! state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string, ! int start, int end) { ! /* prepare state object */ ! PyBufferProcs *buffer; ! int size, bytes; void* ptr; - memset(state, 0, sizeof(SRE_STATE)); - - state->lastindex = -1; - #if defined(HAVE_UNICODE) if (PyUnicode_Check(string)) { --- 1402,1416 ---- } ! static void* ! getstring(PyObject* string, int* p_length, int* p_charsize) { ! /* given a python object, return a data pointer, a length (in ! characters), and a character size. return NULL if the object ! is not a string (or not compatible) */ ! PyBufferProcs *buffer; ! int size, bytes, charsize; void* ptr; #if defined(HAVE_UNICODE) if (PyUnicode_Check(string)) { *************** *** 1409,1413 **** bytes = PyUnicode_GET_DATA_SIZE(string); size = PyUnicode_GET_SIZE(string); ! state->charsize = sizeof(Py_UNICODE); } else { --- 1419,1423 ---- bytes = PyUnicode_GET_DATA_SIZE(string); size = PyUnicode_GET_SIZE(string); ! charsize = sizeof(Py_UNICODE); } else { *************** *** 1437,1444 **** if (PyString_Check(string) || bytes == size) ! state->charsize = 1; #if defined(HAVE_UNICODE) else if (bytes == (int) (size * sizeof(Py_UNICODE))) ! state->charsize = sizeof(Py_UNICODE); #endif else { --- 1447,1454 ---- if (PyString_Check(string) || bytes == size) ! charsize = 1; #if defined(HAVE_UNICODE) else if (bytes == (int) (size * sizeof(Py_UNICODE))) ! charsize = sizeof(Py_UNICODE); #endif else { *************** *** 1451,1465 **** #endif /* adjust boundaries */ if (start < 0) start = 0; ! else if (start > size) ! start = size; if (end < 0) end = 0; ! else if (end > size) ! end = size; state->beginning = ptr; --- 1461,1501 ---- #endif + *p_length = size; + *p_charsize = charsize; + + return ptr; + } + + LOCAL(PyObject*) + state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string, + int start, int end) + { + /* prepare state object */ + + int length; + int charsize; + void* ptr; + + memset(state, 0, sizeof(SRE_STATE)); + + state->lastindex = -1; + + ptr = getstring(string, &length, &charsize); + if (!ptr) + return NULL; + /* adjust boundaries */ if (start < 0) start = 0; ! else if (start > length) ! start = length; if (end < 0) end = 0; ! else if (end > length) ! end = length; + state->charsize = charsize; + state->beginning = ptr; *************** *** 2039,2042 **** --- 2075,2079 ---- PyObject* args; PyObject* match; + void* ptr; int status; int n; *************** *** 2050,2062 **** filter_is_callable = 1; } else { ! /* if not callable, call the template compiler. it may return ! either a filter function or a literal string */ ! filter = call( ! SRE_MODULE, "_subx", ! Py_BuildValue("OO", self, template) ! ); ! if (!filter) ! return NULL; ! filter_is_callable = PyCallable_Check(filter); } --- 2087,2119 ---- filter_is_callable = 1; } else { ! /* if not callable, check if it's a literal string */ ! int literal; ! ptr = getstring(template, &n, &b); ! if (ptr) { ! if (b == 1) { ! literal = sre_literal_template(ptr, n); ! } else { ! #if defined(HAVE_UNICODE) ! literal = sre_uliteral_template(ptr, n); ! #endif ! } ! } else { ! PyErr_Clear(); ! literal = 0; ! } ! if (literal) { ! filter = template; ! Py_INCREF(filter); ! filter_is_callable = 0; ! } else { ! /* not a literal; hand it over to the template compiler */ ! filter = call( ! SRE_MODULE, "_subx", ! Py_BuildValue("OO", self, template) ! ); ! if (!filter) ! return NULL; ! filter_is_callable = PyCallable_Check(filter); ! } } *************** *** 2133,2140 **** /* add to list */ ! status = PyList_Append(list, item); ! Py_DECREF(item); ! if (status < 0) ! goto error; i = e; --- 2190,2199 ---- /* add to list */ ! if (item != Py_None) { ! status = PyList_Append(list, item); ! Py_DECREF(item); ! if (status < 0) ! goto error; ! } i = e; From fdrake@users.sourceforge.net Mon Oct 22 22:45:27 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 22 Oct 2001 14:45:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.92,1.93 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20755 Modified Files: test_descr.py Log Message: Fixed denial-of-weak-ref-support test; Jeremy changed the error message used by the weakref code since he didn't like the word "referencable". Is it really necessary to be more specific than to test for TypeError here, though? Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.92 retrieving revision 1.93 diff -C2 -d -r1.92 -r1.93 *** test_descr.py 2001/10/22 00:43:43 1.92 --- test_descr.py 2001/10/22 21:45:25 1.93 *************** *** 1375,1379 **** weakref.ref(no) except TypeError, msg: ! verify(str(msg).find("weakly") >= 0) else: verify(0, "weakref.ref(no) should be illegal") --- 1375,1379 ---- weakref.ref(no) except TypeError, msg: ! verify(str(msg).find("weak reference") >= 0) else: verify(0, "weakref.ref(no) should be illegal") From guido@python.org Mon Oct 22 22:48:47 2001 From: guido@python.org (Guido van Rossum) Date: Mon, 22 Oct 2001 17:48:47 -0400 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.92,1.93 In-Reply-To: Your message of "Mon, 22 Oct 2001 14:45:27 PDT." References: Message-ID: <200110222148.RAA01790@cj20424-a.reston1.va.home.com> > Fixed denial-of-weak-ref-support test; Jeremy changed the error message > used by the weakref code since he didn't like the word "referencable". > Is it really necessary to be more specific than to test for TypeError here, > though? Usually I'd say no, but since there are so many other reasons why this test could fail with some other TypeError, I think it's a good idea. --Guido van Rossum (home page: http://www.python.org/~guido/) From tim_one@users.sourceforge.net Mon Oct 22 23:06:12 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 22 Oct 2001 15:06:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test regrtest.py,1.62,1.63 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv25850/python/Lib/test Modified Files: regrtest.py Log Message: Record that test_curses doesn't run on win32. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** regrtest.py 2001/10/22 15:26:09 1.62 --- regrtest.py 2001/10/22 22:06:08 1.63 *************** *** 475,478 **** --- 475,479 ---- test_commands test_crypt + test_curses test_dbm test_dl From jhylton@users.sourceforge.net Mon Oct 22 23:17:43 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Mon, 22 Oct 2001 15:17:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python traceback.c,2.33,2.34 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv28124 Modified Files: traceback.c Log Message: Make traceback objects collectable. This should eliminate the traceback returned by sys.exc_info() as a common source of memory leaks. Index: traceback.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/traceback.c,v retrieving revision 2.33 retrieving revision 2.34 diff -C2 -d -r2.33 -r2.34 *** traceback.c 2001/10/22 19:34:09 2.33 --- traceback.c 2001/10/22 22:17:41 2.34 *************** *** 37,46 **** { Py_TRASHCAN_SAFE_BEGIN(tb) Py_XDECREF(tb->tb_next); Py_XDECREF(tb->tb_frame); ! PyObject_DEL(tb); Py_TRASHCAN_SAFE_END(tb) } PyTypeObject PyTraceBack_Type = { PyObject_HEAD_INIT(&PyType_Type) --- 37,70 ---- { Py_TRASHCAN_SAFE_BEGIN(tb) + _PyObject_GC_UNTRACK(tb); Py_XDECREF(tb->tb_next); Py_XDECREF(tb->tb_frame); ! PyObject_GC_Del(tb); Py_TRASHCAN_SAFE_END(tb) } + static int + tb_traverse(tracebackobject *tb, visitproc visit, void *arg) + { + int err = 0; + if (tb->tb_next) { + err = visit((PyObject *)tb->tb_next, arg); + if (err) + return err; + } + if (tb->tb_frame) + err = visit((PyObject *)tb->tb_frame, arg); + return err; + } + + static void + tb_clear(tracebackobject *tb) + { + Py_XDECREF(tb->tb_next); + Py_XDECREF(tb->tb_frame); + tb->tb_next = NULL; + tb->tb_frame = NULL; + } + PyTypeObject PyTraceBack_Type = { PyObject_HEAD_INIT(&PyType_Type) *************** *** 58,61 **** --- 82,104 ---- 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_HAVE_GC,/* tp_flags */ + 0, /* tp_doc */ + (traverseproc)tb_traverse, /* tp_traverse */ + (inquiry)tb_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ }; *************** *** 70,74 **** return NULL; } ! tb = PyObject_NEW(tracebackobject, &PyTraceBack_Type); if (tb != NULL) { Py_XINCREF(next); --- 113,117 ---- return NULL; } ! tb = PyObject_GC_New(tracebackobject, &PyTraceBack_Type); if (tb != NULL) { Py_XINCREF(next); *************** *** 78,81 **** --- 121,125 ---- tb->tb_lasti = lasti; tb->tb_lineno = lineno; + _PyObject_GC_TRACK(tb); } return tb; From tim_one@users.sourceforge.net Tue Oct 23 02:59:56 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 22 Oct 2001 18:59:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.296,1.297 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv21293/python/Misc Modified Files: NEWS Log Message: Doc and NEWS changes due to Jeremy adding traceback objects to gc. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.296 retrieving revision 1.297 diff -C2 -d -r1.296 -r1.297 *** NEWS 2001/10/22 18:41:51 1.296 --- NEWS 2001/10/23 01:59:54 1.297 *************** *** 17,20 **** --- 17,24 ---- Library + - Traceback objects are now scanned by cyclic garbage collection, so + cycles created by casual use of sys.exc_info() no longer cause + permanent memory leaks (provided garbage collection is enabled). + Tools/Demos From tim_one@users.sourceforge.net Tue Oct 23 02:59:56 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 22 Oct 2001 18:59:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libsys.tex,1.54,1.55 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv21293/python/Doc/lib Modified Files: libsys.tex Log Message: Doc and NEWS changes due to Jeremy adding traceback objects to gc. Index: libsys.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsys.tex,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -d -r1.54 -r1.55 *** libsys.tex 2001/10/20 04:24:09 1.54 --- libsys.tex 2001/10/23 01:59:54 1.55 *************** *** 110,114 **** to delete it after use (best done with a \keyword{try} ... \keyword{finally} statement) or to call \function{exc_info()} in ! a function that does not itself handle an exception.} \end{funcdesc} --- 110,117 ---- to delete it after use (best done with a \keyword{try} ... \keyword{finally} statement) or to call \function{exc_info()} in ! a function that does not itself handle an exception.} \note{Beginning ! with Python 2.2, such cycles are automatically reclaimed when garbage ! collection is enabled and they become unreachable, but it remains more ! efficient to avoid creating cycles.} \end{funcdesc} From nascheme@users.sourceforge.net Tue Oct 23 03:18:37 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Mon, 22 Oct 2001 19:18:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include pgenheaders.h,2.26,2.27 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv26358/Include Modified Files: pgenheaders.h Log Message: Add function attributes that allow GCC to check the arguments of printf-like functions. Index: pgenheaders.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pgenheaders.h,v retrieving revision 2.26 retrieving revision 2.27 diff -C2 -d -r2.26 -r2.27 *** pgenheaders.h 2001/07/26 21:34:59 2.26 --- pgenheaders.h 2001/10/23 02:18:35 2.27 *************** *** 26,31 **** #include "pydebug.h" ! DL_IMPORT(void) PySys_WriteStdout(const char *format, ...); ! DL_IMPORT(void) PySys_WriteStderr(const char *format, ...); #define addarc _Py_addarc --- 26,33 ---- #include "pydebug.h" ! DL_IMPORT(void) PySys_WriteStdout(const char *format, ...) ! __attribute__((format(printf, 1, 2))); ! DL_IMPORT(void) PySys_WriteStderr(const char *format, ...) ! __attribute__((format(printf, 1, 2))); #define addarc _Py_addarc From nascheme@users.sourceforge.net Tue Oct 23 03:19:12 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Mon, 22 Oct 2001 19:19:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include pyerrors.h,2.50,2.51 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv26538/Include Modified Files: pyerrors.h Log Message: Add function attributes that allow GCC to check the arguments of printf-like functions. Index: pyerrors.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pyerrors.h,v retrieving revision 2.50 retrieving revision 2.51 diff -C2 -d -r2.50 -r2.51 *** pyerrors.h 2001/10/05 21:50:08 2.50 --- pyerrors.h 2001/10/23 02:19:10 2.51 *************** *** 78,82 **** extern DL_IMPORT(PyObject *) PyErr_SetFromErrno(PyObject *); extern DL_IMPORT(PyObject *) PyErr_SetFromErrnoWithFilename(PyObject *, char *); ! extern DL_IMPORT(PyObject *) PyErr_Format(PyObject *, const char *, ...); #ifdef MS_WINDOWS extern DL_IMPORT(PyObject *) PyErr_SetFromWindowsErrWithFilename(int, const char *); --- 78,83 ---- extern DL_IMPORT(PyObject *) PyErr_SetFromErrno(PyObject *); extern DL_IMPORT(PyObject *) PyErr_SetFromErrnoWithFilename(PyObject *, char *); ! extern DL_IMPORT(PyObject *) PyErr_Format(PyObject *, const char *, ...) ! __attribute__((format(printf, 2, 3))); #ifdef MS_WINDOWS extern DL_IMPORT(PyObject *) PyErr_SetFromWindowsErrWithFilename(int, const char *); *************** *** 127,132 **** #ifndef HAVE_SNPRINTF #include ! extern DL_IMPORT(int) PyOS_snprintf(char *str, size_t size, const char *format, ...); ! extern DL_IMPORT(int) PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va); #else # define PyOS_vsnprintf vsnprintf --- 128,135 ---- #ifndef HAVE_SNPRINTF #include ! extern DL_IMPORT(int) PyOS_snprintf(char *str, size_t size, const char *format, ...) ! __attribute__((format(printf, 3, 4))); ! extern DL_IMPORT(int) PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) ! __attribute__((format(printf, 3, 0))); #else # define PyOS_vsnprintf vsnprintf From nascheme@users.sourceforge.net Tue Oct 23 03:20:39 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Mon, 22 Oct 2001 19:20:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include pyport.h,2.37,2.38 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv26961/Include Modified Files: pyport.h Log Message: Hide GCC attributes fom compilers that don't support them. Index: pyport.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pyport.h,v retrieving revision 2.37 retrieving revision 2.38 diff -C2 -d -r2.37 -r2.38 *** pyport.h 2001/10/01 19:50:06 2.37 --- pyport.h 2001/10/23 02:20:37 2.38 *************** *** 447,449 **** --- 447,458 ---- #endif + /* + * Hide GCC attributes from compilers that don't support them. + */ + #if !defined(__GNUC__) || __GNUC__ < 2 || \ + (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || \ + defined(NEXT) + #define __attribute__(__x) + #endif + #endif /* Py_PYPORT_H */ From nascheme@users.sourceforge.net Tue Oct 23 03:21:06 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Mon, 22 Oct 2001 19:21:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include stringobject.h,2.31,2.32 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv27092/Include Modified Files: stringobject.h Log Message: Add function attributes that allow GCC to check the arguments of printf-like functions. Index: stringobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/stringobject.h,v retrieving revision 2.31 retrieving revision 2.32 diff -C2 -d -r2.31 -r2.32 *** stringobject.h 2001/09/11 01:41:58 2.31 --- stringobject.h 2001/10/23 02:21:03 2.32 *************** *** 57,62 **** extern DL_IMPORT(PyObject *) PyString_FromStringAndSize(const char *, int); extern DL_IMPORT(PyObject *) PyString_FromString(const char *); ! extern DL_IMPORT(PyObject *) PyString_FromFormatV(const char*, va_list); ! extern DL_IMPORT(PyObject *) PyString_FromFormat(const char*, ...); extern DL_IMPORT(int) PyString_Size(PyObject *); extern DL_IMPORT(char *) PyString_AsString(PyObject *); --- 57,64 ---- extern DL_IMPORT(PyObject *) PyString_FromStringAndSize(const char *, int); extern DL_IMPORT(PyObject *) PyString_FromString(const char *); ! extern DL_IMPORT(PyObject *) PyString_FromFormatV(const char*, va_list) ! __attribute__((format(printf, 1, 0))); ! extern DL_IMPORT(PyObject *) PyString_FromFormat(const char*, ...) ! __attribute__((format(printf, 1, 2))); extern DL_IMPORT(int) PyString_Size(PyObject *); extern DL_IMPORT(char *) PyString_AsString(PyObject *); From nascheme@users.sourceforge.net Tue Oct 23 03:21:24 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Mon, 22 Oct 2001 19:21:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include sysmodule.h,2.23,2.24 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv27199/Include Modified Files: sysmodule.h Log Message: Add function attributes that allow GCC to check the arguments of printf-like functions. Index: sysmodule.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/sysmodule.h,v retrieving revision 2.23 retrieving revision 2.24 diff -C2 -d -r2.23 -r2.24 *** sysmodule.h 2000/12/15 22:01:39 2.23 --- sysmodule.h 2001/10/23 02:21:22 2.24 *************** *** 14,19 **** DL_IMPORT(void) PySys_SetPath(char *); ! DL_IMPORT(void) PySys_WriteStdout(const char *format, ...); ! DL_IMPORT(void) PySys_WriteStderr(const char *format, ...); extern DL_IMPORT(PyObject *) _PySys_TraceFunc, *_PySys_ProfileFunc; --- 14,21 ---- DL_IMPORT(void) PySys_SetPath(char *); ! DL_IMPORT(void) PySys_WriteStdout(const char *format, ...) ! __attribute__((format(printf, 1, 2))); ! DL_IMPORT(void) PySys_WriteStderr(const char *format, ...) ! __attribute__((format(printf, 1, 2))); extern DL_IMPORT(PyObject *) _PySys_TraceFunc, *_PySys_ProfileFunc; From tim_one@users.sourceforge.net Tue Oct 23 03:21:54 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 22 Oct 2001 19:21:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib doctest.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv26862/python/Lib Modified Files: doctest.py Log Message: SF bug [#473864] doctest expects spurios space. Repair unlikely surprise due to magical softspace attr and the use of print with a trailing comma in doctest examples. Bugfix candidate. Index: doctest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** doctest.py 2001/10/03 04:08:26 1.20 --- doctest.py 2001/10/23 02:21:52 1.21 *************** *** 380,386 **** --- 380,392 ---- if guts and not guts.endswith("\n"): guts = guts + "\n" + # Prevent softspace from screwing up the next test case, in + # case they used print with a trailing comma in an example. + if hasattr(self, "softspace"): + del self.softspace return guts def clear(self): self.buf = [] + if hasattr(self, "softspace"): + del self.softspace def flush(self): # JPython calls flush From fdrake@users.sourceforge.net Tue Oct 23 15:41:10 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 23 Oct 2001 07:41:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.67,2.68 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv2941 Modified Files: getargs.c Log Message: Style conformance: function name begins a new line *consistently*. Make convertbuffer() static like the prototype says. Not used elsewhere. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.67 retrieving revision 2.68 diff -C2 -d -r2.67 -r2.68 *** getargs.c 2001/10/11 14:40:37 2.67 --- getargs.c 2001/10/23 14:41:08 2.68 *************** *** 32,36 **** static char *skipitem(char **, va_list *); ! int PyArg_Parse(PyObject *args, char *format, ...) { int retval; --- 32,37 ---- static char *skipitem(char **, va_list *); ! int ! PyArg_Parse(PyObject *args, char *format, ...) { int retval; *************** *** 44,48 **** ! int PyArg_ParseTuple(PyObject *args, char *format, ...) { int retval; --- 45,50 ---- ! int ! PyArg_ParseTuple(PyObject *args, char *format, ...) { int retval; *************** *** 972,976 **** } ! int convertbuffer(PyObject *arg, void **p, char **errmsg) { PyBufferProcs *pb = arg->ob_type->tp_as_buffer; --- 974,979 ---- } ! static int ! convertbuffer(PyObject *arg, void **p, char **errmsg) { PyBufferProcs *pb = arg->ob_type->tp_as_buffer; *************** *** 995,1002 **** Geoff Philbrick */ ! int PyArg_ParseTupleAndKeywords(PyObject *args, ! PyObject *keywords, ! char *format, ! char **kwlist, ...) { int retval; --- 998,1006 ---- Geoff Philbrick */ ! int ! PyArg_ParseTupleAndKeywords(PyObject *args, ! PyObject *keywords, ! char *format, ! char **kwlist, ...) { int retval; From gvanrossum@users.sourceforge.net Tue Oct 23 16:10:57 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 23 Oct 2001 08:10:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test regrtest.py,1.63,1.64 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv16271 Modified Files: regrtest.py Log Message: test_curses is an expected skip on Linux too. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.63 retrieving revision 1.64 diff -C2 -d -r1.63 -r1.64 *** regrtest.py 2001/10/22 22:06:08 1.63 --- regrtest.py 2001/10/23 15:10:55 1.64 *************** *** 503,506 **** --- 503,507 ---- test_cd test_cl + test_curses test_dl test_gl From fdrake@users.sourceforge.net Tue Oct 23 22:09:31 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 23 Oct 2001 14:09:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include modsupport.h,2.37,2.38 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv19103/Include Modified Files: modsupport.h Log Message: PyArg_UnpackTuple(): New argument unpacking function suggested by Jim Fulton, based on code Jim supplied. Index: modsupport.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/modsupport.h,v retrieving revision 2.37 retrieving revision 2.38 diff -C2 -d -r2.37 -r2.38 *** modsupport.h 2001/08/02 04:15:00 2.37 --- modsupport.h 2001/10/23 21:09:29 2.38 *************** *** 14,17 **** --- 14,18 ---- extern DL_IMPORT(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, char *, char **, ...); + extern DL_IMPORT(int) PyArg_UnpackTuple(PyObject *, char *, int, int, ...); extern DL_IMPORT(PyObject *) Py_BuildValue(char *, ...); From fdrake@users.sourceforge.net Tue Oct 23 22:09:31 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 23 Oct 2001 14:09:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.68,2.69 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv19103/Python Modified Files: getargs.c Log Message: PyArg_UnpackTuple(): New argument unpacking function suggested by Jim Fulton, based on code Jim supplied. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.68 retrieving revision 2.69 diff -C2 -d -r2.68 -r2.69 *** getargs.c 2001/10/23 14:41:08 2.68 --- getargs.c 2001/10/23 21:09:29 2.69 *************** *** 1361,1362 **** --- 1361,1422 ---- return NULL; } + + + int + PyArg_UnpackTuple(PyObject *args, char *name, int min, int max, ...) + { + int i, l; + PyObject **o; + va_list vargs; + + #ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, max); + #else + va_start(vargs); + #endif + + assert(min >= 0); + assert(min <= max); + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_SystemError, + "PyArg_UnpackTuple() argument list is not a tuple"); + return 0; + } + l = PyTuple_GET_SIZE(args); + if (l < min) { + if (name != NULL) + PyErr_Format( + PyExc_TypeError, + "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at least "), min, l); + else + PyErr_Format( + PyExc_TypeError, + "unpacked tuple should have %s%d elements," + " but has %d", + (min == max ? "" : "at least "), min, l); + va_end(vargs); + return 0; + } + if (l > max) { + if (name != NULL) + PyErr_Format( + PyExc_TypeError, + "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at most "), max, l); + else + PyErr_Format( + PyExc_TypeError, + "unpacked tuple should have %s%d elements," + " but has %d", + (min == max ? "" : "at most "), max, l); + va_end(vargs); + return 0; + } + for (i = 0; i < l; i++) { + o = va_arg(vargs, PyObject **); + *o = PyTuple_GET_ITEM(args, i); + } + va_end(vargs); + return 1; + } From fdrake@users.sourceforge.net Tue Oct 23 22:10:20 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 23 Oct 2001 14:10:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api utilities.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv19522/Doc/api Modified Files: utilities.tex Log Message: Documentation for the new PyArg_UnpackTuple() function. Index: utilities.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/utilities.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** utilities.tex 2001/10/14 04:45:51 1.2 --- utilities.tex 2001/10/23 21:10:18 1.3 *************** *** 389,392 **** --- 389,439 ---- \end{cfuncdesc} + \begin{cfuncdesc}{int}{PyArg_UnpackTuple}{PyObject *args, char *name, + int min, int max, \moreargs} + A simpler form of parameter retrieval which does not use a format + string to specify the types of the arguments. Functions which use + this method to retrieve their parameters should be declared as + \constant{METH_VARARGS} in function or method tables. The tuple + containing the actual parameters should be passed as \var{args}; it + must actually be a tuple. The length of the tuple must be at least + \var{min} and no more than \var{max}; \var{min} and \var{max} may be + equal. Additional arguments must be passed to the function, each of + which should be a pointer to a \ctype{PyObject*} variable; these + will be filled in with the values from \var{args}; they will contain + borrowed references. The variables which correspond to optional + parameters not given by \var{args} will not be filled in; these + should be initialized by the caller. + This function returns true on success and false if \var{args} is not + a tuple or contains the wrong number of elements; an exception will + be set if there was a failure. + + This is an example of the use of this function, taken from the + sources for the \module{_weakref} helper module for weak references: + + \begin{verbatim} + static PyObject * + weakref_ref(PyObject *self, PyObject *args) + { + PyObject *object; + PyObject *callback = NULL; + PyObject *result = NULL; + + if (PyArg_UnpackTuple(args, "ref", 1, 2, &object, &callback)) { + result = PyWeakref_NewRef(object, callback); + } + return result; + } + \end{verbatim} + + The call to \cfunction{PyArg_UnpackTuple()} in this example is + entirely equivalent to this call to \cfunction{PyArg_ParseTuple()}: + + \begin{verbatim} + PyArg_ParseTuple(args, "O|O:ref", &object, &callback) + \end{verbatim} + + \versionadded{2.2} + \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{Py_BuildValue}{char *format, \moreargs} From fdrake@users.sourceforge.net Tue Oct 23 22:12:49 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 23 Oct 2001 14:12:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _weakref.c,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv20701/Modules Modified Files: _weakref.c Log Message: Convert the ref() and proxy() implementations to use the new PyArg_UnpackTuple() function (serves as an example and test case). Index: _weakref.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_weakref.c,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** _weakref.c 2001/10/05 22:00:24 1.14 --- _weakref.c 2001/10/23 21:12:47 1.15 *************** *** 70,74 **** PyObject *result = NULL; ! if (PyArg_ParseTuple(args, "O|O:ref", &object, &callback)) { result = PyWeakref_NewRef(object, callback); } --- 70,74 ---- PyObject *result = NULL; ! if (PyArg_UnpackTuple(args, "ref", 1, 2, &object, &callback)) { result = PyWeakref_NewRef(object, callback); } *************** *** 89,93 **** PyObject *result = NULL; ! if (PyArg_ParseTuple(args, "O|O:new", &object, &callback)) { result = PyWeakref_NewProxy(object, callback); } --- 89,93 ---- PyObject *result = NULL; ! if (PyArg_UnpackTuple(args, "proxy", 1, 2, &object, &callback)) { result = PyWeakref_NewProxy(object, callback); } From gvanrossum@users.sourceforge.net Tue Oct 23 22:25:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 23 Oct 2001 14:25:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.129,1.130 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv25768/Misc Modified Files: ACKS Log Message: SF patch #474175 (Jay T Miller): file.readinto arg parsing bug The C-code in fileobject.readinto(buffer) which parses the arguments assumes that size_t is interchangeable with int: size_t ntodo, ndone, nnow; if (f->f_fp == NULL) return err_closed(); if (!PyArg_Parse(args, "w#", &ptr, &ntodo)) return NULL; This causes a problem on Alpha / Tru64 / OSF1 v5.1 where size_t is a long and sizeof(long) != sizeof(int). The patch I'm proposing declares ntodo as an int. An alternative might be to redefine w# to expect size_t. [We can't change w# because there are probably third party modules relying on it. GvR] Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.129 retrieving revision 1.130 diff -C2 -d -r1.129 -r1.130 *** ACKS 2001/10/20 14:21:45 1.129 --- ACKS 2001/10/23 21:25:24 1.130 *************** *** 280,283 **** --- 280,284 ---- Michael McLay Gordon McMillan + Jay T. Miller Caolan McNamara Craig McPheeters From gvanrossum@users.sourceforge.net Tue Oct 23 22:25:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 23 Oct 2001 14:25:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.134,2.135 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv25768/Objects Modified Files: fileobject.c Log Message: SF patch #474175 (Jay T Miller): file.readinto arg parsing bug The C-code in fileobject.readinto(buffer) which parses the arguments assumes that size_t is interchangeable with int: size_t ntodo, ndone, nnow; if (f->f_fp == NULL) return err_closed(); if (!PyArg_Parse(args, "w#", &ptr, &ntodo)) return NULL; This causes a problem on Alpha / Tru64 / OSF1 v5.1 where size_t is a long and sizeof(long) != sizeof(int). The patch I'm proposing declares ntodo as an int. An alternative might be to redefine w# to expect size_t. [We can't change w# because there are probably third party modules relying on it. GvR] Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.134 retrieving revision 2.135 diff -C2 -d -r2.134 -r2.135 *** fileobject.c 2001/10/12 20:01:53 2.134 --- fileobject.c 2001/10/23 21:25:24 2.135 *************** *** 607,611 **** { char *ptr; ! size_t ntodo, ndone, nnow; if (f->f_fp == NULL) --- 607,612 ---- { char *ptr; ! int ntodo; ! size_t ndone, nnow; if (f->f_fp == NULL) From gvanrossum@users.sourceforge.net Tue Oct 23 22:42:47 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 23 Oct 2001 14:42:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib SocketServer.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv1184 Modified Files: SocketServer.py Log Message: Apply the first chunk of the second patch from SF bug #471720: ThreadingMixIn/TCPServer forgets close (Max Neunhöffer). This ensures that handle_error() and close_request() are called when an error occurs in the thread. (I am not applying the second chunk of the patch, which moved the finish() call into the finally clause in BaseRequestHandler's __init__ method; that would be a semantic change that I cannot accept at this point - the data would be sent even if the handler raised an exception.) Index: SocketServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/SocketServer.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** SocketServer.py 2001/10/18 18:02:07 1.28 --- SocketServer.py 2001/10/23 21:42:45 1.29 *************** *** 450,456 **** def process_request_thread(self, request, client_address): ! """Same as in BaseServer but as a thread.""" ! self.finish_request(request, client_address) ! self.close_request(request) def process_request(self, request, client_address): --- 450,464 ---- def process_request_thread(self, request, client_address): ! """Same as in BaseServer but as a thread. ! ! In addition, exception handling is done here. ! ! """ ! try: ! self.finish_request(request, client_address) ! self.close_request(request) ! except: ! self.handle_error(request, client_address) ! self.close_request(request) def process_request(self, request, client_address): From jackjansen@users.sourceforge.net Tue Oct 23 23:18:12 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:18:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Build PythonCore.mcp,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory usw-pr-cvs1:/tmp/cvs-serv15179/Python/Mac/Build Modified Files: PythonCore.mcp Log Message: Tweaks for MacPython 2.2b1. Index: PythonCore.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCore.mcp,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 Binary files /tmp/cvsyw97GV and /tmp/cvsWQh7RI differ From jackjansen@users.sourceforge.net Tue Oct 23 23:19:41 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:19:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Distributions dev.exclude,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions In directory usw-pr-cvs1:/tmp/cvs-serv15829/Python/Mac/Distributions Modified Files: dev.exclude Log Message: Tweaks for MacPython 2.2b1 Index: dev.exclude =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/dev.exclude,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** dev.exclude 2001/02/14 16:58:21 1.6 --- dev.exclude 2001/10/23 22:19:39 1.7 *************** *** 17,18 **** --- 17,19 ---- CVS [(]*[)] + *.pyo From jackjansen@users.sourceforge.net Tue Oct 23 23:19:54 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:19:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Distributions dev.include,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions In directory usw-pr-cvs1:/tmp/cvs-serv15903/Python/Mac/Distributions Modified Files: dev.include Log Message: Tweaks for MacPython 2.2b1 Index: dev.include =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/dev.include,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** dev.include 2001/09/08 21:36:49 1.21 --- dev.include 2001/10/23 22:19:52 1.22 *************** *** 354,357 **** --- 354,360 ---- (':Mac:MPW', None) (':Mac:Modules', None) + (':Mac:OSX:Makefile', None) + (':Mac:OSX:README', None) + (':Mac:OSX:README.macosx.txt', None) (':Mac:OSXResources', None) (':Mac:OSXResources:', None) *************** *** 587,591 **** (':setup.py', None) (':site-packages', None) ! (':Mac:OSX:README.macosx.txt', None) ! (':Mac:OSX:README', None) ! (':Mac:OSX:Makefile', None) --- 590,598 ---- (':setup.py', None) (':site-packages', None) ! (':Mac:Build:_hotshot.mcp.xml', None) ! (':Mac:Build:_hotshot.mcp.exp', None) ! (':Mac:Build:_hotshot.mcp', None) ! (':Mac:Build:_hotshot.carbon.mcp.xml', None) ! (':Mac:Build:_hotshot.carbon.mcp.exp', None) ! (':Mac:Build:_hotshot.carbon.mcp', None) ! (':Modules:_hotshot.c', None) From jackjansen@users.sourceforge.net Tue Oct 23 23:20:19 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:20:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Distributions binary.include,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions In directory usw-pr-cvs1:/tmp/cvs-serv16149/Python/Mac/Distributions Modified Files: binary.include Log Message: Tweaks for MacPython 2.2b1 Index: binary.include =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/binary.include,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** binary.include 2001/09/08 21:36:56 1.18 --- binary.include 2001/10/23 22:20:17 1.19 *************** *** 128,132 **** (':Mac:Contrib:Sherlock', '') (':Mac:Contrib:Tabcleaner', '') - (':Mac:Contrib:morefindertools', '') (':Mac:Contrib:osam:OSAm.carbon.slb', '') (':Mac:Contrib:osam:OSAm.exp', None) --- 128,131 ---- *************** *** 144,147 **** --- 143,147 ---- (':Mac:MPW', None) (':Mac:Modules', None) + (':Mac:OSX:README', None) (':Mac:OSX:README.macosx.txt', None) (':Mac:OSXResources', None) *************** *** 175,178 **** --- 175,179 ---- (':PLAN.txt', None) (':Parser:Icon', None) + (':Parser:grammar.mak', None) (':Python IDE', None) (':Python:Icon', None) *************** *** 219,221 **** (':setup.py', None) (':site-packages', None) - (':Mac:OSX:README', None) --- 220,221 ---- From jackjansen@users.sourceforge.net Tue Oct 23 23:20:05 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:20:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Distributions binary.exclude,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions In directory usw-pr-cvs1:/tmp/cvs-serv16019/Python/Mac/Distributions Modified Files: binary.exclude Log Message: Tweaks for MacPython 2.2b1 Index: binary.exclude =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/binary.exclude,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** binary.exclude 2001/02/27 23:23:23 1.9 --- binary.exclude 2001/10/23 22:20:03 1.10 *************** *** 20,24 **** *.prj *.prj.exp - *.pyc *.xSYM *.µ --- 20,23 ---- *************** *** 34,35 **** --- 33,36 ---- Setup.in [(]*[)] + *.pyc + *.pyo From jackjansen@users.sourceforge.net Tue Oct 23 23:20:32 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:20:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac Relnotes,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Mac In directory usw-pr-cvs1:/tmp/cvs-serv16250/Python/Mac Modified Files: Relnotes Log Message: Tweaks for MacPython 2.2b1 Index: Relnotes =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Relnotes,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** Relnotes 2001/09/08 21:38:26 1.26 --- Relnotes 2001/10/23 22:20:30 1.27 *************** *** 1,8 **** ! Changes in 2.2a3 since 2.1.1 ---------------------------- These release notes refer to Mac-specific changes only. See NEWS (in the Misc folder) ! for machine-independent changes. - The main change is that all toolbox modules have moved to a package called Carbon. So things like "import Res" should be changed to "from Carbon import Res", and --- 1,9 ---- ! Changes in 2.2b1 since 2.1.1 ---------------------------- These release notes refer to Mac-specific changes only. See NEWS (in the Misc folder) ! for machine-independent changes. Changes that were already in 2.2a3 are flagged as such. + - The main change is that all toolbox modules have moved to a package called Carbon. So things like "import Res" should be changed to "from Carbon import Res", and *************** *** 10,30 **** some open questions and join the discussions on pythonmac-sig if you have anything to contribute. Aside from reducing clutter this change will also benefit the ! port to Mach-O/OSX Python later. - On input MacPython now accepts either \n (unix style) or \r (mac style) newlines for text files. This behaviour can be turned off with a preference. ! This is an experimental feature; again: feedback is requested. - There is a new module macresource which makes it easier to open a resource file accompanying your script when the script is not (yet) converted to an applet. ! This module will later also do the right thing in Mach-O/OSX Python. - Threads had a stack that was too small for many serious Python applications (20K). ! They now get 64K. There is still no overflow check, though. ! - Garbage collection and the gc module have (finally) been enabled. - EasyDialogs.ProgressBar now has indeterminate progressbars if you specify maxval=0. ! This is also the new default. Patch supplied by Dean Draayer. - There are new preferences for enabling old-style division warnings and for accepting unix-style newlines in text input files. These can also be set during ! startup, and in addition you can select very verbose import tracing. ! - Various outdated scripts have been moved to :Mac:Unsupported. ! - Various outdated items from :Mac:Lib:test have been removed. What is not in this distribution --- 11,38 ---- some open questions and join the discussions on pythonmac-sig if you have anything to contribute. Aside from reducing clutter this change will also benefit the ! port to Mach-O/OSX Python later. [2.2a3] - On input MacPython now accepts either \n (unix style) or \r (mac style) newlines for text files. This behaviour can be turned off with a preference. ! This is an experimental feature; again: feedback is requested. [2.2a3] - There is a new module macresource which makes it easier to open a resource file accompanying your script when the script is not (yet) converted to an applet. ! This module will later also do the right thing in Mach-O/OSX Python. [2.2a3] - Threads had a stack that was too small for many serious Python applications (20K). ! They now get 64K. There is still no overflow check, though. [2.2a3] ! - Garbage collection and the gc module have (finally) been enabled. [2.2a3] - EasyDialogs.ProgressBar now has indeterminate progressbars if you specify maxval=0. ! This is also the new default. Patch supplied by Dean Draayer. [2.2a3] - There are new preferences for enabling old-style division warnings and for accepting unix-style newlines in text input files. These can also be set during ! startup, and in addition you can select very verbose import tracing. [2.2a3] ! - Various outdated scripts have been moved to :Mac:Unsupported. [2.2a3] ! - Various outdated items from :Mac:Lib:test have been removed. [2.2a3] ! - C Developers: you know have control over the Python console if you are embedding ! MacPython in another application, thanks to Alexandre Parenteau. :Mac:Demo:embed.html ! has very minimal documentation. ! - BuildCGIApplet works again. ! - The CodeWarrior OSA suite missed quit(). It is back. ! - Contrib:morefindertools is gone, the functionality has been integrated into ! the standard module findertools.py. What is not in this distribution From jackjansen@users.sourceforge.net Tue Oct 23 23:20:45 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:20:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac ReadMe,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Mac In directory usw-pr-cvs1:/tmp/cvs-serv16320/Python/Mac Modified Files: ReadMe Log Message: Tweaks for MacPython 2.2b1 Index: ReadMe =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/ReadMe,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** ReadMe 2001/09/08 21:37:01 1.34 --- ReadMe 2001/10/23 22:20:43 1.35 *************** *** 1,3 **** ! How to install Python 2.2a3 on your Macintosh --------------------------------------------- --- 1,3 ---- ! How to install Python 2.2b1 on your Macintosh --------------------------------------------- *************** *** 7,11 **** You should definitely read the Relnotes file too, and the section below about ! toolbox module reorganization. A special note about the active installer: do not background it, it may hang --- 7,12 ---- You should definitely read the Relnotes file too, and the section below about ! toolbox module reorganization. You should also read :Misc:NEWS, which lists ! the general (non-mac-dependent) new features of this Python release. A special note about the active installer: do not background it, it may hang *************** *** 13,19 **** are working on it. - Aside from the general new Python 2.2a3 listed in the general relnotes file - there is some other new machine-independent stuff in this release as well, as - it was built from newer sources than unix/windows 2.2a3. ------ --- 14,17 ---- *************** *** 65,89 **** modules you may think of as toolbox modules (such as Waste) really are not, and they are not in the Carbon package. - - Some open issues I would like to discuss on the PythonMac-SIG, please join - in if you have views on the matter: - - Is this all a good idea? - - Some modules are not in the Carbon package (icglue, for instance, or - supporting module such as aetools and aepack) and maybe they should be, - some are (ControlAccessors) which arguably should not. Opinions are welcome. - - I'm tempted to put Qt and QuickTime into their own package, especially - since I'm also working on porting it to Windows. It would also be in line - with Apple's organization. Opinions? - - Should we get rid of the Res/Resource dichotomy, where the first is the - extension module and the second is the Python module with the constants? - We could simply import the extension module functionality into the Python - module, at the expense of a rather large namespace. - - Should we have a Carbon.Carbon module that simply imports the whole world, - so that "from Carbon.Carbon import *" is pretty much equivalent to the C - #include ? - - Should we put all the other Mac modules into a Mac package? This will make - MacPython programs a lot more verbose, but that is a good thing too if people - try to port Mac Python scripts to other platforms. - Should the Carbon package then be a sub-package of the Mac package? Another change related to the OSX growth path is that there is a new module --- 63,66 ---- *************** *** 95,102 **** OSX MachO Python. ! ... and more ! ------------ ! ! A feature that I am not sure about (so: feedback!) is that if you open a textfile for reading MacPython will now accept either unix linefeeds (LF, '\n') or Macintosh linefeeds (CR, '\r') and present both of them as '\n'. This is done on --- 72,76 ---- OSX MachO Python. ! Another feature to help with the OSX transition is that if you open a textfile for reading MacPython will now accept either unix linefeeds (LF, '\n') or Macintosh linefeeds (CR, '\r') and present both of them as '\n'. This is done on *************** *** 152,161 **** test_time will fail because MacPython accepts bogus values for mktime(), this ! will be fixed later. test_descrtut will fail because of a problem with the test itself. Three tests will fail on MacOS9 with MemoryErrors: ! test_longexp, test_sha and test_zlib (on MacOSX nothing should fail). If you increase the PythonInterpreter memory --- 126,135 ---- test_time will fail because MacPython accepts bogus values for mktime(), this ! will be fixed later (it is not a very serious problem). test_descrtut will fail because of a problem with the test itself. Three tests will fail on MacOS9 with MemoryErrors: ! test_longexp, test_sha and test_zlib (on MacOSX these should pass). If you increase the PythonInterpreter memory *************** *** 182,186 **** Two items are installed in the system folder: the interpreter shared libraries PythonCore and PythonCoreCarbon lives in the Extensions folder and the ! "Python 2.2a3 Preferences" file in the Python subfolder in the Preferences folder. All the rest of Python lives in the folder you installed in. --- 156,160 ---- Two items are installed in the system folder: the interpreter shared libraries PythonCore and PythonCoreCarbon lives in the Extensions folder and the ! "Python 2.2b1 Preferences" file in the Python subfolder in the Preferences folder. All the rest of Python lives in the folder you installed in. *************** *** 231,237 **** are lost and you have to set them again. ! After you are satisfied that 2.2a3 works as expected you can trash anything in the system folder that has "python" in the name and not ! "2.2a3". The ConfigurePython... applets will try to detect incompatible preferences --- 205,211 ---- are lost and you have to set them again. ! After you are satisfied that 2.2b1 works as expected you can trash anything in the system folder that has "python" in the name and not ! "2.2b1". The ConfigurePython... applets will try to detect incompatible preferences From jackjansen@users.sourceforge.net Tue Oct 23 23:21:00 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:21:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include patchlevel.h,2.56,2.57 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv16428/Python/Include Modified Files: patchlevel.h Log Message: Tweaks for MacPython 2.2b1 Index: patchlevel.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/patchlevel.h,v retrieving revision 2.56 retrieving revision 2.57 diff -C2 -d -r2.56 -r2.57 *** patchlevel.h 2001/10/19 17:11:58 2.56 --- patchlevel.h 2001/10/23 22:20:58 2.57 *************** *** 27,31 **** /* Version as a string */ ! #define PY_VERSION "2.2b1+" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. --- 27,31 ---- /* Version as a string */ ! #define PY_VERSION "2.2b1" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From jackjansen@users.sourceforge.net Tue Oct 23 23:21:12 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:21:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac _checkversion.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Mac In directory usw-pr-cvs1:/tmp/cvs-serv16519/Python/Mac Modified Files: _checkversion.py Log Message: Tweaks for MacPython 2.2b1 Index: _checkversion.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/_checkversion.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** _checkversion.py 2001/09/08 21:37:06 1.10 --- _checkversion.py 2001/10/23 22:21:10 1.11 *************** *** 6,10 **** _PACKAGE="MacPython" ! _VERSION="2.2a3" _URL="http://www.cwi.nl/~jack/macpythonversion.txt" --- 6,10 ---- _PACKAGE="MacPython" ! _VERSION="2.2b1" _URL="http://www.cwi.nl/~jack/macpythonversion.txt" From jackjansen@users.sourceforge.net Tue Oct 23 23:21:21 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:21:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Include macbuildno.h,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Include In directory usw-pr-cvs1:/tmp/cvs-serv16559/Python/Mac/Include Modified Files: macbuildno.h Log Message: Tweaks for MacPython 2.2b1 Index: macbuildno.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Include/macbuildno.h,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** macbuildno.h 2001/09/08 21:37:25 1.20 --- macbuildno.h 2001/10/23 22:21:19 1.21 *************** *** 1 **** ! #define BUILD 107 --- 1 ---- ! #define BUILD 111 From jackjansen@users.sourceforge.net Tue Oct 23 23:21:42 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:21:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Build PythonCoreCarbon.exp,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory usw-pr-cvs1:/tmp/cvs-serv16612/Python/Mac/Build Modified Files: PythonCoreCarbon.exp Log Message: Tweaks for MacPython 2.2b1 Index: PythonCoreCarbon.exp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCoreCarbon.exp,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** PythonCoreCarbon.exp 2001/10/08 15:35:33 1.17 --- PythonCoreCarbon.exp 2001/10/23 22:21:40 1.18 *************** *** 131,134 **** --- 131,135 ---- PyMarshal_ReadLastObjectFromFile PyMarshal_ReadLongFromFile + PyMarshal_ReadShortFromFile PyMarshal_WriteObjectToFile PyMarshal_WriteLongToFile *************** *** 712,716 **** pcre_study initcPickle ! Pickler_setattr cPickle_PyMapping_HasKey initcStringIO --- 713,717 ---- pcre_study initcPickle ! fast_save_leave cPickle_PyMapping_HasKey initcStringIO *************** *** 1040,1043 **** --- 1041,1046 ---- PyWeakref_NewRef _PyWeakref_GetWeakrefCount + PyStructSequence_InitType + PyStructSequence_New GUSISetupConsoleStdio GUSIStdioFlush From jackjansen@users.sourceforge.net Tue Oct 23 23:22:12 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:22:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Build PythonCore.exp,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory usw-pr-cvs1:/tmp/cvs-serv16785/Python/Mac/Build Modified Files: PythonCore.exp Log Message: Tweaks for MacPython 2.2b1 Index: PythonCore.exp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCore.exp,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** PythonCore.exp 2001/10/08 15:35:26 1.17 --- PythonCore.exp 2001/10/23 22:22:09 1.18 *************** *** 131,134 **** --- 131,135 ---- PyMarshal_ReadLastObjectFromFile PyMarshal_ReadLongFromFile + PyMarshal_ReadShortFromFile PyMarshal_WriteObjectToFile PyMarshal_WriteLongToFile *************** *** 718,722 **** pcre_study initcPickle ! Pickler_setattr cPickle_PyMapping_HasKey initcStringIO --- 719,723 ---- pcre_study initcPickle ! fast_save_leave cPickle_PyMapping_HasKey initcStringIO From jackjansen@users.sourceforge.net Tue Oct 23 23:23:36 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:23:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/scripts fullbuild.py,1.74,1.75 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory usw-pr-cvs1:/tmp/cvs-serv17294/Python/Mac/scripts Modified Files: fullbuild.py Log Message: Added _hotshot. Index: fullbuild.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/fullbuild.py,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -d -r1.74 -r1.75 *** fullbuild.py 2001/08/29 22:07:59 1.74 --- fullbuild.py 2001/10/23 22:23:34 1.75 *************** *** 240,243 **** --- 240,244 ---- (":Mac:Build:_symtable.mcp", "_symtable.ppc"), (":Mac:Build:_testcapi.mcp", "_testcapi.ppc"), + (":Mac:Build:_hotshot.mcp", "_hotshot.ppc"), (":Mac:Build:xx.mcp", "xx.ppc"), (":Mac:Build:xxsubtype.mcp", "xxsubtype.ppc"), *************** *** 282,285 **** --- 283,287 ---- (":Mac:Build:_symtable.carbon.mcp", "_symtable.carbon"), (":Mac:Build:_testcapi.carbon.mcp", "_testcapi.carbon"), + (":Mac:Build:_hotshot.carbon.mcp", "_hotshot.carbon"), (":Mac:Build:xx.carbon.mcp", "xx.carbon"), (":Mac:Build:xxsubtype.carbon.mcp", "xxsubtype.carbon"), From jackjansen@users.sourceforge.net Tue Oct 23 23:23:46 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:23:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/scripts genpluginprojects.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory usw-pr-cvs1:/tmp/cvs-serv17350/Python/Mac/scripts Modified Files: genpluginprojects.py Log Message: Added _hotshot. Index: genpluginprojects.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/genpluginprojects.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** genpluginprojects.py 2001/08/29 22:08:06 1.20 --- genpluginprojects.py 2001/10/23 22:23:44 1.21 *************** *** 114,117 **** --- 114,118 ---- genpluginproject("all", "xx") genpluginproject("all", "xxsubtype", sources=["xxsubtype.c"]) + genpluginproject("all", "_hotshot", sources=["_hotshot.c"]) # bgen-generated Toolbox modules From jackjansen@users.sourceforge.net Tue Oct 23 23:23:04 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:23:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Lib/lib-scriptpackages/CodeWarrior Standard_Suite.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Lib/lib-scriptpackages/CodeWarrior In directory usw-pr-cvs1:/tmp/cvs-serv17156/Python/Mac/Lib/lib-scriptpackages/CodeWarrior Modified Files: Standard_Suite.py Log Message: quit() wasn't included in the suite. This is a quick manual patch to add it. Index: Standard_Suite.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Lib/lib-scriptpackages/CodeWarrior/Standard_Suite.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Standard_Suite.py 2001/05/17 12:40:44 1.2 --- Standard_Suite.py 2001/10/23 22:23:02 1.3 *************** *** 11,15 **** _code = 'CoRe' ! class Standard_Suite_Events: _argmap_close = { --- 11,16 ---- _code = 'CoRe' ! from StdSuites.Standard_Suite import * ! class Standard_Suite_Events(Standard_Suite_Events): _argmap_close = { From jackjansen@users.sourceforge.net Tue Oct 23 23:26:18 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:26:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _hotshot.c,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv18131/Python/Modules Modified Files: _hotshot.c Log Message: Got this to work in MacPython. The code is #ifdef macintosh style (to match the existing #ifdef MS_WINDOWS), but eventually ifdeffing on configure features is probably better. Index: _hotshot.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_hotshot.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** _hotshot.c 2001/10/15 22:11:02 1.6 --- _hotshot.c 2001/10/23 22:26:16 1.7 *************** *** 32,37 **** --- 32,41 ---- #error "This module requires gettimeofday() on non-Windows platforms!" #endif + #ifdef macintosh + #include + #else #include #include + #endif typedef struct timeval hs_time; #endif *************** *** 49,52 **** --- 53,60 ---- #define BUFFERSIZE 10240 + #ifdef macintosh + #define PATH_MAX 254 + #endif + #ifndef PATH_MAX # ifdef MAX_PATH *************** *** 305,309 **** } else { ! *pvalue = PyString_FromStringAndSize(self->buffer + self->index, len); if (*pvalue == NULL) { --- 313,317 ---- } else { ! *pvalue = PyString_FromStringAndSize((char *)self->buffer + self->index, len); if (*pvalue == NULL) { *************** *** 890,894 **** #endif } ! #ifdef MS_WIN32 rusage_diff = -1; #else --- 898,902 ---- #endif } ! #if defined(MS_WIN32) || defined(macintosh) rusage_diff = -1; #else From jackjansen@users.sourceforge.net Tue Oct 23 23:27:19 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:27:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Demo index.html,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo In directory usw-pr-cvs1:/tmp/cvs-serv18579/Python/Mac/Demo Modified Files: index.html Log Message: New URL for Joe Strouts example page. Index: index.html =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/index.html,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** index.html 2000/04/22 22:56:09 1.16 --- index.html 2001/10/23 22:27:17 1.17 *************** *** 15,21 **** Another set of Macintosh-savvy examples, more aimed at beginners, is ! maintained by Joseph Strout, at ! http://www-acs.ucsd.edu/~jstrout/python/.

    --- 15,21 ---- Another set of Macintosh-savvy examples, more aimed at beginners, is ! maintained by Joseph Strout, at Python Tidbits in ! http://www.strout.net/python/.

    From jackjansen@users.sourceforge.net Tue Oct 23 23:28:25 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:28:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules macmodule.c,1.46,1.47 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory usw-pr-cvs1:/tmp/cvs-serv18866/Python/Mac/Modules Modified Files: macmodule.c Log Message: Some escaped newlines had spaces between the backslash and the newline. Also slightly changed the comment on xstat(). Index: macmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/macmodule.c,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -d -r1.46 -r1.47 *** macmodule.c 2001/10/18 20:34:25 1.46 --- macmodule.c 2001/10/23 22:28:23 1.47 *************** *** 468,474 **** or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\ \n\ - Macintosh: The fields st_rsize, st_creator, and st_type are available from\n\ - os.xstat.\n\ - \n\ See os.stat for more information.\n"; --- 468,471 ---- *************** *** 476,483 **** { "st_mode", "protection bits" }, \ { "st_ino", "inode" }, \ ! { "st_dev", "device" }, \ { "st_nlink", "number of hard links" }, \ ! { "st_uid", "user ID of owner" }, \ ! { "st_gid", "group ID of owner" }, \ { "st_size", "total size, in bytes" }, \ { "st_atime", "time of last access" }, \ --- 473,480 ---- { "st_mode", "protection bits" }, \ { "st_ino", "inode" }, \ ! { "st_dev", "device" }, \ { "st_nlink", "number of hard links" }, \ ! { "st_uid", "user ID of owner" }, \ ! { "st_gid", "group ID of owner" }, \ { "st_size", "total size, in bytes" }, \ { "st_atime", "time of last access" }, \ *************** *** 503,507 **** #ifdef TARGET_API_MAC_OS8 static PyStructSequence_Field xstat_result_fields[] = { ! COMMON_XSTAT_RESULT_FIELDS { "st_rsize" }, { "st_creator" }, --- 500,504 ---- #ifdef TARGET_API_MAC_OS8 static PyStructSequence_Field xstat_result_fields[] = { ! COMMON_STAT_RESULT_FIELDS { "st_rsize" }, { "st_creator" }, From jackjansen@users.sourceforge.net Tue Oct 23 23:29:08 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 23 Oct 2001 15:29:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules zlibmodule.c,2.55,2.56 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv19150/Python/Modules Modified Files: zlibmodule.c Log Message: Added missing cast. Index: zlibmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/zlibmodule.c,v retrieving revision 2.55 retrieving revision 2.56 diff -C2 -d -r2.55 -r2.56 *** zlibmodule.c 2001/10/17 13:32:02 2.55 --- zlibmodule.c 2001/10/23 22:29:06 2.56 *************** *** 528,532 **** if(max_length) { Py_DECREF(self->unconsumed_tail); ! self->unconsumed_tail = PyString_FromStringAndSize(self->zst.next_in, self->zst.avail_in); if(!self->unconsumed_tail) { --- 528,532 ---- if(max_length) { Py_DECREF(self->unconsumed_tail); ! self->unconsumed_tail = PyString_FromStringAndSize((char *)self->zst.next_in, self->zst.avail_in); if(!self->unconsumed_tail) { From fdrake@acm.org Wed Oct 24 02:42:58 2001 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Tue, 23 Oct 2001 21:42:58 -0400 Subject: [Python-checkins] CVS: python/dist/src/Modules _hotshot.c,1.6,1.7 In-Reply-To: References: Message-ID: <15318.7330.150430.122954@grendel.zope.com> Jack Jansen writes: > Got this to work in MacPython. The code is #ifdef macintosh style > (to match the existing #ifdef MS_WINDOWS), but eventually ifdeffing > on configure features is probably better. Thanks! > + #ifdef macintosh > + #define PATH_MAX 254 > + #endif > + This in particular looks like it could go in Include/pyport.h. This constant is also used in Python/dynload_beos.c, and seems fairly general. -Fred -- Fred L. Drake, Jr. PythonLabs at Zope Corporation From jackjansen@users.sourceforge.net Wed Oct 24 09:50:01 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 24 Oct 2001 01:50:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include patchlevel.h,2.57,2.58 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv27927 Modified Files: patchlevel.h Log Message: Oops, undo previous change, which wasn't supposed to escape from my machine. Luckily everyone is asleep, so I didn't have to use the time machine. Index: patchlevel.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/patchlevel.h,v retrieving revision 2.57 retrieving revision 2.58 diff -C2 -d -r2.57 -r2.58 *** patchlevel.h 2001/10/23 22:20:58 2.57 --- patchlevel.h 2001/10/24 08:49:59 2.58 *************** *** 27,31 **** /* Version as a string */ ! #define PY_VERSION "2.2b1" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. --- 27,31 ---- /* Version as a string */ ! #define PY_VERSION "2.2b1+" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From loewis@users.sourceforge.net Wed Oct 24 15:36:02 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 24 Oct 2001 07:36:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.183,1.184 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv10527/Modules Modified Files: socketmodule.c Log Message: Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.183 retrieving revision 1.184 diff -C2 -d -r1.183 -r1.184 *** socketmodule.c 2001/10/19 12:40:40 1.183 --- socketmodule.c 2001/10/24 14:36:00 1.184 *************** *** 623,626 **** --- 623,632 ---- hints.ai_family = af; error = getaddrinfo(name, NULL, &hints, &res); + if (error = EAI_NONAME && af == AF_UNSPEC) { + /* On OSF/1 V5.1, numeric-to-addr conversion + fails if no address family is given. Assume IPv4 for now.*/ + hints.ai_family = AF_INET; + error = getaddrinfo(name, NULL, &hints, &res); + } if (error) { PyGAI_Err(error); From loewis@users.sourceforge.net Wed Oct 24 15:36:02 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 24 Oct 2001 07:36:02 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.268,1.269 configure.in,1.276,1.277 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv10527 Modified Files: configure configure.in Log Message: Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.268 retrieving revision 1.269 diff -C2 -d -r1.268 -r1.269 *** configure 2001/10/21 22:32:04 1.268 --- configure 2001/10/24 14:35:57 1.269 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.275 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.276 [...3921 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 < *************** *** 7471,7475 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7474: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 7442,7446 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7445: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.276 retrieving revision 1.277 diff -C2 -d -r1.276 -r1.277 *** configure.in 2001/10/21 22:32:04 1.276 --- configure.in 2001/10/24 14:35:59 1.277 *************** *** 1427,1431 **** AC_CHECK_FUNCS(gettimeofday, AC_TRY_COMPILE([#include ], [gettimeofday((struct timeval*)0,(struct timezone*)0);], ,AC_DEFINE(GETTIMEOFDAY_NO_TZ))) ! AC_CHECK_FUNCS(getaddrinfo, [dnl AC_MSG_CHECKING(getaddrinfo bug) AC_TRY_RUN([ --- 1427,1441 ---- AC_CHECK_FUNCS(gettimeofday, AC_TRY_COMPILE([#include ], [gettimeofday((struct timeval*)0,(struct timezone*)0);], ,AC_DEFINE(GETTIMEOFDAY_NO_TZ))) ! ! # On OSF/1 V5.1, getaddrinfo is available, but a define ! # for [no]getaddrinfo in netdb.h. ! AC_MSG_CHECKING(for getaddrinfo) ! AC_TRY_LINK([ ! #include ! #include ! ],[ ! getaddrinfo(NULL, NULL, NULL, NULL); ! ], [ ! AC_MSG_RESULT(yes) AC_MSG_CHECKING(getaddrinfo bug) AC_TRY_RUN([ *************** *** 1520,1524 **** buggygetaddrinfo=yes, AC_MSG_RESULT(buggy) ! buggygetaddrinfo=yes)], [buggygetaddrinfo=yes]) if test "$buggygetaddrinfo" = "yes"; then --- 1530,1537 ---- buggygetaddrinfo=yes, AC_MSG_RESULT(buggy) ! buggygetaddrinfo=yes)], [ ! AC_MSG_RESULT(no) ! buggygetaddrinfo=yes ! ]) if test "$buggygetaddrinfo" = "yes"; then *************** *** 1528,1531 **** --- 1541,1546 ---- exit 1 fi + else + AC_DEFINE(HAVE_GETADDRINFO) fi AC_CHECK_FUNCS(getnameinfo) From jack@oratrix.nl Wed Oct 24 15:52:48 2001 From: jack@oratrix.nl (Jack Jansen) Date: Wed, 24 Oct 2001 16:52:48 +0200 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.183,1.184 In-Reply-To: Message by "Martin v. L?wis" , Wed, 24 Oct 2001 07:36:02 -0700 , Message-ID: <20011024145248.75BFB303181@snelboot.oratrix.nl> Martin, are you sure about this fix? The if (error = EAI_NONAME bit looks suspicious... > Update of /cvsroot/python/python/dist/src/Modules > In directory usw-pr-cvs1:/tmp/cvs-serv10527/Modules > > Modified Files: > socketmodule.c > Log Message: > > > > Index: socketmodule.c > =================================================================== > RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v > retrieving revision 1.183 > retrieving revision 1.184 > diff -C2 -d -r1.183 -r1.184 > *** socketmodule.c 2001/10/19 12:40:40 1.183 > --- socketmodule.c 2001/10/24 14:36:00 1.184 > *************** > *** 623,626 **** > --- 623,632 ---- > hints.ai_family = af; > error = getaddrinfo(name, NULL, &hints, &res); > + if (error = EAI_NONAME && af == AF_UNSPEC) { > + /* On OSF/1 V5.1, numeric-to-addr conversion > + fails if no address family is given. Assume IPv4 for now.*/ > + hints.ai_family = AF_INET; > + error = getaddrinfo(name, NULL, &hints, &res); > + } > if (error) { > PyGAI_Err(error); > > > _______________________________________________ > Python-checkins mailing list > Python-checkins@python.org > http://mail.python.org/mailman/listinfo/python-checkins > -- Jack Jansen | ++++ stop the execution of Mumia Abu-Jamal ++++ Jack.Jansen@oratrix.com | ++++ if you agree copy these lines to your sig ++++ www.cwi.nl/~jack | see http://www.xs4all.nl/~tank/spg-l/sigaction.htm From loewis@users.sourceforge.net Wed Oct 24 18:10:51 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 24 Oct 2001 10:10:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include py_curses.h,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv27487/Include Modified Files: py_curses.h Log Message: Check for HP/UX curses problems. Define _XOPEN_SOURCE_EXTENDED and STRICT_SYSV_CURSES when compiling curses module on HP/UX. Generalize access to _flags on systems where WINDOW is opaque. Fixes bugs #432497, #422265, and the curses parts of #467145 and #473150. Index: py_curses.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/py_curses.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** py_curses.h 2001/10/13 09:12:41 1.2 --- py_curses.h 2001/10/24 17:10:49 1.3 *************** *** 13,16 **** --- 13,27 ---- #endif + #ifdef HAVE_NCURSES_H + /* configure was checking , but we will + use , which has all these features. */ + #ifndef WINDOW_HAS_FLAGS + #define WINDOW_HAS_FLAGS 1 + #endif + #ifndef MVWDELCH_IS_EXPRESSION + #define MVWDELCH_IS_EXPRESSION 1 + #endif + #endif + #ifdef __cplusplus extern "C" { From loewis@users.sourceforge.net Wed Oct 24 18:10:51 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 24 Oct 2001 10:10:51 -0700 Subject: [Python-checkins] CVS: python/dist/src acconfig.h,1.57,1.58 configure.in,1.277,1.278 pyconfig.h.in,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv27487 Modified Files: acconfig.h configure.in pyconfig.h.in Log Message: Check for HP/UX curses problems. Define _XOPEN_SOURCE_EXTENDED and STRICT_SYSV_CURSES when compiling curses module on HP/UX. Generalize access to _flags on systems where WINDOW is opaque. Fixes bugs #432497, #422265, and the curses parts of #467145 and #473150. Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.57 retrieving revision 1.58 diff -C2 -d -r1.57 -r1.58 *** acconfig.h 2001/09/30 21:09:58 1.57 --- acconfig.h 2001/10/24 17:10:49 1.58 *************** *** 233,236 **** --- 233,242 ---- #undef WITH_THREAD + /* Define if mvwdelch in curses.h is an expression. */ + #undef MVWDELCH_IS_EXPRESSION + + /* Define if WINDOW in curses.h offers a field _flags. */ + #undef WINDOW_HAS_FLAGS + /* Leave that blank line there-- autoheader needs it! */ Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.277 retrieving revision 1.278 diff -C2 -d -r1.277 -r1.278 *** configure.in 2001/10/24 14:35:59 1.277 --- configure.in 2001/10/24 17:10:49 1.278 *************** *** 1964,1967 **** --- 1964,1999 ---- fi + # On HP/UX 11.0, mvwdelch is a block with a return statement + AC_MSG_CHECKING(whether mvwdelch is an expression) + AC_CACHE_VAL(ac_cv_mvwdelch_is_expression, + AC_TRY_COMPILE([#include ], [ + int rtn; + rtn = mvwdelch(0,0,0); + ], ac_cv_mvwdelch_is_expression=yes, + ac_cv_mvwdelch_is_expression=no, + ac_cv_mvwdelch_is_expression=yes)) + AC_MSG_RESULT($ac_cv_mvwdelch_is_expression) + + if test "$ac_cv_mvwdelch_is_expression" = yes + then + AC_DEFINE(MVWDELCH_IS_EXPRESSION) + fi + + AC_MSG_CHECKING(whether WINDOW has _flags) + AC_CACHE_VAL(ac_cv_window_has_flags, + AC_TRY_COMPILE([#include ], [ + WINDOW *w; + w->_flags = 0; + ], ac_cv_window_has_flags=yes, + ac_cv_window_has_flags=no, + ac_cv_window_has_flags=no)) + AC_MSG_RESULT($ac_cv_window_has_flags) + + + if test "$ac_cv_window_has_flags" = yes + then + AC_DEFINE(WINDOW_HAS_FLAGS) + fi + # THIS MUST BE LAST, IT CAN BREAK OTHER TESTS! # Add sys/socket.h to confdefs.h Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** pyconfig.h.in 2001/10/19 01:31:59 1.19 --- pyconfig.h.in 2001/10/24 17:10:49 1.20 *************** *** 289,292 **** --- 289,298 ---- #undef WITH_THREAD + /* Define if mvwdelch in curses.h is an expression. */ + #undef MVWDELCH_IS_EXPRESSION + + /* Define if WINDOW in curses.h offers a field _flags. */ + #undef WINDOW_HAS_FLAGS + /* The number of bytes in a char. */ #undef SIZEOF_CHAR From loewis@users.sourceforge.net Wed Oct 24 18:10:51 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 24 Oct 2001 10:10:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _cursesmodule.c,2.57,2.58 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv27487/Modules Modified Files: _cursesmodule.c Log Message: Check for HP/UX curses problems. Define _XOPEN_SOURCE_EXTENDED and STRICT_SYSV_CURSES when compiling curses module on HP/UX. Generalize access to _flags on systems where WINDOW is opaque. Fixes bugs #432497, #422265, and the curses parts of #467145 and #473150. Index: _cursesmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_cursesmodule.c,v retrieving revision 2.57 retrieving revision 2.58 diff -C2 -d -r2.57 -r2.58 *** _cursesmodule.c 2001/10/20 16:05:52 2.57 --- _cursesmodule.c 2001/10/24 17:10:49 2.58 *************** *** 108,111 **** --- 108,116 ---- #endif + #ifdef __hpux + #define _XOPEN_SOURCE_EXTENDED + #define STRICT_SYSV_CURSES + #endif + #define CURSES_MODULE #include "py_curses.h" *************** *** 120,124 **** #endif ! #if defined(sgi) || defined(__sun) #define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ typedef chtype attr_t; /* No attr_t type is available */ --- 125,129 ---- #endif ! #if !defined(HAVE_NCURSES_H) && (defined(sgi) || defined(__sun)) #define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ typedef chtype attr_t; /* No attr_t type is available */ *************** *** 606,609 **** --- 611,627 ---- } + #if defined(HAVE_NCURSES_H) || defined(MVWDELCH_IS_EXPRESSION) + #define py_mvwdelch mvwdelch + #else + int py_mvwdelch(WINDOW *w, int y, int x) + { + mvwdelch(w,y,x); + /* On HP/UX, mvwdelch already returns. On other systems, + we may well run into this return statement. */ + return 0; + } + #endif + + static PyObject * PyCursesWindow_DelCh(PyCursesWindowObject *self, PyObject *args) *************** *** 619,623 **** if (!PyArg_Parse(args,"(ii);y,x", &y, &x)) return NULL; ! rtn = mvwdelch(self->win,y,x); break; default: --- 637,641 ---- if (!PyArg_Parse(args,"(ii);y,x", &y, &x)) return NULL; ! rtn = py_mvwdelch(self->win,y,x); break; default: *************** *** 689,693 **** } ! #if !defined(__NetBSD__) if (self->win->_flags & _ISPAD) return PyCursesCheckERR(pechochar(self->win, ch | attr), --- 707,711 ---- } ! #ifdef WINDOW_HAS_FLAGS if (self->win->_flags & _ISPAD) return PyCursesCheckERR(pechochar(self->win, ch | attr), *************** *** 1095,1099 **** int rtn; ! #if defined(__NetBSD__) if (0) { #else --- 1113,1117 ---- int rtn; ! #ifndef WINDOW_HAS_FLAGS if (0) { #else *************** *** 1237,1241 **** int rtn; ! #if defined(__NetBSD__) if (0) { #else --- 1255,1259 ---- int rtn; ! #ifndef WINDOW_HAS_FLAGS if (0) { #else *************** *** 1305,1309 **** /* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */ ! #if !defined(__NetBSD__) if (self->win->_flags & _ISPAD) win = subpad(self->win, nlines, ncols, begin_y, begin_x); --- 1323,1327 ---- /* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */ ! #ifdef WINDOW_HAS_FLAGS if (self->win->_flags & _ISPAD) win = subpad(self->win, nlines, ncols, begin_y, begin_x); *************** *** 1833,1836 **** --- 1851,1859 ---- SetDictInt("ACS_VLINE", (ACS_VLINE)); SetDictInt("ACS_PLUS", (ACS_PLUS)); + #if !defined(__hpux) || defined(HAVE_NCURSES_H) + /* On HP/UX 11, these are of type cchar_t, which is not an + integral type. If this is a problem on more platforms, a + configure test should be added to determine whether ACS_S1 + is of integral type. */ SetDictInt("ACS_S1", (ACS_S1)); SetDictInt("ACS_S9", (ACS_S9)); *************** *** 1847,1850 **** --- 1870,1874 ---- SetDictInt("ACS_LANTERN", (ACS_LANTERN)); SetDictInt("ACS_BLOCK", (ACS_BLOCK)); + #endif SetDictInt("ACS_BSSB", (ACS_ULCORNER)); SetDictInt("ACS_SSBB", (ACS_LLCORNER)); *************** *** 2287,2290 **** --- 2311,2323 ---- } + #ifdef __hpux + /* tparm is declared with 10 arguments on HP/UX 11. + If this is a problem on other platforms as well, + an autoconf test should be added to determine + whether tparm can be called with a variable number + of arguments. Perhaps the other arguments should + be initialized in this case also. */ + result = tparm(fmt,i1,i2,i3,i4,i5,i6,i7,i8,i9); + #else switch (PyTuple_GET_SIZE(args)) { case 1: *************** *** 2319,2323 **** break; } ! return PyString_FromString(result); } --- 2352,2356 ---- break; } ! #endif /* __hpux */ return PyString_FromString(result); } From loewis@users.sourceforge.net Wed Oct 24 18:35:48 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 24 Oct 2001 10:35:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.184,1.185 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv2688 Modified Files: socketmodule.c Log Message: Fix typo. Thanks to Jack Jansen for spotting it. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.184 retrieving revision 1.185 diff -C2 -d -r1.184 -r1.185 *** socketmodule.c 2001/10/24 14:36:00 1.184 --- socketmodule.c 2001/10/24 17:35:46 1.185 *************** *** 623,627 **** hints.ai_family = af; error = getaddrinfo(name, NULL, &hints, &res); ! if (error = EAI_NONAME && af == AF_UNSPEC) { /* On OSF/1 V5.1, numeric-to-addr conversion fails if no address family is given. Assume IPv4 for now.*/ --- 623,627 ---- hints.ai_family = af; error = getaddrinfo(name, NULL, &hints, &res); ! if (error == EAI_NONAME && af == AF_UNSPEC) { /* On OSF/1 V5.1, numeric-to-addr conversion fails if no address family is given. Assume IPv4 for now.*/ From loewis@informatik.hu-berlin.de Wed Oct 24 18:36:43 2001 From: loewis@informatik.hu-berlin.de (Martin von Loewis) Date: Wed, 24 Oct 2001 19:36:43 +0200 (MEST) Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.183,1.184 In-Reply-To: <20011024145248.75BFB303181@snelboot.oratrix.nl> (message from Jack Jansen on Wed, 24 Oct 2001 16:52:48 +0200) References: <20011024145248.75BFB303181@snelboot.oratrix.nl> Message-ID: <200110241736.TAA24296@paros.informatik.hu-berlin.de> > are you sure about this fix? The > if (error = EAI_NONAME > bit looks suspicious... Arghh. Even after the obvious correction, it still fixes the problem, fortunately. Thanks a lot, Martin From fdrake@users.sourceforge.net Wed Oct 24 20:50:33 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 24 Oct 2001 12:50:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref6.tex,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv6131/ref Modified Files: ref6.tex Log Message: When describing "import *", add a level of indirection between "*" and the set of names imported (the "public names"), adding a definition of "public names" that describes the use of __all__. This closes SF bug #473986. Flesh out the vague reference to __import__(). Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** ref6.tex 2001/07/06 22:49:53 1.41 --- ref6.tex 2001/10/24 19:50:31 1.42 *************** *** 604,612 **** supplied by specifying "\keyword{as} localname". If a name is not found, \exception{ImportError} is raised. If the list of identifiers is replaced ! by a star (\samp{*}), all names defined in the module are bound, except ! those beginning with an underscore (\character{_}). \indexii{name}{binding} \exindex{ImportError} Names bound by \keyword{import} statements may not occur in \keyword{global} statements in the same scope. --- 604,621 ---- supplied by specifying "\keyword{as} localname". If a name is not found, \exception{ImportError} is raised. If the list of identifiers is replaced ! by a star (\character{*}), all public names defined in the module are ! bound in the local namespace of the \keyword{import} statement.. \indexii{name}{binding} \exindex{ImportError} + The \emph{public names} defined by a module are determined by checking + the module's namespace for a variable named \code{__all__}; if + defined, it must be a sequence of strings which are names defined or + imported by that module. The names given in \code{__all__} are all + considered public and are required to exist. If \code{__all__} is not + defined, the set of public names includes all names found in the + module's namespace which do not begin with an underscore character + (\character{_}). + Names bound by \keyword{import} statements may not occur in \keyword{global} statements in the same scope. *************** *** 629,633 **** about how the module search works from inside a package.] ! [XXX Also should mention __import__().] \bifuncindex{__import__} --- 638,647 ---- about how the module search works from inside a package.] ! The built-in function \function{__import__()} is provided to support ! applications that determine which modules need to be loaded ! dynamically; refer to \ulink{Built-in ! Functions}{../lib/built-in-funcs.html} in the ! \citetitle[../lib/lib.html]{Python Library Reference} for additional ! information. \bifuncindex{__import__} From fdrake@users.sourceforge.net Wed Oct 24 20:52:16 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 24 Oct 2001 12:52:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref6.tex,1.37,1.37.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv6583/ref Modified Files: Tag: release21-maint ref6.tex Log Message: When describing "import *", add a level of indirection between "*" and the set of names imported (the "public names"), adding a definition of "public names" that describes the use of __all__. This closes SF bug #473986. Flesh out the vague reference to __import__(). Index: ref6.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref6.tex,v retrieving revision 1.37 retrieving revision 1.37.2.1 diff -C2 -d -r1.37 -r1.37.2.1 *** ref6.tex 2001/04/13 15:55:25 1.37 --- ref6.tex 2001/10/24 19:52:14 1.37.2.1 *************** *** 567,575 **** supplied by specifying "\keyword{as} localname". If a name is not found, \exception{ImportError} is raised. If the list of identifiers is replaced ! by a star (\samp{*}), all names defined in the module are bound, except ! those beginning with an underscore (\character{_}). \indexii{name}{binding} \exindex{ImportError} Names bound by \keyword{import} statements may not occur in \keyword{global} statements in the same scope. --- 567,584 ---- supplied by specifying "\keyword{as} localname". If a name is not found, \exception{ImportError} is raised. If the list of identifiers is replaced ! by a star (\character{*}), all public names defined in the module are ! bound in the local namespace of the \keyword{import} statement.. \indexii{name}{binding} \exindex{ImportError} + The \emph{public names} defined by a module are determined by checking + the module's namespace for a variable named \code{__all__}; if + defined, it must be a sequence of strings which are names defined or + imported by that module. The names given in \code{__all__} are all + considered public and are required to exist. If \code{__all__} is not + defined, the set of public names includes all names found in the + module's namespace which do not begin with an underscore character + (\character{_}). + Names bound by \keyword{import} statements may not occur in \keyword{global} statements in the same scope. *************** *** 592,596 **** about how the module search works from inside a package.] ! [XXX Also should mention __import__().] \bifuncindex{__import__} --- 601,610 ---- about how the module search works from inside a package.] ! The built-in function \function{__import__()} is provided to support ! applications that determine which modules need to be loaded ! dynamically; refer to \ulink{Built-in ! Functions}{../lib/built-in-funcs.html} in the ! \citetitle[../lib/lib.html]{Python Library Reference} for additional ! information. \bifuncindex{__import__} From gvanrossum@users.sourceforge.net Wed Oct 24 21:04:53 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 24 Oct 2001 13:04:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/RISCOS Makefile,1.2,1.3 pyconfig.h,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/RISCOS In directory usw-pr-cvs1:/tmp/cvs-serv9204 Modified Files: Makefile pyconfig.h Log Message: SF patch #474590 -- RISC OS support Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/RISCOS/Makefile,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Makefile 2001/04/10 22:03:33 1.2 --- Makefile 2001/10/24 20:04:51 1.3 *************** *** 5,9 **** OSLIB = $(LIBSROOT).OSLib CLIB = $(LIBSROOT).clib ! SOCKLIB = $(LIBSROOT).netlib DLKLIB = $(LIBSROOT).dlk ZLIB = $(LIBSROOT).zlib --- 5,9 ---- OSLIB = $(LIBSROOT).OSLib CLIB = $(LIBSROOT).clib ! TCPIPLIB = $(LIBSROOT).TCPIPLibs DLKLIB = $(LIBSROOT).dlk ZLIB = $(LIBSROOT).zlib *************** *** 14,19 **** # change from time to time (don't forget to change !Boot also) ! TARGET=Python21 ! BUILD=12 --- 14,19 ---- # change from time to time (don't forget to change !Boot also) ! TARGET=Python22 ! BUILD=23 *************** *** 21,52 **** # You shouldn't need to change anything below this line # - OSLIBS = OSLib:Computer,OSLib:Core,OSLib:User - DLKFLAG= -DDLK DLKOBJS = $(DLKLIB).o.dlk_load @.o.linktab ! HEADERS = @,@.^.Include,@.^.Modules,@.^.Objects,@.^.Python,$(CLIB),$(OSLIBS),$(DLKLIB) ! CC = cc -c -j$(HEADERS) $(DLKFLAG) -DRISCOS -DHAVE_CONFIG_H -wad -throwback ! #-depend !Depend ! CCEXPAT = cc -c -j$(HEADERS),$(EXPAT) $(DLKFLAG) -DHAVE_EXPAT_H -DRISCOS -DHAVE_CONFIG_H -wad -throwback LINK = link LINKFLAGS = -aif #-NOUNUSED #-d ! LOADLIBS = $(CLIB).o.Stubs $(OSLIB).o.OSLib $(DLKOBJS) .c.o : $(CC) -o $@ $*.c # code for main Python binary MODULES_STATIC =\ - @.^.Modules.o.python\ @.^.Modules.o.main\ ! Modules.o.config\ @.^.Modules.o.getbuildinfo\ ! Modules.o.getpath_riscos\ ! Modules.o.riscosmodule --- 21,58 ---- # You shouldn't need to change anything below this line # DLKFLAG= -DDLK DLKOBJS = $(DLKLIB).o.dlk_load @.o.linktab ! HEADERS = @,$(TCPIPLIB),@.^.Include,@.^.Modules,@.^.Objects,@.^.Python,$(CLIB),$(OSLIB),$(DLKLIB) ! CFLAGS = -c $(DLKFLAG) -DRISCOS -DHAVE_CONFIG_H -wadP -throwback -APCS 3/32bit/fpe3 + CC = cc $(CFLAGS) -j$(HEADERS) + CCEXPAT = cc $(CFLAGS) -j$(HEADERS),$(EXPAT) -DHAVE_EXPAT_H + LINK = link LINKFLAGS = -aif #-NOUNUSED #-d ! LOADLIBS = $(TCPIPLIB).o.unixlib $(TCPIPLIB).o.inetlib $(TCPIPLIB).o.socklib $(CLIB).o.Stubs $(OSLIB).o.OSLib32 $(DLKOBJS) + LIBFILE = libfile -c + .c.o : $(CC) -o $@ $*.c + MAIN_PYTHON =\ + @.^.Modules.o.python + LIB_PYTHON =\ + @.^.LibPython + # code for main Python binary MODULES_STATIC =\ @.^.Modules.o.main\ ! @.Modules.o.config\ @.^.Modules.o.getbuildinfo\ ! @.Modules.o.getpath_riscos\ ! @.Modules.o.riscosmodule\ ! @.^.Modules.o.gcmodule *************** *** 86,90 **** @.^.Lib.plat-riscos.drawf/pyd\ @.^.Lib.plat-riscos.swi/pyd\ ! @.^.Lib._sre/pyd --- 92,98 ---- @.^.Lib.plat-riscos.drawf/pyd\ @.^.Lib.plat-riscos.swi/pyd\ ! @.^.Lib._sre/pyd\ ! @.^.Lib.xxsubtype/pyd\ ! @.^.Lib._symtable/pyd *************** *** 99,102 **** --- 107,111 ---- @.^.Python.o.pyfpe\ @.^.Python.o.mystrtoul\ + @.^.Python.o.mysnprintf\ @.^.Python.o.modsupport\ @.^.Python.o.marshal\ *************** *** 142,145 **** --- 151,155 ---- @.^.Objects.o.listobject\ @.^.Objects.o.intobject\ + @.^.Objects.o.iterobject\ @.^.Objects.o.funcobject\ @.^.Objects.o.frameobject\ *************** *** 154,158 **** @.^.Objects.o.abstract\ @.^.Objects.o.unicodectype\ ! @.^.Objects.o.unicodeobject --- 164,169 ---- @.^.Objects.o.abstract\ @.^.Objects.o.unicodectype\ ! @.^.Objects.o.unicodeobject\ ! @.^.Objects.o.descrobject *************** *** 184,190 **** ! @.^.$(TARGET): $(OBJECTS) o.linktab ! $(LINK) -o @.^.$(TARGET) $(OBJECTS) $(LOADLIBS) ######################################################################### --- 195,204 ---- ! $(LIB_PYTHON): $(OBJECTS) ! $(LIBFILE) $(LIB_PYTHON) $(OBJECTS) + @.^.$(TARGET): o.linktab $(MAIN_PYTHON) $(LIB_PYTHON) + $(LINK) -o @.^.$(TARGET) $(MAIN_PYTHON) @.^.LibPython $(LOADLIBS) + ######################################################################### *************** *** 230,234 **** @.^.Lib.plat-riscos.drawf/pyd: Modules.o.drawfmodule #s.linktab ! $(LINK) -aof -o Modules.o.drawflink Modules.o.drawfmodule $(OSLIB).o.OSLIB $(MAKEDLK) -d @.^.Lib.plat-riscos.drawf/pyd -s s.linktab -o Modules.o.drawflink -e initdrawf --- 244,248 ---- @.^.Lib.plat-riscos.drawf/pyd: Modules.o.drawfmodule #s.linktab ! $(LINK) -aof -o Modules.o.drawflink Modules.o.drawfmodule $(OSLIB).o.OSLIB32 $(MAKEDLK) -d @.^.Lib.plat-riscos.drawf/pyd -s s.linktab -o Modules.o.drawflink -e initdrawf *************** *** 278,284 **** $(MAKEDLK) -d @.^.Lib.signal/pyd -s s.linktab -o @.^.Modules.o.signalmodule -e initsignal - #@.^.Lib.soundex/pyd: @.^.Modules.o.soundex s.linktab - # $(MAKEDLK) -d @.^.Lib.soundex/pyd -s s.linktab -o @.^.Modules.o.soundex -e initsoundex - @.^.Lib.strop/pyd: @.^.Modules.o.stropmodule s.linktab $(MAKEDLK) -d @.^.Lib.strop/pyd -s s.linktab -o @.^.Modules.o.stropmodule -e initstrop --- 292,295 ---- *************** *** 288,292 **** @.^.Lib.plat-riscos.swi/pyd: Modules.o.swimodule s.linktab ! $(LINK) -aof -o Modules.o.swilink Modules.o.swimodule $(OSLIB).o.OSLIB $(MAKEDLK) -d @.^.Lib.plat-riscos.swi/pyd -s s.linktab -o Modules.o.swilink -e initswi --- 299,303 ---- @.^.Lib.plat-riscos.swi/pyd: Modules.o.swimodule s.linktab ! $(LINK) -aof -o Modules.o.swilink Modules.o.swimodule $(OSLIB).o.OSLIB32 $(MAKEDLK) -d @.^.Lib.plat-riscos.swi/pyd -s s.linktab -o Modules.o.swilink -e initswi *************** *** 312,337 **** $(MAKEDLK) -d @.^.Lib.xreadlines/pyd -s s.linktab -o @.^.Modules.o.xreadlinesmodule -e initxreadlines ############################################################################ # Dynamic Modules with other dependencies # @.^.Lib.select/pyd: @.^.Modules.o.selectmodule s.linktab ! $(LINK) -aof -o @.^.Modules.o.selectlink @.^.Modules.o.selectmodule $(SOCKLIB).o.socklib $(MAKEDLK) -d @.^.Lib.select/pyd -s s.linktab -o @.^.Modules.o.selectlink -e initselect @.^.Modules.o.selectmodule: @.^.Modules.c.selectmodule ! $(CC) -I$(SOCKLIB).include -o $@ @.^.Modules.c.selectmodule @.^.Lib._socket/pyd: @.^.Modules.o.socketmodule s.linktab ! $(LINK) -aof -o @.^.Modules.o._socketlink @.^.Modules.o.socketmodule $(SOCKLIB).o.inetlib $(SOCKLIB).o.unixlib $(SOCKLIB).o.socklib $(MAKEDLK) -d @.^.Lib._socket/pyd -s s.linktab -o @.^.Modules.o._socketlink -e init_socket @.^.Modules.o.socketmodule: @.^.Modules.c.socketmodule ! $(CC) -I$(SOCKLIB).include -o $@ @.^.Modules.c.socketmodule @.^.Lib.zlib/pyd: @.^.Modules.o.zlibmodule s.linktab ! $(LINK) -aof -o @.^.Modules.o.zliblink @.^.Modules.o.zlibmodule $(ZLIB).zlib_lib $(MAKEDLK) -d @.^.Lib.zlib/pyd -s s.linktab -o @.^.Modules.o.zliblink -e initzlib --- 323,353 ---- $(MAKEDLK) -d @.^.Lib.xreadlines/pyd -s s.linktab -o @.^.Modules.o.xreadlinesmodule -e initxreadlines + @.^.Lib.xxsubtype/pyd: @.^.Modules.o.xxsubtype s.linktab + $(MAKEDLK) -d @.^.Lib.xxsubtype/pyd -s s.linktab -o @.^.Modules.o.xxsubtype -e initxxsubtype + @.^.Lib._symtable/pyd: @.^.Modules.o.symtablemodule s.linktab + $(MAKEDLK) -d @.^.Lib._symtable/pyd -s s.linktab -o @.^.Modules.o.symtablemodule -e init_symtable + ############################################################################ # Dynamic Modules with other dependencies # @.^.Lib.select/pyd: @.^.Modules.o.selectmodule s.linktab ! $(LINK) -aof -o @.^.Modules.o.selectlink @.^.Modules.o.selectmodule $(TCPIPLIB).o.socklib $(MAKEDLK) -d @.^.Lib.select/pyd -s s.linktab -o @.^.Modules.o.selectlink -e initselect @.^.Modules.o.selectmodule: @.^.Modules.c.selectmodule ! $(CC) -I$(TCPIPLIB).include -o $@ @.^.Modules.c.selectmodule @.^.Lib._socket/pyd: @.^.Modules.o.socketmodule s.linktab ! $(LINK) -aof -o @.^.Modules.o._socketlink @.^.Modules.o.socketmodule $(TCPIPLIB).o.inetlib $(TCPIPLIB).o.unixlib $(TCPIPLIB).o.socklib $(MAKEDLK) -d @.^.Lib._socket/pyd -s s.linktab -o @.^.Modules.o._socketlink -e init_socket @.^.Modules.o.socketmodule: @.^.Modules.c.socketmodule ! $(CC) -I$(TCPIPLIB).include -o $@ @.^.Modules.c.socketmodule @.^.Lib.zlib/pyd: @.^.Modules.o.zlibmodule s.linktab ! $(LINK) -aof -o @.^.Modules.o.zliblink @.^.Modules.o.zlibmodule $(ZLIB).zlib $(MAKEDLK) -d @.^.Lib.zlib/pyd -s s.linktab -o @.^.Modules.o.zliblink -e initzlib *************** *** 341,348 **** @.^.Lib.time/pyd: @.^.Modules.o.timemodule s.linktab @.o.sleep ! $(LINK) -aof -o @.^.Modules.o.timelink @.^.Modules.o.timemodule @.o.sleep $(OSLIB).o.OSLib $(MAKEDLK) -d @.^.Lib.time/pyd -s s.linktab -o @.^.Modules.o.timelink -e inittime @.^.Lib.pyexpat/pyd: @.^.Modules.o.pyexpat s.linktab $(LINK) -aof -o @.^.Modules.o.pyexpatlink @.^.Modules.o.pyexpat $(EXPAT).expat_lib --- 357,368 ---- @.^.Lib.time/pyd: @.^.Modules.o.timemodule s.linktab @.o.sleep ! $(LINK) -aof -o @.^.Modules.o.timelink @.^.Modules.o.timemodule @.o.sleep $(OSLIB).o.OSLib32 $(MAKEDLK) -d @.^.Lib.time/pyd -s s.linktab -o @.^.Modules.o.timelink -e inittime + #@.^.Lib.time/pyd: @.Modules.o.timemodule s.linktab + # $(LINK) -aof -o @.Modules.o.timelink @.Modules.o.timemodule $(OSLIB).o.OSLib32 + # $(MAKEDLK) -d @.^.Lib.time/pyd -s s.linktab -o @.Modules.o.timelink -e inittime + @.^.Lib.pyexpat/pyd: @.^.Modules.o.pyexpat s.linktab $(LINK) -aof -o @.^.Modules.o.pyexpatlink @.^.Modules.o.pyexpat $(EXPAT).expat_lib *************** *** 357,361 **** # o.linktab: s.linktab ! ObjAsm s.linktab o.linktab s.linktab: $(OBJECTS) --- 377,381 ---- # o.linktab: s.linktab ! ObjAsm -APCS 3/32bit s.linktab o.linktab s.linktab: $(OBJECTS) *************** *** 366,405 **** # libclean: ! create @.^.Lib.dummy/pyc ! create @.^.Lib.dummy/pyo ! create @.^.Lib.plat-riscos.dummy/pyc ! create @.^.Lib.plat-riscos.dummy/pyo ! create @.^.Lib.test.dummy/pyc ! create @.^.Lib.test.dummy/pyo ! wipe @.^.Lib.*/pyc ~C~V ! wipe @.^.Lib.*/pyo ~C~V ! wipe @.^.Lib.plat-riscos.*/pyc ~C~V ! wipe @.^.Lib.plat-riscos.*/pyo ~C~V ! wipe @.^.Lib.test.*/pyc ~C~V ! wipe @.^.Lib.test.*/pyo ~C~V clean: libclean ! create @.^.Objects.o.dummy ! create @.^.Parser.o.dummy ! create @.^.Modules.o.dummy ! create o.dummy ! create @.^.Python.o.dummy ! wipe @.^.Modules.o.* ~C ~V ! wipe @.^.Objects.o.* ~C ~V ! wipe @.^.Parser.o.* ~C ~V ! wipe @.^.Python.o.* ~C ~V ! wipe o.* ~C ~V ! rebuild: clean ! create @.^.Lib.dummy/pyd ! create @.^.$(TARGET) ! create @.^.Lib.plat-riscos.dummy/pyd ! create s.linktab ! create o.linktab ! wipe @.^.$(TARGET) ~C~V ! wipe @.^.Lib.*/pyd ~C ~V ! wipe @.^.Lib.plat-riscos.*/pyd ~C~V ! wipe s.linktab ~C~V ! wipe o.linktab ~C~V cdirs: --- 386,426 ---- # libclean: ! -wipe @.^.Lib.*/pyc ~C~V ! -wipe @.^.Lib.*/pyo ~C~V ! -wipe @.^.Lib.plat-riscos.*/pyc ~C~V ! -wipe @.^.Lib.plat-riscos.*/pyo ~C~V ! -wipe @.^.Lib.test.*/pyc ~C~V ! -wipe @.^.Lib.test.*/pyo ~C~V ! -wipe @.^.Lib.encodings.*/pyc ~C~V ! -wipe @.^.Lib.encodings.*/pyo ~C~V ! -wipe @.^.Lib.curses.*/pyc ~C~V ! -wipe @.^.Lib.curses.*/pyo ~C~V ! -wipe @.^.Lib.xml.*/pyc ~C~V ! -wipe @.^.Lib.xml.*/pyo ~C~V ! -wipe @.^.Lib.xml.sax.*/pyc ~C~V ! -wipe @.^.Lib.xml.sax.*/pyo ~C~V ! -wipe @.^.Lib.xml.dom.*/pyc ~C~V ! -wipe @.^.Lib.xml.dom.*/pyo ~C~V ! -wipe @.^.Lib.xml.parsers.*/pyc ~C~V ! -wipe @.^.Lib.xml.parsers.*/pyo ~C~V clean: libclean ! -wipe @.^.Modules.o.* ~C~V ! -wipe @.^.Objects.o.* ~C~V ! -wipe @.^.Parser.o.* ~C~V ! -wipe @.^.Python.o.* ~C~V ! -wipe @.Modules.o.* ~C~V ! -wipe @.Python.o.* ~C~V ! -wipe @.o.* ~C ~V ! rebuild: clean clean-support ! remove @.^.$(TARGET) ! -wipe @.^.Lib.*/pyd ~C ~V ! -wipe @.^.Lib.plat-riscos.*/pyd ~C~V ! remove s.linktab ! ! clean-support: ! -wipe @.^.!* ~C~V ! remove @.^.AddToPath cdirs: Index: pyconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/RISCOS/pyconfig.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pyconfig.h 2001/07/26 13:41:06 1.1 --- pyconfig.h 2001/10/24 20:04:51 1.2 *************** *** 1,3 **** ! /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if on AIX 3. --- 1,3 ---- ! /* RISCOS/pyconfig.h: Python configuration for RISC OS */ /* Define if on AIX 3. *************** *** 9,13 **** --- 9,15 ---- /* Define if type char is unsigned and you are not using gcc. */ + #ifndef __CHAR_UNSIGNED__ #undef __CHAR_UNSIGNED__ + #endif /* Define to empty if the keyword does not work. */ *************** *** 15,19 **** /* Define to `int' if doesn't define. */ ! #define gid_t int /* Define if your struct tm has tm_zone. */ --- 17,21 ---- /* Define to `int' if doesn't define. */ ! #undef gid_t /* Define if your struct tm has tm_zone. */ *************** *** 28,38 **** /* Define to `int' if doesn't define. */ ! #define mode_t int /* Define to `long' if doesn't define. */ ! #define off_t long /* Define to `int' if doesn't define. */ ! #define pid_t int /* Define if the system does not provide POSIX.1 features except --- 30,40 ---- /* Define to `int' if doesn't define. */ ! #undef mode_t /* Define to `long' if doesn't define. */ ! #undef off_t /* Define to `int' if doesn't define. */ ! #undef pid_t /* Define if the system does not provide POSIX.1 features except *************** *** 59,63 **** /* Define to `int' if doesn't define. */ ! #define uid_t int /* Define if your contains bad prototypes for exec*() --- 61,73 ---- /* Define to `int' if doesn't define. */ ! #undef uid_t ! ! /* Define if your processor stores words with the most significant ! byte first (like Motorola and SPARC, unlike Intel and VAX). */ ! #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*() *************** *** 78,86 **** #undef clock_t ! /* Used for BeOS configuration */ ! #undef DL_EXPORT_HEADER ! #ifdef DL_EXPORT_HEADER ! #include DL_EXPORT_HEADER ! #endif /* Define if getpgrp() must be called as getpgrp(0). */ --- 88,96 ---- #undef clock_t ! /* Defined on Solaris to see additional function prototypes. */ ! #undef __EXTENSIONS__ ! ! /* This must be set to 64 on some systems to enable large file support */ ! #undef _FILE_OFFSET_BITS /* Define if getpgrp() must be called as getpgrp(0). */ *************** *** 94,97 **** --- 104,125 ---- #undef HAVE_ALTZONE + /* Define if --enable-ipv6 is specified */ + #undef ENABLE_IPV6 + + /* Define if sockaddr has sa_len member */ + #undef HAVE_SOCKADDR_SA_LEN + + /* struct addrinfo (netdb.h) */ + #undef HAVE_ADDRINFO + + /* struct sockaddr_storage (sys/socket.h) */ + #undef HAVE_SOCKADDR_STORAGE + + /* Defined when any dynamic module loading is enabled */ + #define HAVE_DYNAMIC_LOADING 1 + + /* 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 *************** *** 106,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 a K&R style C preprocessor */ - #undef HAVE_OLD_CPP - /* Define if your compiler supports function prototypes */ #define HAVE_PROTOTYPES 1 /* Define if your compiler supports variable length function prototypes (e.g. void fprintf(FILE *, char *, ...);) *and* */ #define HAVE_STDARG_PROTOTYPES 1 /* Define if malloc(0) returns a NULL pointer */ #undef MALLOC_ZERO_RETURNS_NULL --- 134,188 ---- #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 */ #define HAVE_PROTOTYPES 1 + /* Define if you have GNU PTH threads */ + #undef HAVE_PTH + + /* Define if you have readline 4.2 */ + #undef HAVE_RL_COMPLETION_MATCHES + /* Define if your compiler supports variable length function prototypes (e.g. void fprintf(FILE *, char *, ...);) *and* */ #define HAVE_STDARG_PROTOTYPES 1 + /* 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 + + /* This must be defined on some systems to enable large file support */ + #undef _LARGEFILE_SOURCE + + /* Define if you want to have a Unicode type. */ + #define Py_USING_UNICODE 1 + + /* Define as the integral type used for Unicode representation. */ + #define PY_UNICODE_TYPE unsigned short + + /* Define as the size of the unicode type. */ + #define Py_UNICODE_SIZE 2 + + /* Define if nice() returns success/failure instead of the new priority. */ + #undef HAVE_BROKEN_NICE + /* Define if malloc(0) returns a NULL pointer */ #undef MALLOC_ZERO_RETURNS_NULL *************** *** 125,128 **** --- 191,197 ---- #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 *************** *** 134,137 **** --- 203,223 ---- #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. */ + #define SIZEOF_OFF_T 4 + + /* The number of bytes in a time_t. */ + #define SIZEOF_TIME_T 4 + + /* The number of bytes in a pthread_t. */ + #undef SIZEOF_PTHREAD_T + + /* Define to `int' if doesn't define. */ + #define socklen_t int + /* Define if you can safely include both and (which you can't on SCO ODT 3.0). */ *************** *** 147,156 **** #undef WANT_SIGFPE_HANDLER ! /* 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. --- 233,242 ---- #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 */ ! #define WITH_CYCLE_GC 1 /* Define if you want to emulate SGI (IRIX 4) dynamic linking. *************** *** 162,166 **** ftp://ftp.cwi.nl/pub/dynload/dld-3.2.3.tar.Z. Don't bother on SunOS 4 or 5, they already have dynamic linking using ! shared libraries */ #undef WITH_DL_DLD --- 248,252 ---- ftp://ftp.cwi.nl/pub/dynload/dld-3.2.3.tar.Z. Don't bother on SunOS 4 or 5, they already have dynamic linking using ! shared libraries */ #undef WITH_DL_DLD *************** *** 170,175 **** #undef WITH_DYLD ! /* Define if you want to compile in rudimentary thread support */ ! #undef WITH_THREAD /* Define if you want to produce an OpenStep/Rhapsody framework --- 256,261 ---- #undef WITH_DYLD ! /* Define if you want to compile in Python-specific mallocs */ ! #undef WITH_PYMALLOC /* Define if you want to produce an OpenStep/Rhapsody framework *************** *** 177,195 **** #undef WITH_NEXT_FRAMEWORK ! /* The number of bytes in an off_t. */ ! #undef SIZEOF_OFF_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 ! /* The number of bytes in a time_t. */ ! #define SIZEOF_TIME_T 4 /* The number of bytes in a int. */ #define SIZEOF_INT 4 --- 263,291 ---- #undef WITH_NEXT_FRAMEWORK ! /* Define if you want to use MacPython modules on MacOSX in unix-Python */ ! #undef USE_TOOLBOX_OBJECT_GLUE ! /* 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. */ + #define SIZEOF_CHAR 1 + + /* The number of bytes in a double. */ + #define SIZEOF_DOUBLE 8 + + /* The number of bytes in a float. */ + #define SIZEOF_FLOAT 4 + + /* The number of bytes in a fpos_t. */ + #undef SIZEOF_FPOS_T + /* The number of bytes in a int. */ #define SIZEOF_INT 4 *************** *** 201,207 **** --- 297,315 ---- #undef SIZEOF_LONG_LONG + /* The number of bytes in a short. */ + #define SIZEOF_SHORT 2 + + /* The number of bytes in a uintptr_t. */ + #undef SIZEOF_UINTPTR_T + /* The number of bytes in a void *. */ #define SIZEOF_VOID_P 4 + /* The number of bytes in a wchar_t. */ + #undef SIZEOF_WCHAR_T + + /* Define if you have the _getpty function. */ + #undef HAVE__GETPTY + /* Define if you have the alarm function. */ #undef HAVE_ALARM *************** *** 213,216 **** --- 321,333 ---- #define HAVE_CLOCK 1 + /* Define if you have the confstr function. */ + #undef HAVE_CONFSTR + + /* Define if you have the ctermid function. */ + #undef HAVE_CTERMID + + /* Define if you have the ctermid_r function. */ + #undef HAVE_CTERMID_R + /* Define if you have the dlopen function. */ #undef HAVE_DLOPEN *************** *** 231,234 **** --- 348,357 ---- #undef HAVE_FORK + /* Define if you have the forkpty function. */ + #undef HAVE_FORKPTY + + /* Define if you have the fpathconf function. */ + #undef HAVE_FPATHCONF + /* Define if you have the fseek64 function. */ #undef HAVE_FSEEK64 *************** *** 255,261 **** --- 378,402 ---- #undef HAVE_FTRUNCATE + /* Define if you have the gai_strerror function. */ + #undef HAVE_GAI_STRERROR + + /* Define if you have the getaddrinfo function. */ + #undef HAVE_GETADDRINFO + /* Define if you have the getcwd function. */ #undef HAVE_GETCWD + /* Define if you have the getgroups function. */ + #undef HAVE_GETGROUPS + + /* Define if you have the gethostbyname function. */ + #undef HAVE_GETHOSTBYNAME + + /* Define if you have the getlogin function. */ + #undef HAVE_GETLOGIN + + /* Define if you have the getnameinfo function. */ + #undef HAVE_GETNAMEINFO + /* Define if you have the getpeername function. */ #undef HAVE_GETPEERNAME *************** *** 267,270 **** --- 408,414 ---- #undef HAVE_GETPID + /* Define if you have the getpriority function. */ + #undef HAVE_GETPRIORITY + /* Define if you have the getpwent function. */ #undef HAVE_GETPWENT *************** *** 276,282 **** --- 420,432 ---- #undef HAVE_GETWD + /* Define if you have the hstrerror function. */ + #undef HAVE_HSTRERROR + /* Define if you have the hypot function. */ #undef HAVE_HYPOT + /* Define if you have the inet_pton function. */ + #define HAVE_INET_PTON 1 + /* Define if you have the kill function. */ #undef HAVE_KILL *************** *** 297,303 **** --- 447,462 ---- #define HAVE_MKTIME 1 + /* Define if you have the mremap function. */ + #undef HAVE_MREMAP + /* Define if you have the nice function. */ #undef HAVE_NICE + /* Define if you have the openpty function. */ + #undef HAVE_OPENPTY + + /* Define if you have the pathconf function. */ + #undef HAVE_PATHCONF + /* Define if you have the pause function. */ #undef HAVE_PAUSE *************** *** 306,309 **** --- 465,471 ---- #undef HAVE_PLOCK + /* Define if you have the poll function. */ + #undef HAVE_POLL + /* Define if you have the pthread_init function. */ #undef HAVE_PTHREAD_INIT *************** *** 318,326 **** #undef HAVE_SELECT /* Define if you have the setgid function. */ #undef HAVE_SETGID /* Define if you have the setlocale function. */ ! #undef HAVE_SETLOCALE /* Define if you have the setpgid function. */ --- 480,494 ---- #undef HAVE_SELECT + /* Define if you have the setegid function. */ + #undef HAVE_SETEGID + + /* Define if you have the seteuid function. */ + #undef HAVE_SETEUID + /* Define if you have the setgid function. */ #undef HAVE_SETGID /* Define if you have the setlocale function. */ ! #define HAVE_SETLOCALE 1 /* Define if you have the setpgid function. */ *************** *** 330,333 **** --- 498,507 ---- #undef HAVE_SETPGRP + /* Define if you have the setregid function. */ + #undef HAVE_SETREGID + + /* Define if you have the setreuid function. */ + #undef HAVE_SETREUID + /* Define if you have the setsid function. */ #undef HAVE_SETSID *************** *** 348,356 **** #undef HAVE_SIGRELSE /* Define if you have the statvfs function. */ #undef HAVE_STATVFS /* Define if you have the strdup function. */ ! #undef HAVE_STRDUP /* Define if you have the strerror function. */ --- 522,533 ---- #undef HAVE_SIGRELSE + /* Define if you have the snprintf function. */ + #undef HAVE_SNPRINTF + /* Define if you have the statvfs function. */ #undef HAVE_STATVFS /* Define if you have the strdup function. */ ! #define HAVE_STRDUP 1 /* Define if you have the strerror function. */ *************** *** 366,369 **** --- 543,549 ---- #undef HAVE_SYMLINK + /* Define if you have the sysconf function. */ + #undef HAVE_SYSCONF + /* Define if you have the tcgetpgrp function. */ #undef HAVE_TCGETPGRP *************** *** 372,375 **** --- 552,558 ---- #undef HAVE_TCSETPGRP + /* Define if you have the tempnam function. */ + #undef HAVE_TEMPNAM + /* Define if you have the timegm function. */ #undef HAVE_TIMEGM *************** *** 378,381 **** --- 561,573 ---- #undef HAVE_TIMES + /* Define if you have the tmpfile function. */ + #undef HAVE_TMPFILE + + /* Define if you have the tmpnam function. */ + #undef HAVE_TMPNAM + + /* Define if you have the tmpnam_r function. */ + #undef HAVE_TMPNAM_R + /* Define if you have the truncate function. */ #undef HAVE_TRUNCATE *************** *** 387,390 **** --- 579,591 ---- #undef HAVE_WAITPID + /* Define if you have the header file. */ + #undef HAVE_DB_H + + /* Define if you have the header file. */ + #undef HAVE_DB1_NDBM_H + + /* Define if you have the header file. */ + #undef HAVE_DB_185_H + /* Define if you have the header file. */ #undef HAVE_DIRENT_H *************** *** 396,399 **** --- 597,609 ---- #undef HAVE_FCNTL_H + /* Define if you have the header file. */ + #undef HAVE_GDBM_NDBM_H + + /* Define if you have the header file. */ + #undef HAVE_LANGINFO_H + + /* Define if you have the header file. */ + #undef HAVE_LIBUTIL_H + /* Define if you have the header file. */ #define HAVE_LIMITS_H 1 *************** *** 405,414 **** --- 615,636 ---- #undef HAVE_NCURSES_H + /* Define if you have the header file. */ + #undef HAVE_NDBM_H + /* Define if you have the header file. */ #undef HAVE_NDIR_H + /* Define if you have the header file. */ + #undef HAVE_NETPACKET_PACKET_H + + /* Define if you have the header file. */ + #undef HAVE_POLL_H + /* Define if you have the header file. */ #undef HAVE_PTHREAD_H + /* Define if you have the header file. */ + #undef HAVE_PTY_H + /* Define if you have the header file. */ #define HAVE_SIGNAL_H 1 *************** *** 435,438 **** --- 657,663 ---- #undef HAVE_SYS_LOCK_H + /* Define if you have the header file. */ + #undef HAVE_SYS_MODEM_H + /* Define if you have the header file. */ #undef HAVE_SYS_NDIR_H *************** *** 441,447 **** --- 666,681 ---- #undef HAVE_SYS_PARAM_H + /* Define if you have the header file. */ + #undef HAVE_SYS_POLL_H + + /* Define if you have the header file. */ + #undef HAVE_SYS_RESOURCE_H + /* Define if you have the header file. */ #undef HAVE_SYS_SELECT_H + /* Define if you have the header file. */ + #undef HAVE_SYS_SOCKET_H + /* Define if you have the header file. */ #undef HAVE_SYS_TIME_H *************** *** 459,467 **** #undef HAVE_SYS_WAIT_H /* Define if you have the header file. */ #undef HAVE_THREAD_H /* Define if you have the header file. */ ! #undef HAVE_UNISTD_H /* Define if you have the header file. */ --- 693,704 ---- #undef HAVE_SYS_WAIT_H + /* Define if you have the header file. */ + #undef HAVE_TERMIOS_H + /* Define if you have the header file. */ #undef HAVE_THREAD_H /* Define if you have the header file. */ ! #define HAVE_UNISTD_H 1 /* Define if you have the header file. */ *************** *** 477,488 **** #undef HAVE_LIBIEEE ! #define DONT_HAVE_SYS_TYPES_H 1 #define DONT_HAVE_FSTAT 1 #define DONT_HAVE_STAT 1 ! #define DONT_HAVE_SYS_STAT_H 1 ! ! #define PLATFORM "RISCOS" ! #define socklen_t int ! #define HAVE_DYNAMIC_LOADING --- 714,736 ---- #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 + /* Define the macros needed if on a UnixWare 7.x system. */ + #if defined(__USLC__) && defined(__SCO_VERSION__) + #define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ + #endif + + #define DONT_HAVE_FSTAT 1 #define DONT_HAVE_STAT 1 ! #undef DONT_HAVE_SYS_STAT_H ! #define PLATFORM "riscos" From gvanrossum@users.sourceforge.net Wed Oct 24 21:12:31 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 24 Oct 2001 13:12:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/RISCOS README,1.1,1.2 sleep.c,1.1,1.2 unixstuff.c,1.1,1.2 unixstuff.h,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/RISCOS In directory usw-pr-cvs1:/tmp/cvs-serv11257/RISCOS Modified Files: README sleep.c unixstuff.c unixstuff.h Log Message: SF patch #474590 -- RISC OS support From gvanrossum@users.sourceforge.net Wed Oct 24 21:13:17 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 24 Oct 2001 13:13:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/RISCOS/Modules riscosmodule.c,1.2,1.3 swimodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/RISCOS/Modules In directory usw-pr-cvs1:/tmp/cvs-serv11528/RISCOS/Modules Modified Files: riscosmodule.c swimodule.c Log Message: SF patch #474590 -- RISC OS support Index: riscosmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/RISCOS/Modules/riscosmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** riscosmodule.c 2001/10/18 20:34:25 1.2 --- riscosmodule.c 2001/10/24 20:13:15 1.3 *************** *** 1,8 **** /* RISCOS module implementation */ ! #include "h.osfscontrol" ! #include "h.osgbpb" ! #include "h.os" ! #include "h.osfile" #include "Python.h" --- 1,9 ---- /* RISCOS module implementation */ ! #include "oslib/osfscontrol.h" ! #include "oslib/osgbpb.h" ! #include "oslib/os.h" ! #include "oslib/osfile.h" ! #include "unixstuff.h" #include "Python.h" *************** *** 12,23 **** static os_error *e; ! static PyObject *RiscosError; /* Exception riscos.error */ static PyObject *riscos_oserror(void) ! { PyErr_SetString(RiscosError,e->errmess); ! return 0; } - static PyObject *riscos_error(char *s) { PyErr_SetString(RiscosError,s);return 0;} /* RISCOS file commands */ --- 13,29 ---- static os_error *e; ! /*static PyObject *RiscosError;*/ /* Exception riscos.error */ + static PyObject *riscos_error(char *s) + { + PyErr_SetString(PyExc_OSError, s); + return NULL; + } + static PyObject *riscos_oserror(void) ! { ! return riscos_error(e->errmess); } /* RISCOS file commands */ *************** *** 26,30 **** { char *path1; if (!PyArg_Parse(args, "s", &path1)) return NULL; ! if (remove(path1)) return PyErr_SetFromErrno(RiscosError); Py_INCREF(Py_None); return Py_None; --- 32,36 ---- { char *path1; if (!PyArg_Parse(args, "s", &path1)) return NULL; ! if (remove(path1)) return PyErr_SetFromErrno(PyExc_OSError); Py_INCREF(Py_None); return Py_None; *************** *** 34,38 **** { char *path1, *path2; if (!PyArg_Parse(args, "(ss)", &path1, &path2)) return NULL; ! if (rename(path1,path2)) return PyErr_SetFromErrno(RiscosError);; Py_INCREF(Py_None); return Py_None; --- 40,44 ---- { char *path1, *path2; if (!PyArg_Parse(args, "(ss)", &path1, &path2)) return NULL; ! if (rename(path1,path2)) return PyErr_SetFromErrno(PyExc_OSError); Py_INCREF(Py_None); return Py_None; *************** *** 212,221 **** } static PyObject *riscos_utime(PyObject *self,PyObject *args) ! { char *path; ! int x,y; ! if (!PyArg_Parse(args, "(s(ii))", &path,&x,&y)) return NULL; ! e=xosfile_stamp(path); ! if(e) return riscos_oserror(); Py_INCREF(Py_None); return Py_None; --- 218,271 ---- } + static PyObject *riscos_utime(PyObject *self,PyObject *args) ! { ! char *path; ! long atime, mtime; ! PyObject* arg; ! ! if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg)) ! return NULL; ! ! if (arg == Py_None) { ! /* optional time values not given */ ! Py_BEGIN_ALLOW_THREADS ! e=xosfile_stamp(path); ! Py_END_ALLOW_THREADS ! if(e) return riscos_oserror(); ! } ! else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) { ! PyErr_SetString(PyExc_TypeError, ! "utime() arg 2 must be a tuple (atime, mtime)"); ! return NULL; ! } ! else { ! /* catalogue info*/ ! fileswitch_object_type obj_type; ! bits load_addr, exec_addr; ! int size; ! fileswitch_attr attr; ! ! /* read old catalogue info */ ! Py_BEGIN_ALLOW_THREADS ! e=xosfile_read_no_path(path, &obj_type, &load_addr, &exec_addr, &size, &attr); ! Py_END_ALLOW_THREADS ! if(e) return riscos_oserror(); ! ! /* check if load and exec address really contain filetype and date */ ! if ( (load_addr & 0xFFF00000U) != 0xFFF00000U) ! return riscos_error("can't set date for object with load and exec addresses"); ! ! /* convert argument mtime to RISC OS load and exec address */ ! if(acorntime(&exec_addr, &load_addr, (time_t) mtime)) ! return riscos_oserror(); ! ! /* write new load and exec address */ ! Py_BEGIN_ALLOW_THREADS ! e = xosfile_write(path, load_addr, exec_addr, attr); ! Py_END_ALLOW_THREADS ! if(e) return riscos_oserror(); ! } ! Py_INCREF(Py_None); return Py_None; *************** *** 329,335 **** /* Initialize riscos.error exception */ ! RiscosError = PyString_FromString("riscos.error"); ! if (RiscosError == NULL || PyDict_SetItemString(d, "error", RiscosError) != 0) ! Py_FatalError("can't define riscos.error"); PyStructSequence_InitType(&StatResultType, &stat_result_desc); --- 379,383 ---- /* Initialize riscos.error exception */ ! PyDict_SetItemString(d, "error", PyExc_OSError); PyStructSequence_InitType(&StatResultType, &stat_result_desc); Index: swimodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/RISCOS/Modules/swimodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** swimodule.c 2001/03/02 05:57:54 1.1 --- swimodule.c 2001/10/24 20:13:15 1.2 *************** *** 14,22 **** */ ! #include "h.os" ! #include "h.kernel" #include "Python.h" - #include #define PyBlock_Check(op) ((op)->ob_type == &PyBlockType) --- 14,21 ---- */ ! #include "oslib/os.h" ! #include #include "Python.h" #define PyBlock_Check(op) ((op)->ob_type == &PyBlockType) From gvanrossum@users.sourceforge.net Wed Oct 24 21:13:18 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 24 Oct 2001 13:13:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/RISCOS/support !Boot,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/RISCOS/support In directory usw-pr-cvs1:/tmp/cvs-serv11528/RISCOS/support Modified Files: !Boot Log Message: SF patch #474590 -- RISC OS support Index: !Boot =================================================================== RCS file: /cvsroot/python/python/dist/src/RISCOS/support/!Boot,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** !Boot 2001/04/10 22:03:33 1.1 --- !Boot 2001/10/24 20:13:15 1.2 *************** *** 10,12 **** | -display set File$Type_ae5 Python ! set Alias$Python Run .python21 %*0 \ No newline at end of file --- 10,12 ---- | -display set File$Type_ae5 Python ! set Alias$Python Run .python22 %*0 \ No newline at end of file From gvanrossum@users.sourceforge.net Wed Oct 24 21:13:18 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 24 Oct 2001 13:13:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/RISCOS/Python dynload_riscos.c,1.1,1.2 getmtime_riscos.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/RISCOS/Python In directory usw-pr-cvs1:/tmp/cvs-serv11528/RISCOS/Python Modified Files: dynload_riscos.c getmtime_riscos.c Log Message: SF patch #474590 -- RISC OS support Index: dynload_riscos.c =================================================================== RCS file: /cvsroot/python/python/dist/src/RISCOS/Python/dynload_riscos.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** dynload_riscos.c 2001/03/02 05:57:54 1.1 --- dynload_riscos.c 2001/10/24 20:13:15 1.2 *************** *** 53,58 **** int err; char errstr[256]; ! err = dlk_load(pathname); if (err) { --- 53,59 ---- int err; char errstr[256]; + void (*init_function)(void); ! err = dlk_load_no_init(pathname, &init_function); if (err) { *************** *** 60,63 **** PyErr_SetString(PyExc_ImportError, errstr); } ! return dynload_init_dummy; } --- 61,64 ---- PyErr_SetString(PyExc_ImportError, errstr); } ! return init_function; } Index: getmtime_riscos.c =================================================================== RCS file: /cvsroot/python/python/dist/src/RISCOS/Python/getmtime_riscos.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** getmtime_riscos.c 2001/03/02 05:57:54 1.1 --- getmtime_riscos.c 2001/10/24 20:13:15 1.2 *************** *** 2,6 **** #define __swi ! #include "osfile.h" long PyOS_GetLastModificationTime(char *path, FILE *fp) --- 2,6 ---- #define __swi ! #include "oslib/osfile.h" long PyOS_GetLastModificationTime(char *path, FILE *fp) From tim_one@users.sourceforge.net Wed Oct 24 21:22:42 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 24 Oct 2001 13:22:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pyclbr.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv13797/python/Lib Modified Files: pyclbr.py Log Message: SF bug #473525 pyclbr broken As the comments in the module implied, pyclbr was easily confused by "strange stuff" inside single- (but not triple-) quoted strings. It isn't anymore. Its behavior remains flaky in the presence of nested functions and classes, though. Bugfix candidate. Index: pyclbr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pyclbr.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** pyclbr.py 2001/08/13 20:20:51 1.22 --- pyclbr.py 2001/10/24 20:22:40 1.23 *************** *** 30,38 **** BUGS ! - Continuation lines are not dealt with at all. ! - While triple-quoted strings won't confuse it, lines that look like ! def, class, import or "from ... import" stmts inside backslash-continued ! single-quoted strings are treated like code. The expense of stopping ! that isn't worth it. - Code that doesn't pass tabnanny or python -t will confuse it, unless you set the module TABWIDTH vrbl (default 8) to the correct tab width --- 30,35 ---- BUGS ! - Continuation lines are not dealt with at all, except inside strings. ! - Nested classes and functions can confuse it. - Code that doesn't pass tabnanny or python -t will confuse it, unless you set the module TABWIDTH vrbl (default 8) to the correct tab width *************** *** 76,79 **** --- 73,80 ---- )* ''' + + | " [^"\\\n]* (?: \\. [^"\\\n]*)* " + + | ' [^'\\\n]* (?: \\. [^'\\\n]*)* ' ) From gvanrossum@users.sourceforge.net Wed Oct 24 21:27:30 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 24 Oct 2001 13:27:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include pyport.h,2.38,2.39 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv15838 Modified Files: pyport.h Log Message: SF patch #474590 -- RISC OS support Index: pyport.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pyport.h,v retrieving revision 2.38 retrieving revision 2.39 diff -C2 -d -r2.38 -r2.39 *** pyport.h 2001/10/23 02:20:37 2.38 --- pyport.h 2001/10/24 20:27:28 2.39 *************** *** 154,157 **** --- 154,161 ---- #endif + #ifdef RISCOS + #include + #endif + #ifndef DONT_HAVE_SYS_STAT_H #include From gvanrossum@users.sourceforge.net Wed Oct 24 21:29:33 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 24 Oct 2001 13:29:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib os.py,1.48,1.49 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv16541 Modified Files: os.py Log Message: SF patch #474590 -- RISC OS support Index: os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/os.py,v retrieving revision 1.48 retrieving revision 1.49 diff -C2 -d -r1.48 -r1.49 *** os.py 2001/10/19 01:31:59 1.48 --- os.py 2001/10/24 20:29:30 1.49 *************** *** 8,11 **** --- 8,12 ---- - os.pardir is a string representing the parent directory ('..' or '::') - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\') + - os.extsep is the extension separator ('.' or '/') - os.altsep is the alternate pathname separator (None or '/') - os.pathsep is the component separator used in $PATH etc *************** *** 168,171 **** --- 169,178 ---- else: raise ImportError, 'no os specific module found' + + + if sep=='.': + extsep = '/' + else: + extsep = '.' __all__.append("path") From gvanrossum@users.sourceforge.net Wed Oct 24 21:32:05 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 24 Oct 2001 13:32:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test regrtest.py,1.64,1.65 test_imageop.py,1.11,1.12 test_import.py,1.9,1.10 test_mailbox.py,1.7,1.8 test_mhlib.py,1.5,1.6 test_minidom.py,1.28,1.29 test_pkg.py,1.13,1.14 test_pkgimport.py,1.4,1.5 test_repr.py,1.8,1.9 test_rgbimg.py,1.12,1.13 test_sax.py,1.18,1.19 test_signal.py,1.8,1.9 test_tokenize.py,1.5,1.6 test_urllib2.py,1.5,1.6 test_zipfile.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv17145 Modified Files: regrtest.py test_imageop.py test_import.py test_mailbox.py test_mhlib.py test_minidom.py test_pkg.py test_pkgimport.py test_repr.py test_rgbimg.py test_sax.py test_signal.py test_tokenize.py test_urllib2.py test_zipfile.py Log Message: SF patch #474590 -- RISC OS support Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.64 retrieving revision 1.65 diff -C2 -d -r1.64 -r1.65 *** regrtest.py 2001/10/23 15:10:55 1.64 --- regrtest.py 2001/10/24 20:32:02 1.65 *************** *** 157,161 **** for i in range(len(args)): # Strip trailing ".py" from arguments ! if args[i][-3:] == '.py': args[i] = args[i][:-3] stdtests = STDTESTS[:] --- 157,161 ---- for i in range(len(args)): # Strip trailing ".py" from arguments ! if args[i][-3:] == os.extsep+'py': args[i] = args[i][:-3] stdtests = STDTESTS[:] *************** *** 273,277 **** tests = [] for name in names: ! if name[:5] == "test_" and name[-3:] == ".py": modname = name[:-3] if modname not in stdtests and modname not in nottests: --- 273,277 ---- tests = [] for name in names: ! if name[:5] == "test_" and name[-3:] == os.extsep+"py": modname = name[:-3] if modname not in stdtests and modname not in nottests: *************** *** 573,576 **** --- 573,618 ---- test_sunaudiodev test_sundry + test_unicode_file + test_winreg + test_winsound + """, + 'riscos': + """ + test_al + test_asynchat + test_bsddb + test_cd + test_cl + test_commands + test_crypt + test_dbm + test_dl + test_fcntl + test_fork1 + test_gdbm + test_gl + test_grp + test_imgfile + test_largefile + test_linuxaudiodev + test_locale + test_mmap + test_nis + test_ntpath + test_openpty + test_poll + test_popen2 + test_pty + test_pwd + test_socket_ssl + test_socketserver + test_strop + test_sunaudiodev + test_sundry + test_thread + test_threaded_import + test_threadedtempfile + test_threading + test_timing test_unicode_file test_winreg Index: test_imageop.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_imageop.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** test_imageop.py 2001/01/17 21:51:35 1.11 --- test_imageop.py 2001/10/24 20:32:02 1.12 *************** *** 8,22 **** from test_support import verbose, unlink ! import imageop, uu def main(use_rgbimg=1): # Create binary test files ! uu.decode(get_qualified_path('testrgb.uue'), 'test.rgb') if use_rgbimg: ! image, width, height = getrgbimage('test.rgb') else: ! image, width, height = getimage('test.rgb') # Return the selected part of image, which should by width by height --- 8,22 ---- from test_support import verbose, unlink ! import imageop, uu, os def main(use_rgbimg=1): # Create binary test files ! uu.decode(get_qualified_path('testrgb'+os.extsep+'uue'), 'test'+os.extsep+'rgb') if use_rgbimg: ! image, width, height = getrgbimage('test'+os.extsep+'rgb') else: ! image, width, height = getimage('test'+os.extsep+'rgb') # Return the selected part of image, which should by width by height *************** *** 115,119 **** # Cleanup ! unlink('test.rgb') def getrgbimage(name): --- 115,119 ---- # Cleanup ! unlink('test'+os.extsep+'rgb') def getrgbimage(name): Index: test_import.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_import.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_import.py 2001/08/24 18:38:02 1.9 --- test_import.py 2001/10/24 20:32:02 1.10 *************** *** 19,27 **** def test_with_extension(ext): # ext normally ".py"; perhaps ".pyw" source = TESTFN + ext ! pyo = TESTFN + ".pyo" if sys.platform.startswith('java'): pyc = TESTFN + "$py.class" else: ! pyc = TESTFN + ".pyc" f = open(source, "w") --- 19,27 ---- def test_with_extension(ext): # ext normally ".py"; perhaps ".pyw" source = TESTFN + ext ! pyo = TESTFN + os.extsep + "pyo" if sys.platform.startswith('java'): pyc = TESTFN + "$py.class" else: ! pyc = TESTFN + os.extsep + "pyc" f = open(source, "w") *************** *** 64,68 **** sys.path.insert(0, os.curdir) try: ! test_with_extension(".py") if sys.platform.startswith("win"): for ext in ".PY", ".Py", ".pY", ".pyw", ".PYW", ".pYw": --- 64,68 ---- sys.path.insert(0, os.curdir) try: ! test_with_extension(os.extsep + "py") if sys.platform.startswith("win"): for ext in ".PY", ".Py", ".pY", ".pyw", ".PYW", ".pYw": Index: test_mailbox.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mailbox.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_mailbox.py 2001/09/20 21:33:42 1.7 --- test_mailbox.py 2001/10/24 20:32:02 1.8 *************** *** 43,47 **** pid = self._counter self._counter += 1 ! filename = "%s.%s.myhostname.mydomain" % (t, pid) tmpname = os.path.join(self._dir, "tmp", filename) newname = os.path.join(self._dir, dir, filename) --- 43,47 ---- pid = self._counter self._counter += 1 ! filename = os.extsep.join((str(t), str(pid), "myhostname", "mydomain")) tmpname = os.path.join(self._dir, "tmp", filename) newname = os.path.join(self._dir, dir, filename) Index: test_mhlib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mhlib.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_mhlib.py 2001/09/20 21:33:42 1.5 --- test_mhlib.py 2001/10/24 20:32:02 1.6 *************** *** 13,18 **** import mhlib ! if sys.platform.startswith("win"): ! raise TestSkipped("test_mhlib skipped on Windows -- " "too many Unix assumptions") --- 13,18 ---- import mhlib ! if sys.platform.startswith("win") or sys.platform=="riscos": ! raise TestSkipped("test_mhlib skipped on %s -- "%sys.platform + "too many Unix assumptions") Index: test_minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_minidom.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** test_minidom.py 2001/09/28 20:31:50 1.28 --- test_minidom.py 2001/10/24 20:32:02 1.29 *************** *** 5,9 **** import xml.parsers.expat ! import os.path import sys import traceback --- 5,9 ---- import xml.parsers.expat ! import os import sys import traceback *************** *** 14,18 **** else: base = __file__ ! tstfile = os.path.join(os.path.dirname(base), "test.xml") del base --- 14,18 ---- else: base = __file__ ! tstfile = os.path.join(os.path.dirname(base), "test"+os.extsep+"xml") del base Index: test_pkg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pkg.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** test_pkg.py 2001/02/09 11:51:27 1.13 --- test_pkg.py 2001/10/24 20:32:02 1.14 *************** *** 2,6 **** import sys, os, tempfile, traceback ! from os import mkdir, rmdir # Can't test if these fail del mkdir, rmdir from test_support import verify, verbose, TestFailed --- 2,6 ---- import sys, os, tempfile, traceback ! from os import mkdir, rmdir, extsep # Can't test if these fail del mkdir, rmdir from test_support import verify, verbose, TestFailed *************** *** 78,90 **** tests = [ ! ("t1", [("t1", None), ("t1 __init__.py", "")], "import t1"), ("t2", [ ("t2", None), ! ("t2 __init__.py", "'doc for t2'; print __name__, 'loading'"), ("t2 sub", None), ! ("t2 sub __init__.py", ""), ("t2 sub subsub", None), ! ("t2 sub subsub __init__.py", "print __name__, 'loading'; spam = 1"), ], """ --- 78,90 ---- tests = [ ! ("t1", [("t1", None), ("t1 __init__"+os.extsep+"py", "")], "import t1"), ("t2", [ ("t2", None), ! ("t2 __init__"+os.extsep+"py", "'doc for t2'; print __name__, 'loading'"), ("t2 sub", None), ! ("t2 sub __init__"+os.extsep+"py", ""), ("t2 sub subsub", None), ! ("t2 sub subsub __init__"+os.extsep+"py", "print __name__, 'loading'; spam = 1"), ], """ *************** *** 112,120 **** ("t3", [ ("t3", None), ! ("t3 __init__.py", "print __name__, 'loading'"), ("t3 sub", None), ! ("t3 sub __init__.py", ""), ("t3 sub subsub", None), ! ("t3 sub subsub __init__.py", "print __name__, 'loading'; spam = 1"), ], """ --- 112,120 ---- ("t3", [ ("t3", None), ! ("t3 __init__"+os.extsep+"py", "print __name__, 'loading'"), ("t3 sub", None), ! ("t3 sub __init__"+os.extsep+"py", ""), ("t3 sub subsub", None), ! ("t3 sub subsub __init__"+os.extsep+"py", "print __name__, 'loading'; spam = 1"), ], """ *************** *** 127,139 **** ("t4", [ ! ("t4.py", "print 'THIS SHOULD NOT BE PRINTED (t4.py)'"), ("t4", None), ! ("t4 __init__.py", "print __name__, 'loading'"), ! ("t4 sub.py", "print 'THIS SHOULD NOT BE PRINTED (sub.py)'"), ("t4 sub", None), ! ("t4 sub __init__.py", ""), ! ("t4 sub subsub.py", "print 'THIS SHOULD NOT BE PRINTED (subsub.py)'"), ("t4 sub subsub", None), ! ("t4 sub subsub __init__.py", "print __name__, 'loading'; spam = 1"), ], """ --- 127,139 ---- ("t4", [ ! ("t4"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (t4"+os.extsep+"py)'"), ("t4", None), ! ("t4 __init__"+os.extsep+"py", "print __name__, 'loading'"), ! ("t4 sub"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (sub"+os.extsep+"py)'"), ("t4 sub", None), ! ("t4 sub __init__"+os.extsep+"py", ""), ! ("t4 sub subsub"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (subsub"+os.extsep+"py)'"), ("t4 sub subsub", None), ! ("t4 sub subsub __init__"+os.extsep+"py", "print __name__, 'loading'; spam = 1"), ], """ *************** *** 144,150 **** ("t5", [ ("t5", None), ! ("t5 __init__.py", "import t5.foo"), ! ("t5 string.py", "print __name__, 'loading'; spam = 1"), ! ("t5 foo.py", "print __name__, 'loading'; import string; print string.spam"), ], --- 144,150 ---- ("t5", [ ("t5", None), ! ("t5 __init__"+os.extsep+"py", "import t5.foo"), ! ("t5 string"+os.extsep+"py", "print __name__, 'loading'; spam = 1"), ! ("t5 foo"+os.extsep+"py", "print __name__, 'loading'; import string; print string.spam"), ], *************** *** 161,168 **** ("t6", [ ("t6", None), ! ("t6 __init__.py", "__all__ = ['spam', 'ham', 'eggs']"), ! ("t6 spam.py", "print __name__, 'loading'"), ! ("t6 ham.py", "print __name__, 'loading'"), ! ("t6 eggs.py", "print __name__, 'loading'"), ], """ --- 161,168 ---- ("t6", [ ("t6", None), ! ("t6 __init__"+os.extsep+"py", "__all__ = ['spam', 'ham', 'eggs']"), ! ("t6 spam"+os.extsep+"py", "print __name__, 'loading'"), ! ("t6 ham"+os.extsep+"py", "print __name__, 'loading'"), ! ("t6 eggs"+os.extsep+"py", "print __name__, 'loading'"), ], """ *************** *** 175,187 **** ("t7", [ ! ("t7.py", "print 'Importing t7.py'"), ("t7", None), ! ("t7 __init__.py", "print __name__, 'loading'"), ! ("t7 sub.py", "print 'THIS SHOULD NOT BE PRINTED (sub.py)'"), ("t7 sub", None), ! ("t7 sub __init__.py", ""), ! ("t7 sub subsub.py", "print 'THIS SHOULD NOT BE PRINTED (subsub.py)'"), ("t7 sub subsub", None), ! ("t7 sub subsub __init__.py", "print __name__, 'loading'; spam = 1"), ], """ --- 175,187 ---- ("t7", [ ! ("t7"+os.extsep+"py", "print 'Importing t7"+os.extsep+"py'"), ("t7", None), ! ("t7 __init__"+os.extsep+"py", "print __name__, 'loading'"), ! ("t7 sub"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (sub"+os.extsep+"py)'"), ("t7 sub", None), ! ("t7 sub __init__"+os.extsep+"py", ""), ! ("t7 sub subsub"+os.extsep+"py", "print 'THIS SHOULD NOT BE PRINTED (subsub"+os.extsep+"py)'"), ("t7 sub subsub", None), ! ("t7 sub subsub __init__"+os.extsep+"py", "print __name__, 'loading'; spam = 1"), ], """ Index: test_pkgimport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pkgimport.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_pkgimport.py 2001/09/20 21:33:42 1.4 --- test_pkgimport.py 2001/10/24 20:32:02 1.5 *************** *** 24,29 **** self.package_name) os.mkdir(self.package_dir) ! open(os.path.join(self.package_dir, '__init__.py'), 'w') ! self.module_path = os.path.join(self.package_dir, 'foo.py') def tearDown(self): --- 24,29 ---- self.package_name) os.mkdir(self.package_dir) ! open(os.path.join(self.package_dir, '__init__'+os.extsep+'py'), 'w') ! self.module_path = os.path.join(self.package_dir, 'foo'+os.extsep+'py') def tearDown(self): Index: test_repr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_repr.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_repr.py 2001/09/25 03:56:29 1.8 --- test_repr.py 2001/10/24 20:32:02 1.9 *************** *** 174,180 **** # Make the package and subpackage os.mkdir(self.pkgname) ! touch(os.path.join(self.pkgname, '__init__.py')) os.mkdir(self.subpkgname) ! touch(os.path.join(self.subpkgname, '__init__.py')) # Remember where we are self.here = os.getcwd() --- 174,180 ---- # Make the package and subpackage os.mkdir(self.pkgname) ! touch(os.path.join(self.pkgname, '__init__'+os.extsep+'py')) os.mkdir(self.subpkgname) ! touch(os.path.join(self.subpkgname, '__init__'+os.extsep+'py')) # Remember where we are self.here = os.getcwd() *************** *** 196,200 **** def test_module(self): eq = self.assertEquals ! touch(os.path.join(self.subpkgname, self.pkgname + '.py')) from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation eq(repr(areallylongpackageandmodulenametotestreprtruncation), --- 196,200 ---- def test_module(self): eq = self.assertEquals ! touch(os.path.join(self.subpkgname, self.pkgname + os.extsep + 'py')) from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation eq(repr(areallylongpackageandmodulenametotestreprtruncation), *************** *** 203,207 **** def test_type(self): eq = self.assertEquals ! touch(os.path.join(self.subpkgname, 'foo.py'), '''\ class foo(object): pass --- 203,207 ---- def test_type(self): eq = self.assertEquals ! touch(os.path.join(self.subpkgname, 'foo'+os.extsep+'py'), '''\ class foo(object): pass *************** *** 217,221 **** def test_class(self): ! touch(os.path.join(self.subpkgname, 'bar.py'), '''\ class bar: pass --- 217,221 ---- def test_class(self): ! touch(os.path.join(self.subpkgname, 'bar'+os.extsep+'py'), '''\ class bar: pass *************** *** 226,230 **** def test_instance(self): ! touch(os.path.join(self.subpkgname, 'baz.py'), '''\ class baz: pass --- 226,230 ---- def test_instance(self): ! touch(os.path.join(self.subpkgname, 'baz'+os.extsep+'py'), '''\ class baz: pass *************** *** 237,241 **** def test_method(self): eq = self.assertEquals ! touch(os.path.join(self.subpkgname, 'qux.py'), '''\ class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: def amethod(self): pass --- 237,241 ---- def test_method(self): eq = self.assertEquals ! touch(os.path.join(self.subpkgname, 'qux'+os.extsep+'py'), '''\ class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: def amethod(self): pass Index: test_rgbimg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_rgbimg.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_rgbimg.py 2001/01/17 21:51:36 1.12 --- test_rgbimg.py 2001/10/24 20:32:02 1.13 *************** *** 26,32 **** table = [ ! ('testrgb.uue', 'test.rgb'), ! ('testimg.uue', 'test.rawimg'), ! ('testimgr.uue', 'test.rawimg.rev'), ] for source, target in table: --- 26,32 ---- table = [ ! ('testrgb'+os.extsep+'uue', 'test'+os.extsep+'rgb'), ! ('testimg'+os.extsep+'uue', 'test'+os.extsep+'rawimg'), ! ('testimgr'+os.extsep+'uue', 'test'+os.extsep+'rawimg'+os.extsep+'rev'), ] for source, target in table: *************** *** 44,48 **** raise error, 'ttob should start out as zero' ! testimg('test.rgb', 'test.rawimg') ttob = rgbimg.ttob(1) --- 44,48 ---- raise error, 'ttob should start out as zero' ! testimg('test'+os.extsep+'rgb', 'test'+os.extsep+'rawimg') ttob = rgbimg.ttob(1) *************** *** 50,54 **** raise error, 'ttob should be zero' ! testimg('test.rgb', 'test.rawimg.rev') ttob = rgbimg.ttob(0) --- 50,54 ---- raise error, 'ttob should be zero' ! testimg('test'+os.extsep+'rgb', 'test'+os.extsep+'rawimg'+os.extsep+'rev') ttob = rgbimg.ttob(0) Index: test_sax.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sax.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** test_sax.py 2001/08/07 19:17:05 1.18 --- test_sax.py 2001/10/24 20:32:02 1.19 *************** *** 14,17 **** --- 14,18 ---- from cStringIO import StringIO from test_support import verify, verbose, TestFailed, findfile + import os # ===== Utilities *************** *** 229,233 **** parser.setContentHandler(xmlgen) ! parser.parse(open(findfile("test.xml"))) return result.getvalue() == xml_test_out --- 230,234 ---- parser.setContentHandler(xmlgen) ! parser.parse(open(findfile("test"+os.extsep+"xml"))) return result.getvalue() == xml_test_out *************** *** 350,354 **** # ===== InputSource support ! xml_test_out = open(findfile("test.xml.out")).read() def test_expat_inpsource_filename(): --- 351,355 ---- # ===== InputSource support ! xml_test_out = open(findfile("test"+os.extsep+"xml"+os.extsep+"out")).read() def test_expat_inpsource_filename(): *************** *** 358,362 **** parser.setContentHandler(xmlgen) ! parser.parse(findfile("test.xml")) return result.getvalue() == xml_test_out --- 359,363 ---- parser.setContentHandler(xmlgen) ! parser.parse(findfile("test"+os.extsep+"xml")) return result.getvalue() == xml_test_out *************** *** 368,372 **** parser.setContentHandler(xmlgen) ! parser.parse(InputSource(findfile("test.xml"))) return result.getvalue() == xml_test_out --- 369,373 ---- parser.setContentHandler(xmlgen) ! parser.parse(InputSource(findfile("test"+os.extsep+"xml"))) return result.getvalue() == xml_test_out *************** *** 379,383 **** parser.setContentHandler(xmlgen) inpsrc = InputSource() ! inpsrc.setByteStream(open(findfile("test.xml"))) parser.parse(inpsrc) --- 380,384 ---- parser.setContentHandler(xmlgen) inpsrc = InputSource() ! inpsrc.setByteStream(open(findfile("test"+os.extsep+"xml"))) parser.parse(inpsrc) *************** *** 626,632 **** parser.setContentHandler(xmlgen) ! parser.parse(findfile("test.xml")) ! outf = open(findfile("test.xml.out"), "w") outf.write(result.getvalue()) outf.close() --- 627,633 ---- parser.setContentHandler(xmlgen) ! parser.parse(findfile("test"+os.extsep+"xml")) ! outf = open(findfile("test"+os.extsep+"xml"+os.extsep+"out"), "w") outf.write(result.getvalue()) outf.close() Index: test_signal.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_signal.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_signal.py 2001/01/17 21:51:35 1.8 --- test_signal.py 2001/10/24 20:32:02 1.9 *************** *** 5,10 **** import sys ! if sys.platform[:3] in ('win', 'os2'): ! raise TestSkipped, "Can't test signal on %s" % sys.platform[:3] if verbose: --- 5,10 ---- import sys ! if sys.platform[:3] in ('win', 'os2') or sys.platform=='riscos': ! raise TestSkipped, "Can't test signal on %s" % sys.platform if verbose: Index: test_tokenize.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_tokenize.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_tokenize.py 2001/01/17 21:51:36 1.5 --- test_tokenize.py 2001/10/24 20:32:03 1.6 *************** *** 4,8 **** if verbose: print 'starting...' ! file = open(findfile('tokenize_tests.py')) tokenize.tokenize(file.readline) if verbose: --- 4,8 ---- if verbose: print 'starting...' ! file = open(findfile('tokenize_tests'+os.extsep+'py')) tokenize.tokenize(file.readline) if verbose: Index: test_urllib2.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_urllib2.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_urllib2.py 2001/09/04 06:37:28 1.5 --- test_urllib2.py 2001/10/24 20:32:03 1.6 *************** *** 20,23 **** --- 20,28 ---- if os.name == 'mac': fname = '/' + fname.replace(':', '/') + elif os.name == 'riscos': + import string + fname = os.expand(fname) + fname = fname.translate(string.maketrans("/.", "./")) + file_url = "file://%s" % fname f = urllib2.urlopen(file_url) Index: test_zipfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_zipfile.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_zipfile.py 2001/04/10 14:46:39 1.7 --- test_zipfile.py 2001/10/24 20:32:03 1.8 *************** *** 3,13 **** from test_support import TestFailed ! srcname = "junk9630.tmp" ! zipname = "junk9708.tmp" def zipTest(f, compression, srccontents): zip = zipfile.ZipFile(f, "w", compression) # Create the ZIP archive ! zip.write(srcname, "another.name") zip.write(srcname, srcname) zip.close() --- 3,13 ---- from test_support import TestFailed ! srcname = "junk9630"+os.extsep+"tmp" ! zipname = "junk9708"+os.extsep+"tmp" def zipTest(f, compression, srccontents): zip = zipfile.ZipFile(f, "w", compression) # Create the ZIP archive ! zip.write(srcname, "another"+os.extsep+"name") zip.write(srcname, srcname) zip.close() *************** *** 15,19 **** zip = zipfile.ZipFile(f, "r", compression) # Read the ZIP archive readData2 = zip.read(srcname) ! readData1 = zip.read("another.name") zip.close() --- 15,19 ---- zip = zipfile.ZipFile(f, "r", compression) # Read the ZIP archive readData2 = zip.read(srcname) ! readData1 = zip.read("another"+os.extsep+"name") zip.close() From gvanrossum@users.sourceforge.net Wed Oct 24 21:33:36 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 24 Oct 2001 13:33:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib dumbdbm.py,1.13,1.14 fileinput.py,1.7,1.8 site.py,1.36,1.37 socket.py,1.13,1.14 tempfile.py,1.30,1.31 whichdb.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv17535 Modified Files: dumbdbm.py fileinput.py site.py socket.py tempfile.py whichdb.py Log Message: SF patch #474590 -- RISC OS support Index: dumbdbm.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dumbdbm.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** dumbdbm.py 2001/09/04 19:14:13 1.13 --- dumbdbm.py 2001/10/24 20:33:34 1.14 *************** *** 34,44 **** def __init__(self, file): ! if _os.sep == '.': ! endsep = '/' ! else: ! endsep = '.' ! self._dirfile = file + endsep + 'dir' ! self._datfile = file + endsep + 'dat' ! self._bakfile = file + endsep + 'bak' # Mod by Jack: create data file if needed try: --- 34,40 ---- def __init__(self, file): ! self._dirfile = file + _os.extsep + 'dir' ! self._datfile = file + _os.extsep + 'dat' ! self._bakfile = file + _os.extsep + 'bak' # Mod by Jack: create data file if needed try: Index: fileinput.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/fileinput.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** fileinput.py 2001/01/20 23:34:12 1.7 --- fileinput.py 2001/10/24 20:33:34 1.8 *************** *** 236,240 **** if self._inplace: self._backupfilename = ( ! self._filename + (self._backup or ".bak")) try: os.unlink(self._backupfilename) except os.error: pass --- 236,240 ---- if self._inplace: self._backupfilename = ( ! self._filename + (self._backup or os.extsep+"bak")) try: os.unlink(self._backupfilename) except os.error: pass Index: site.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/site.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** site.py 2001/10/02 18:27:09 1.36 --- site.py 2001/10/24 20:33:34 1.37 *************** *** 60,69 **** import sys, os - if os.sep==".": - endsep = "/" - else: - endsep = "." - def makepath(*paths): dir = os.path.abspath(os.path.join(*paths)) --- 60,64 ---- *************** *** 130,134 **** names.sort() for name in names: ! if name[-4:] == endsep + "pth": addpackage(sitedir, name) if reset: --- 125,129 ---- names.sort() for name in names: ! if name[-4:] == os.extsep + "pth": addpackage(sitedir, name) if reset: Index: socket.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/socket.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** socket.py 2001/08/18 21:00:39 1.13 --- socket.py 2001/10/24 20:33:34 1.14 *************** *** 49,53 **** if (sys.platform.lower().startswith("win") or (hasattr(os, 'uname') and os.uname()[0] == "BeOS") ! or (sys.platform=="RISCOS")): _realsocketcall = _socket.socket --- 49,53 ---- if (sys.platform.lower().startswith("win") or (hasattr(os, 'uname') and os.uname()[0] == "BeOS") ! or (sys.platform=="riscos")): _realsocketcall = _socket.socket Index: tempfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tempfile.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** tempfile.py 2001/03/02 05:51:16 1.30 --- tempfile.py 2001/10/24 20:33:34 1.31 *************** *** 35,38 **** --- 35,42 ---- except macfs.error: pass + elif os.name == 'riscos': + scrapdir = os.getenv('Wimp$ScrapDir') + if scrapdir: + attempdirs.insert(0, scrapdir) for envname in 'TMPDIR', 'TEMP', 'TMP': if os.environ.has_key(envname): *************** *** 88,92 **** elif os.name == "nt": template = '~' + `os.getpid()` + '-' ! elif os.name == 'mac': template = 'Python-Tmp-' else: --- 92,96 ---- elif os.name == "nt": template = '~' + `os.getpid()` + '-' ! elif os.name in ('mac', 'riscos'): template = 'Python-Tmp-' else: Index: whichdb.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/whichdb.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** whichdb.py 2001/03/16 08:29:47 1.11 --- whichdb.py 2001/10/24 20:33:34 1.12 *************** *** 3,11 **** import os - if os.sep==".": - endsep = "/" - else: - endsep = "." - def whichdb(filename): """Guess which db package to use to open a db file. --- 3,6 ---- *************** *** 25,31 **** # Check for dbm first -- this has a .pag and a .dir file try: ! f = open(filename + endsep + "pag", "rb") f.close() ! f = open(filename + endsep + "dir", "rb") f.close() return "dbm" --- 20,26 ---- # Check for dbm first -- this has a .pag and a .dir file try: ! f = open(filename + os.extsep + "pag", "rb") f.close() ! f = open(filename + os.extsep + "dir", "rb") f.close() return "dbm" *************** *** 35,41 **** # Check for dumbdbm next -- this has a .dir and and a .dat file try: ! f = open(filename + endsep + "dat", "rb") f.close() ! f = open(filename + endsep + "dir", "rb") try: if f.read(1) in ["'", '"']: --- 30,36 ---- # Check for dumbdbm next -- this has a .dir and and a .dat file try: ! f = open(filename + os.extsep + "dat", "rb") f.close() ! f = open(filename + os.extsep + "dir", "rb") try: if f.read(1) in ["'", '"']: From gvanrossum@users.sourceforge.net Wed Oct 24 21:33:36 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 24 Oct 2001 13:33:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/plat-riscos riscosenviron.py,1.4,1.5 riscospath.py,1.6,1.7 rourl2path.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-riscos In directory usw-pr-cvs1:/tmp/cvs-serv17535/plat-riscos Modified Files: riscosenviron.py riscospath.py rourl2path.py Log Message: SF patch #474590 -- RISC OS support Index: riscosenviron.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-riscos/riscosenviron.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** riscosenviron.py 2001/07/02 04:59:35 1.4 --- riscosenviron.py 2001/10/24 20:33:34 1.5 *************** *** 1,3 **** ! """A more or less complete user-defined wrapper around dictionary objects.""" import riscos --- 1,3 ---- ! """A more or less complete dictionary like interface for the RISC OS environment.""" import riscos *************** *** 9,14 **** return repr(riscos.getenvdict()) def __cmp__(self, dict): ! if isinstance(dict, UserDict): ! return cmp(riscos.getenvdict(), dict) def __len__(self): return len(riscos.getenvdict()) --- 9,13 ---- return repr(riscos.getenvdict()) def __cmp__(self, dict): ! return cmp(riscos.getenvdict(), dict) def __len__(self): return len(riscos.getenvdict()) Index: riscospath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-riscos/riscospath.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** riscospath.py 2001/10/10 04:16:20 1.6 --- riscospath.py 2001/10/24 20:33:34 1.7 *************** *** 104,109 **** for b in p: (fs, drive, path)= _split(b) ! if fs!='' or drive!='' or path[:1] in _roots: j= b else: j= j+'.'+b --- 104,111 ---- for b in p: (fs, drive, path)= _split(b) ! if j=='' or fs!='' or drive!='' or path[:1] in _roots: j= b + elif j[-1]==':': + j= j+b else: j= j+'.'+b Index: rourl2path.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-riscos/rourl2path.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** rourl2path.py 2001/07/02 04:59:35 1.2 --- rourl2path.py 2001/10/24 20:33:34 1.3 *************** *** 7,19 **** import os ! def url2pathname(pathname): ! "Convert /-delimited pathname to mac pathname" ! # ! # XXXX The .. handling should be fixed... ! # ! tp = urllib.splittype(pathname)[0] if tp and tp <> 'file': raise RuntimeError, 'Cannot convert non-local URL to pathname' ! components = string.split(pathname, '/') # Remove . and embedded .. i = 0 --- 7,30 ---- import os ! __all__ = ["url2pathname","pathname2url"] ! ! __slash_dot = string.maketrans("/.", "./") ! ! def url2pathname(url): ! "Convert URL to a RISC OS path." ! tp = urllib.splittype(url)[0] if tp and tp <> 'file': raise RuntimeError, 'Cannot convert non-local URL to pathname' ! # Turn starting /// into /, an empty hostname means current host ! if url[:3] == '///': ! url = url[2:] ! elif url[:2] == '//': ! raise RuntimeError, 'Cannot convert non-local URL to pathname' ! components = string.split(url, '/') ! if not components[0]: ! if '$' in components: ! del components[0] ! else: ! components[0] = '$' # Remove . and embedded .. i = 0 *************** *** 24,66 **** components[i-1] not in ('', '..'): del components[i-1:i+1] ! i = i-1 elif components[i] == '' and i > 0 and components[i-1] <> '': del components[i] else: ! if components[i]<>'..' and string.find(components[i], '.')<>-1 : ! components[i] = string.join(string.split(components[i],'.'),'/') ! i = i+1 ! if not components[0]: ! # Absolute unix path, don't start with colon ! return string.join(components[1:], '.') ! else: ! # relative unix path, start with colon. First replace ! # leading .. by empty strings (giving ::file) ! i = 0 ! while i < len(components) and components[i] == '..': ! components[i] = '^' ! i = i + 1 ! return string.join(components, '.') def pathname2url(pathname): ! "convert mac pathname to /-delimited pathname" ! if '/' in pathname: ! raise RuntimeError, "Cannot convert pathname containing slashes" ! components = string.split(pathname, ':') ! # Replace empty string ('::') by .. (will result in '/../' later) ! for i in range(1, len(components)): ! if components[i] == '': ! components[i] = '..' ! # Truncate names longer than 31 bytes ! components = map(lambda x: x[:31], components) ! ! if os.path.isabs(pathname): ! return '/' + string.join(components, '/') ! else: ! return string.join(components, '/') def test(): for url in ["index.html", "/SCSI::SCSI4/$/Anwendung/Comm/Apps/!Fresco/Welcome", "../index.html", "bar/index.html", --- 35,57 ---- components[i-1] not in ('', '..'): del components[i-1:i+1] ! i -= 1 ! elif components[i] == '..': ! components[i] = '^' ! i += 1 elif components[i] == '' and i > 0 and components[i-1] <> '': del components[i] else: ! i += 1 ! components = map(lambda x: urllib.unquote(x).translate(__slash_dot), components) ! return '.'.join(components) def pathname2url(pathname): ! "Convert a RISC OS path name to a file url." ! return urllib.quote('///' + pathname.translate(__slash_dot), "/$:") def test(): for url in ["index.html", "/SCSI::SCSI4/$/Anwendung/Comm/Apps/!Fresco/Welcome", + "/SCSI::SCSI4/$/Anwendung/Comm/Apps/../!Fresco/Welcome", "../index.html", "bar/index.html", *************** *** 69,80 **** "/"]: print `url`, '->', `url2pathname(url)` ! for path in ["drive:", ! "drive:dir:", ! "drive:dir:file", ! "drive:file", ! "file", ! ":file", ! ":dir:", ! ":dir:file"]: print `path`, '->', `pathname2url(path)` --- 60,67 ---- "/"]: print `url`, '->', `url2pathname(url)` ! print "*******************************************************" ! for path in ["SCSI::SCSI4.$.Anwendung", ! "PythonApp:Lib", ! "PythonApp:Lib.rourl2path/py"]: print `path`, '->', `pathname2url(path)` From gvanrossum@users.sourceforge.net Wed Oct 24 21:37:12 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 24 Oct 2001 13:37:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules selectmodule.c,2.56,2.57 socketmodule.c,1.185,1.186 structmodule.c,2.50,2.51 timemodule.c,2.115,2.116 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv18456 Modified Files: selectmodule.c socketmodule.c structmodule.c timemodule.c Log Message: SF patch #474590 -- RISC OS support Index: selectmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/selectmodule.c,v retrieving revision 2.56 retrieving revision 2.57 diff -C2 -d -r2.56 -r2.57 *** selectmodule.c 2001/08/16 21:59:46 2.56 --- selectmodule.c 2001/10/24 20:37:10 2.57 *************** *** 53,64 **** #endif - #ifdef RISCOS - #define NO_DUP - #undef off_t - #undef uid_t - #undef gid_t - #undef errno - #include "socklib.h" - #endif /* RISCOS */ static PyObject *SelectError; --- 53,56 ---- Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.185 retrieving revision 1.186 diff -C2 -d -r1.185 -r1.186 *** socketmodule.c 2001/10/24 17:35:46 1.185 --- socketmodule.c 2001/10/24 20:37:10 1.186 *************** *** 131,148 **** #endif - #ifdef RISCOS - #define NO_DUP - #undef off_t - #undef uid_t - #undef gid_t - #undef errno - #include - #include "socklib.h" - #include "inetlib.h" - #include "netdb.h" - #include "unixlib.h" - #include "netinet/in.h" - #include "sys/ioctl.h" - #else /*RISCOS*/ #include --- 131,134 ---- *************** *** 166,176 **** #endif #include #else #include #include #endif - #endif /*RISCOS*/ #ifdef HAVE_SYS_UN_H --- 152,167 ---- #endif + #ifndef RISCOS #include #else + #include + #define NO_DUP + int h_errno; /* not used */ + #endif + #else #include #include #endif #ifdef HAVE_SYS_UN_H *************** *** 1805,1809 **** --- 1796,1804 ---- if (h == NULL) { /* Let's get real error message to return */ + #ifndef RISCOS PyH_Err(h_errno); + #else + PyErr_SetString(PySocket_Error, "host not found"); + #endif return NULL; } Index: structmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v retrieving revision 2.50 retrieving revision 2.51 diff -C2 -d -r2.50 -r2.51 *** structmodule.c 2001/09/15 02:35:15 2.50 --- structmodule.c 2001/10/24 20:37:10 2.51 *************** *** 54,70 **** #endif /* __MWERKS__ */ ! typedef struct { char c; short x; } s_short; ! typedef struct { char c; int x; } s_int; ! typedef struct { char c; long x; } s_long; ! typedef struct { char c; float x; } s_float; ! typedef struct { char c; double x; } s_double; ! typedef struct { char c; void *x; } s_void_p; ! #define SHORT_ALIGN (sizeof(s_short) - sizeof(short)) ! #define INT_ALIGN (sizeof(s_int) - sizeof(int)) ! #define LONG_ALIGN (sizeof(s_long) - sizeof(long)) ! #define FLOAT_ALIGN (sizeof(s_float) - sizeof(float)) ! #define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double)) ! #define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void *)) /* We can't support q and Q in native mode unless the compiler does; --- 54,70 ---- #endif /* __MWERKS__ */ ! typedef struct { char c; short x; } st_short; ! typedef struct { char c; int x; } st_int; ! typedef struct { char c; long x; } st_long; ! typedef struct { char c; float x; } st_float; ! typedef struct { char c; double x; } st_double; ! typedef struct { char c; void *x; } st_void_p; ! #define SHORT_ALIGN (sizeof(st_short) - sizeof(short)) ! #define INT_ALIGN (sizeof(st_int) - sizeof(int)) ! #define LONG_ALIGN (sizeof(st_long) - sizeof(long)) ! #define FLOAT_ALIGN (sizeof(st_float) - sizeof(float)) ! #define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double)) ! #define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *)) /* We can't support q and Q in native mode unless the compiler does; Index: timemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/timemodule.c,v retrieving revision 2.115 retrieving revision 2.116 diff -C2 -d -r2.115 -r2.116 *** timemodule.c 2001/10/18 20:34:25 2.115 --- timemodule.c 2001/10/24 20:37:10 2.116 *************** *** 18,24 **** #endif /* USE_GUSI2 */ #else - #ifndef RISCOS #include - #endif /* RISCOS */ #endif --- 18,22 ---- From gvanrossum@users.sourceforge.net Wed Oct 24 21:39:14 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 24 Oct 2001 13:39:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects floatobject.c,2.101,2.102 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv18992 Modified Files: floatobject.c Log Message: SF patch #474590 -- RISC OS support Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.101 retrieving revision 2.102 diff -C2 -d -r2.101 -r2.102 *** floatobject.c 2001/10/05 20:51:38 2.101 --- floatobject.c 2001/10/24 20:39:12 2.102 *************** *** 611,614 **** --- 611,621 ---- (void)modf(x, &wholepart); + #ifdef RISCOS + /* conversion from floating to integral type would raise exception */ + if (wholepart>LONG_MAX || wholepart Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv19612 Modified Files: bltinmodule.c import.c Log Message: SF patch #474590 -- RISC OS support Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.241 retrieving revision 2.242 diff -C2 -d -r2.241 -r2.242 *** bltinmodule.c 2001/10/16 21:31:32 2.241 --- bltinmodule.c 2001/10/24 20:42:55 2.242 *************** *** 14,17 **** --- 14,21 ---- #endif + #ifdef RISCOS + #include "unixstuff.h" + #endif + /* The default encoding used by the platform file system APIs Can remain NULL for all platforms that don't have such a concept *************** *** 537,541 **** --- 541,547 ---- PyCompilerFlags cf; int exists; + #ifndef RISCOS struct stat s; + #endif if (!PyArg_ParseTuple(args, "s|O!O!:execfile", *************** *** 559,562 **** --- 565,569 ---- exists = 0; /* Test for existence or directory. */ + #ifndef RISCOS if (!stat(filename, &s)) { if (S_ISDIR(s.st_mode)) *************** *** 565,568 **** --- 572,583 ---- exists = 1; } + #else + if (object_exists(filename)) { + if (isdir(filename)) + errno = EISDIR; + else + exists = 1; + } + #endif /* RISCOS */ if (exists) { Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.188 retrieving revision 2.189 diff -C2 -d -r2.188 -r2.189 *** import.c 2001/10/18 18:54:11 2.188 --- import.c 2001/10/24 20:42:55 2.189 *************** *** 984,994 **** /* XXX How are you going to test for directories? */ #ifdef RISCOS ! { ! static struct filedescr fd = {"", "", PKG_DIRECTORY}; ! if (isdir(buf)) { ! if (find_init_module(buf)) ! return &fd; ! } ! } #endif #endif --- 984,991 ---- /* XXX How are you going to test for directories? */ #ifdef RISCOS ! if (isdir(buf) && ! find_init_module(buf) && ! case_ok(buf, len, namelen, name)) ! return &fd_package; #endif #endif *************** *** 1070,1073 **** --- 1067,1072 ---- #include + #elif defined(RISCOS) + #include "oslib/osfscontrol.h" #endif *************** *** 1198,1201 **** --- 1197,1225 ---- } return 0 ; /* Not found */ + + /* RISC OS */ + #elif defined(RISCOS) + char canon[MAXPATHLEN+1]; /* buffer for the canonical form of the path */ + char buf2[MAXPATHLEN+2]; + char *nameWithExt = buf+len-namelen; + int canonlen; + os_error *e; + + if (Py_GETENV("PYTHONCASEOK") != NULL) + return 1; + + /* workaround: + append wildcard, otherwise case of filename wouldn't be touched */ + strcpy(buf2, buf); + strcat(buf2, "*"); + + e = xosfscontrol_canonicalise_path(buf2,canon,0,0,MAXPATHLEN+1,&canonlen); + canonlen = MAXPATHLEN+1-canonlen; + if (e || canonlen<=0 || canonlen>(MAXPATHLEN+1) ) + return 0; + if (strcmp(nameWithExt, canon+canonlen-strlen(nameWithExt))==0) + return 1; /* match */ + + return 0; /* assuming it's a case-sensitive filesystem, so there's nothing to do! */ From fdrake@users.sourceforge.net Wed Oct 24 21:47:51 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 24 Oct 2001 13:47:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python sysmodule.c,2.93,2.94 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv20824 Modified Files: sysmodule.c Log Message: Convert getrefcount() to METH_O, and sys_excepthook() to use PyArg_UnpackTuple(). Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.93 retrieving revision 2.94 diff -C2 -d -r2.93 -r2.94 *** sysmodule.c 2001/10/04 14:48:42 2.93 --- sysmodule.c 2001/10/24 20:47:48 2.94 *************** *** 117,121 **** { PyObject *exc, *value, *tb; ! if (!PyArg_ParseTuple(args, "OOO:excepthook", &exc, &value, &tb)) return NULL; PyErr_Display(exc, value, tb); --- 117,121 ---- { PyObject *exc, *value, *tb; ! if (!PyArg_UnpackTuple(args, "excepthook", 3, 3, &exc, &value, &tb)) return NULL; PyErr_Display(exc, value, tb); *************** *** 453,461 **** static PyObject * ! sys_getrefcount(PyObject *self, PyObject *args) { - PyObject *arg; - if (!PyArg_ParseTuple(args, "O:getrefcount", &arg)) - return NULL; return PyInt_FromLong(arg->ob_refcnt); } --- 453,458 ---- static PyObject * ! sys_getrefcount(PyObject *self, PyObject *arg) { return PyInt_FromLong(arg->ob_refcnt); } *************** *** 555,559 **** {"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS}, #endif ! {"getrefcount", sys_getrefcount, METH_VARARGS, getrefcount_doc}, {"getrecursionlimit", (PyCFunction)sys_getrecursionlimit, METH_NOARGS, getrecursionlimit_doc}, --- 552,556 ---- {"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS}, #endif ! {"getrefcount", (PyCFunction)sys_getrefcount, METH_O, getrefcount_doc}, {"getrecursionlimit", (PyCFunction)sys_getrecursionlimit, METH_NOARGS, getrecursionlimit_doc}, From gvanrossum@users.sourceforge.net Wed Oct 24 21:51:46 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 24 Oct 2001 13:51:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.297,1.298 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv21756 Modified Files: NEWS Log Message: Note updated RISCOS port. Remove reference in the 2.1 release notes to os.extsep -- that variable actually didn't exist in that release! Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.297 retrieving revision 1.298 diff -C2 -d -r1.297 -r1.298 *** NEWS 2001/10/23 01:59:54 1.297 --- NEWS 2001/10/24 20:51:44 1.298 *************** *** 21,24 **** --- 21,29 ---- permanent memory leaks (provided garbage collection is enabled). + - os.extsep -- a new variable needed by the RISCOS support. It is the + separator used by extensions, and is '.' on all platforms except + RISCOS, where it is '/'. There is no need to use this variable + unless you have a masochistic desire to port your code to RISCOS. + Tools/Demos *************** *** 29,32 **** --- 34,39 ---- New platforms + - Updated RISCOS port by Dietmar Schwertberger. + Tests *************** *** 1447,1454 **** Schwertberger! See RISCOS/README for more information -- it seems that because of the bizarre filename conventions on RISCOS, no port ! to that platform is easy. Note that the new variable os.endsep is ! silently supported in order to make life easier on this platform, ! but we don't advertise it because it's not worth for most folks to ! care about RISCOS portability. --- 1454,1458 ---- Schwertberger! See RISCOS/README for more information -- it seems that because of the bizarre filename conventions on RISCOS, no port ! to that platform is easy. From fdrake@users.sourceforge.net Wed Oct 24 22:10:54 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 24 Oct 2001 14:10:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libposix.tex,1.59,1.60 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv26594/lib Modified Files: libposix.tex Log Message: Minor revision of the text. Index: libposix.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libposix.tex,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -d -r1.59 -r1.60 *** libposix.tex 2001/10/20 04:24:09 1.59 --- libposix.tex 2001/10/24 21:10:52 1.60 *************** *** 89,94 **** implementation of \code{environ} which updates the environment on modification. Note also that updating \code{os.environ} will render ! this dictionary obsolete. Use of the \refmodule{os} for this is ! recommended over direct access to the \module{posix} module.} \end{datadesc} --- 89,94 ---- implementation of \code{environ} which updates the environment on modification. Note also that updating \code{os.environ} will render ! this dictionary obsolete. Use of the \refmodule{os} module version of ! this is recommended over direct access to the \module{posix} module.} \end{datadesc} From fdrake@users.sourceforge.net Wed Oct 24 22:57:01 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 24 Oct 2001 14:57:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libposixfile.tex,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv5509/lib Modified Files: libposixfile.tex Log Message: Make the deprecation notice use the same form as other such notices. This has sat around in a deprecated state for a *long* time! Index: libposixfile.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libposixfile.tex,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** libposixfile.tex 2001/10/20 04:24:09 1.24 --- libposixfile.tex 2001/10/24 21:56:59 1.25 *************** *** 12,18 **** \indexii{\POSIX{}}{file object} ! \note{This module will become obsolete in a future release. ! The locking operation that it provides is done better and more ! portably by the \function{fcntl.lockf()} call.% \withsubitem{(in module fcntl)}{\ttindex{lockf()}}} --- 12,18 ---- \indexii{\POSIX{}}{file object} ! \deprecated{1.5}{The locking operation that this module provides is ! done better and more portably by the ! \function{\refmodule{fcntl}.lockf()} call. \withsubitem{(in module fcntl)}{\ttindex{lockf()}}} From fdrake@users.sourceforge.net Wed Oct 24 23:03:38 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 24 Oct 2001 15:03:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib posixfile.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv7864 Modified Files: posixfile.py Log Message: Add a warning to the posixfile module stating that it will go away. Index: posixfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/posixfile.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** posixfile.py 2001/09/18 05:40:24 1.23 --- posixfile.py 2001/10/24 22:03:35 1.24 *************** *** 54,57 **** --- 54,64 ---- """ + import warnings + warnings.warn( + "The posixfile module is obsolete and will disappear in the future", + DeprecationWarning) + del warnings + + class _posixfile_: """File wrapper class that provides extra POSIX file routines.""" From effbot@users.sourceforge.net Wed Oct 24 23:16:32 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Wed, 24 Oct 2001 15:16:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.73,2.74 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv10490/Modules Modified Files: _sre.c Log Message: (experimental) "finditer" method/function. this works pretty much like findall, but returns an iterator (which returns match objects) instead of a list of strings/tuples. Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.73 retrieving revision 2.74 diff -C2 -d -r2.73 -r2.74 *** _sre.c 2001/10/22 21:18:08 2.73 --- _sre.c 2001/10/24 22:16:30 2.74 *************** *** 36,39 **** --- 36,40 ---- * 2001-10-21 fl added sub/subn primitive * 2001-10-22 fl check for literal sub/subn templates + * 2001-10-24 fl added finditer primitive (for 2.2 only) * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. *************** *** 1955,1958 **** --- 1956,1983 ---- } + #if PY_VERSION_HEX >= 0x02020000 + static PyObject* + pattern_finditer(PatternObject* pattern, PyObject* args) + { + PyObject* scanner; + PyObject* search; + PyObject* iterator; + + scanner = pattern_scanner(pattern, args); + if (!scanner) + return NULL; + + search = PyObject_GetAttrString(scanner, "search"); + Py_DECREF(scanner); + if (!search) + return NULL; + + iterator = PyCallIter_New(search, Py_None); + Py_DECREF(search); + + return iterator; + } + #endif + static PyObject* pattern_split(PatternObject* self, PyObject* args, PyObject* kw) *************** *** 2332,2335 **** --- 2357,2363 ---- {"split", (PyCFunction) pattern_split, METH_VARARGS|METH_KEYWORDS}, {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS}, + #if PY_VERSION_HEX >= 0x02020000 + {"finditer", (PyCFunction) pattern_finditer, METH_VARARGS}, + #endif {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS}, {"__copy__", (PyCFunction) pattern_copy, METH_VARARGS}, From effbot@users.sourceforge.net Wed Oct 24 23:16:32 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Wed, 24 Oct 2001 15:16:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sre.py,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv10490/Lib Modified Files: sre.py Log Message: (experimental) "finditer" method/function. this works pretty much like findall, but returns an iterator (which returns match objects) instead of a list of strings/tuples. Index: sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre.py,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** sre.py 2001/10/21 21:48:30 1.42 --- sre.py 2001/10/24 22:16:30 1.43 *************** *** 94,97 **** --- 94,98 ---- """ + import sys import sre_compile import sre_parse *************** *** 164,167 **** --- 165,177 ---- Empty matches are included in the result.""" return _compile(pattern, 0).findall(string) + + if sys.hexversion >= 0x02020000: + def finditer(pattern, string): + """Return an iterator over all non-overlapping matches in + the string. For each match, the iterator returns a match + object. + + Empty matches are included in the result.""" + return _compile(pattern, 0).finditer(string) def compile(pattern, flags=0): From bwarsaw@users.sourceforge.net Thu Oct 25 00:18:48 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Wed, 24 Oct 2001 16:18:48 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.9,1.10 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv25937 Modified Files: pep-0101.txt Log Message: Updates based on final decision about the inclusion of Doc/ in the source tarball (we do it), a compromise on when the branch is created, and some information about the Mac. Also, added some underlines for actual tick marks. Index: pep-0101.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0101.txt,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** pep-0101.txt 2001/10/22 19:00:55 1.9 --- pep-0101.txt 2001/10/24 23:18:46 1.10 *************** *** 17,21 **** Guido himself. But several recent releases have been performed by other folks, so this PEP attempts to collect, in one place, all ! the steps needed to make a Python release. --- 17,23 ---- Guido himself. But several recent releases have been performed by other folks, so this PEP attempts to collect, in one place, all ! the steps needed to make a Python release. It is organized as a ! recipe and you can actually print this out and check items off as ! you complete them. *************** *** 28,33 **** Otherwise, assume the step is done by the Release Manager (RM), the designated person performing the release. Almost every place ! the RM is mentioned below, this step can also be done by Guido, ! naturally! XXX: We should include a dependency graph to illustrate the steps --- 30,35 ---- Otherwise, assume the step is done by the Release Manager (RM), the designated person performing the release. Almost every place ! the RM is mentioned below, this step can also be done by the BDFL ! of course! XXX: We should include a dependency graph to illustrate the steps *************** *** 41,73 **** used, then we'll say X.Y.MaZ. ! - A day or two before the release, create a branch for X.YaZ. ! All Python development happens on the trunk. A few days before ! the release, the RM will create a branch for this release. Only ! the RM is authorized to make commits to this branch, but ! check ins can proceed as normal on the trunk. It is the ! responsibility of the RM to decide on a case-by-case basis which ! trunk modifications should be merged into the branch. To create a branch the following steps are taken: ! * Do a CVS update with the -A flag, e.g. % cvs update -A ! * CVS tag the trunk with the symbolic name "rXYaZ-fork", e.g. % cvs tag r22a3-fork ! * Make the branch with the symbolic name "rXYaZ-branch", e.g. % cvs tag -b r22a3-branch ! * Check out a clean version of the branch into a new directory. You'll be doing a lot of work in this directory and you want to keep it straight from your trunk working directory. E.g. % cvs -d -q co -d python-22a3 -r r22a3-branch python/dist/src ! - Send an email to python-dev@python.org indicating the fork and branch tags you've just created. ! - Put a freeze on check ins into the branch. At this point, nobody except the RM should make any commits to the branch (or his duly assigned agents, i.e. Guido the BDFL, Fred Drake for --- 43,95 ---- used, then we'll say X.Y.MaZ. ! ___ At noon the day before the release, create a branch for X.YaZ. ! All Python development happens on the trunk. Making releases ! from a branch allows development by the community to continue ! without impacting what ends up in the release. There's a ! natural tension here though: branching too soon causes headaches ! when the branch has to be merged back into the trunk, while ! branching too late can cause dependency problems with ! documentation and Windows release steps. ! ! The compromise is to create the branch at noon, local time, the ! day before the release. This should give enough time to Fred to ! make the documentation, then for Tim to create the Windows ! installer, both of which need to happen before the release can ! be announced. It's also short enough that hopefully not too ! many trunk changes will need to be merged into the branch, or ! vice versa. + Once the branch is made, only the RM or his appointed bots are + allowed to make commits to the branch. You can assume that Fred + is a bot for the Doc/ tree, Tim is a bot for the Windows stuff, + and Jack is a bot for Mac stuff. + + Anyone can continue to make checkins on the trunk, but if such a + change should be merged into the branch, the committer must + indicate this in the checkin message. It is the responsibility + of the RM to decide on a case-by-case basis which trunk + modifications should be merged into the branch. + To create a branch the following steps are taken: ! ___ Do a CVS update with the -A flag, e.g. % cvs update -A ! ___ CVS tag the trunk with the symbolic name "rXYaZ-fork", e.g. % cvs tag r22a3-fork ! ___ Make the branch with the symbolic name "rXYaZ-branch", e.g. % cvs tag -b r22a3-branch ! ___ Check out a clean version of the branch into a new directory. You'll be doing a lot of work in this directory and you want to keep it straight from your trunk working directory. E.g. % cvs -d -q co -d python-22a3 -r r22a3-branch python/dist/src ! ___ Send an email to python-dev@python.org indicating the fork and branch tags you've just created. ! ___ Put a freeze on check ins into the branch. At this point, nobody except the RM should make any commits to the branch (or his duly assigned agents, i.e. Guido the BDFL, Fred Drake for *************** *** 77,89 **** avoid this! ! - In the branch, change Include/patchlevel.h in two places, to reflect the new version number you've just created. You'll want to change the PY_VERSION macro, and one or several of the version subpart macros just above PY_VERSION, as appropriate. ! - For the next few days, selectively merge stuff from trunk into ! branch. For each change you see on the trunk (i.e. via the ! python-checkins mailing list), you need to decide whether the ! change should also be applied to the branch. If so, it's fairly easy to apply the change by diff'ing the file --- 99,115 ---- avoid this! ! ___ In the branch, change Include/patchlevel.h in two places, to reflect the new version number you've just created. You'll want to change the PY_VERSION macro, and one or several of the version subpart macros just above PY_VERSION, as appropriate. ! ___ For the next approximately 20 hours or so, selectively merge ! stuff from trunk into branch. For each change you see on the ! trunk (i.e. via the python-checkins mailing list), you need to ! decide whether the change should also be applied to the branch. ! ! Note that committers of changes to the trunk SHOULD include a ! in the checkin message, a note indicating the suitability of ! their patch for the branch. If so, it's fairly easy to apply the change by diff'ing the file *************** *** 93,98 **** exist in the branch! ! - The night before the release, the RM updates the Misc/NEWS file, ! adding high level items new to this release. E.g. if we're releasing 2.2a3, there must be a section at the top of the file explaining "What's new in Python 2.2a3". It will be followed by --- 119,129 ---- exist in the branch! ! ___ After creating the branch, the most important thing to do next ! is to update the Misc/NEWS file. Tim will need this in order to ! do the Windows release and he likes to stay up late. This step ! can be pretty tedious, so it's best to get to it immediately ! after making the branch. ! ! Add high level items new to this release. E.g. if we're releasing 2.2a3, there must be a section at the top of the file explaining "What's new in Python 2.2a3". It will be followed by *************** *** 105,109 **** about changes on the Mac. ! - Once the branch is frozen, Fred Drake needs to create the HTML from the documentation. He does this and uploads the file to www.python.org. Then he tells Tim Peters where this file is. --- 136,140 ---- about changes on the Mac. ! ___ Once the branch is frozen, Fred Drake needs to create the HTML from the documentation. He does this and uploads the file to www.python.org. Then he tells Tim Peters where this file is. *************** *** 114,118 **** Info format. ! - Tim Peters grabs the HTML and uses this to build the Windows installer. Tim then creates a new "release" named X.YaZ on the SourceForge file release manager. --- 145,154 ---- Info format. ! Note that Fred is responsible both for merging doc changes from ! the trunk to the branch AND for merging any branch changes from ! the branch to the trunk during the cleaning up phase. ! Basically, if it's in Doc/ Fred will take care of it. ! ! ___ Tim Peters grabs the HTML and uses this to build the Windows installer. Tim then creates a new "release" named X.YaZ on the SourceForge file release manager. *************** *** 130,134 **** number. ! - Tim performs his Windows magic, generating an installer executable. He uploads this file to SourceForge under the release he just created. He then sends the RM a notice which --- 166,170 ---- number. ! ___ Tim performs his Windows magic, generating an installer executable. He uploads this file to SourceForge under the release he just created. He then sends the RM a notice which *************** *** 136,170 **** Note that Tim's creation of the Windows executable may generate ! a few more commits on the branch. ! - Now, you're ready to build the source tarball. First cd to your working directory for the branch. E.g. % cd .../python-22a3 ! - Do a "cvs update" in this directory. You should not see any "M" ! files, but you may see several "P" files. I.e. you better not ! have any uncommitted changes in your working directory, but you ! may pick up some of Fred's or Tim's last minute changes. ! - Now tag the branch using a symbolic name like "rXYaZ", e.g. r22a3 % cvs tag r22a3 ! - Change to a neutral directory, i.e. one in which you can do a ! fresh, virgin, export of the branch. You will be creating a new ! directory at this location, to be named "Python-X.YaZ". Do a ! CVS export of the tagged branch. % cd ~ % cvs -d export -rr22a3 -d Python-2.2a3 python/dist/src - - - Remove the documentation sources from the export; these are only - useful to people who have LaTeX and possibly several other tools - installed (how many tools are required depends on the - documentation format you want to end up with). These also add - substantially to the size of the resulting archive (almost a - megabyte for Python 2.2). - % rm -r Python-.2a3/Doc/ ! - Generate the tarball. Note that we're not using the `z' option on the tar command because 1) that's only supported by GNU tar as far as we know, and 2) we're going to max out the compression --- 172,205 ---- Note that Tim's creation of the Windows executable may generate ! a few more commits on the branch. Tim will be responsible for ! merging Windows-specific changes from trunk to branch, and from ! branch to trunk. ! ___ It's Noon! ! ! Now, you're ready to build the source tarball. First cd to your working directory for the branch. E.g. % cd .../python-22a3 ! ___ Do a "cvs update" in this directory. Do NOT include the -A flag! ! You should not see any "M" files, but you may see several "P" ! files. I.e. you better not have any uncommitted changes in your ! working directory, but you may pick up some of Fred's or Tim's ! last minute changes. ! ! ___ Now tag the branch using a symbolic name like "rXYaZ", e.g. r22a3 % cvs tag r22a3 ! ___ Change to a neutral directory, i.e. one in which you can do a ! fresh, virgin, cvs export of the branch. You will be creating a ! new directory at this location, to be named "Python-X.YaZ". Do ! a CVS export of the tagged branch. ! % cd ~ % cvs -d export -rr22a3 -d Python-2.2a3 python/dist/src ! ___ Generate the tarball. Note that we're not using the `z' option on the tar command because 1) that's only supported by GNU tar as far as we know, and 2) we're going to max out the compression *************** *** 172,176 **** % tar cf - Python-2.2a2 | gzip -9 > Python-2.2a2.tgz ! - Calculate the MD5 checksum of the tgz file you just created % md5sum Python-2.2a2.tgz --- 207,211 ---- % tar cf - Python-2.2a2 | gzip -9 > Python-2.2a2.tgz ! ___ Calculate the MD5 checksum of the tgz file you just created % md5sum Python-2.2a2.tgz *************** *** 178,182 **** Python replacement in the Tools/scripts/md5sum.py file. ! - Now you want to perform the very important step of checking the tarball you just created, to make sure a completely clean, virgin build passes the regression test. Here are the best --- 213,217 ---- Python replacement in the Tools/scripts/md5sum.py file. ! ___ Now you want to perform the very important step of checking the tarball you just created, to make sure a completely clean, virgin build passes the regression test. Here are the best *************** *** 194,202 **** If the tests pass, then you can feel good that the tarball is ! fine. If some of the tests pass, or anything else about the freshly unpacked directory looks weird, you better stop now and figure out what the problem is. ! - Start your upload to SF. You need to get Python-2.2a3.tgz into SourceForge. This can take a while both because of the time it takes to upload such a huge file, /and/ because SF has a 30 --- 229,237 ---- If the tests pass, then you can feel good that the tarball is ! fine. If some of the tests fail, or anything else about the freshly unpacked directory looks weird, you better stop now and figure out what the problem is. ! ___ Start your upload to SF. You need to get Python-2.2a3.tgz into SourceForge. This can take a while both because of the time it takes to upload such a huge file, /and/ because SF has a 30 *************** *** 208,212 **** you have it available. You can execute the following command to do the upload: ! % ncftpput -F upload.sf.net incoming Python-2.2a3.tgz If you don't have ncftpput around, you can use whatever ftp --- 243,247 ---- you have it available. You can execute the following command to do the upload: ! % ncftpput upload.sf.net incoming Python-2.2a3.tgz If you don't have ncftpput around, you can use whatever ftp *************** *** 214,218 **** uploading this to the "incoming" directory on upload.sf.net. ! - You also need to upload the tgz file to creosote.python.org. Usually Tim will have already uploaded the exe file to creosote, but if not, you'll need to do that too. These steps can take a --- 249,253 ---- uploading this to the "incoming" directory on upload.sf.net. ! ___ You also need to upload the tgz file to creosote.python.org. Usually Tim will have already uploaded the exe file to creosote, but if not, you'll need to do that too. These steps can take a *************** *** 230,237 **** done if you're on a small pipe. ! - While you're waiting, you can start twiddling the web pages to include the announcement. ! * In the python.org web site CVS tree, cd to the X.Y subdirectory, and copy index.ht to new-index.ht --- 265,274 ---- done if you're on a small pipe. ! I usually opt for #2. ! ! ___ While you're waiting, you can start twiddling the web pages to include the announcement. ! ___ In the python.org web site CVS tree, cd to the X.Y subdirectory, and copy index.ht to new-index.ht *************** *** 239,243 **** % cp index.ht new-index.ht ! * Edit the file for content: usually you can globally replace X.Ya(Z-1) with X.YaZ. However, you'll need to think about the "What's New?" section. You also need to watch out about two --- 276,280 ---- % cp index.ht new-index.ht ! ___ Edit the file for content: usually you can globally replace X.Ya(Z-1) with X.YaZ. However, you'll need to think about the "What's New?" section. You also need to watch out about two *************** *** 248,257 **** below. For now just note what needs to change. ! Also, update the MD5 checksums. ! * Preview the web page by doing a "make" -- NOT a "make install". View the page via a file: url. ! * Similarly, edit the ../index.ht file, i.e. the python.org home page. In the Big Blue Announcement Block, move the paragraph for the new version up to the top and boldify the phrase --- 285,294 ---- below. For now just note what needs to change. ! ___ Also, update the MD5 checksums. ! ___ Preview the web page by doing a "make" -- NOT a "make install". View the page via a file: url. ! ___ Similarly, edit the ../index.ht file, i.e. the python.org home page. In the Big Blue Announcement Block, move the paragraph for the new version up to the top and boldify the phrase *************** *** 259,278 **** above. Do NOT do a "make install" yet! ! - Now we're waiting for the ncftpput command, and the scp to creosote to finish. Da de da, da de dum, hmm, hmm, dum de dum. ! - Do the SourceForge file release dance. ! * Go to the Python project and click on "Admin" ! * Click on "Edit/Release Files" ! * Since Tim has usually by now created the package and release we're going to use, scroll down and click on "Edit Releases" for the package we're releasing into. ! * Find the release named X.YaZ and click on "Edit This Release" You should now perform Step 1 of the file release dance... ! * The "Status" field should be "Active" not "Hidden" ! * In the text box that says "Paste The Notes In", paste in all the "What's New" entries from the Misc/NEWS file that describe this major version of Python, /not/ just the ones for this --- 296,315 ---- above. Do NOT do a "make install" yet! ! ___ Now we're waiting for the ncftpput command, and the scp to creosote to finish. Da de da, da de dum, hmm, hmm, dum de dum. ! ___ Do the SourceForge file release dance. ! ___ Go to the Python project and click on "Admin" ! ___ Click on "Edit/Release Files" ! ___ Since Tim has usually by now created the package and release we're going to use, scroll down and click on "Edit Releases" for the package we're releasing into. ! ___ Find the release named X.YaZ and click on "Edit This Release" You should now perform Step 1 of the file release dance... ! ___ The "Status" field should be "Active" not "Hidden" ! ___ In the text box that says "Paste The Notes In", paste in all the "What's New" entries from the Misc/NEWS file that describe this major version of Python, /not/ just the ones for this *************** *** 280,286 **** we'd include the "What's New" sections for Python 2.2a3, 2.2a2, and 2.2a1. ! * Leave the "Paste The Change Log In" section blank, but click on "Preserve my pre-formatted text". ! * Hit the Submit/Refresh button for Step 1. This will bring you back to the file release page. DO NOT do --- 317,323 ---- we'd include the "What's New" sections for Python 2.2a3, 2.2a2, and 2.2a1. ! ___ Leave the "Paste The Change Log In" section blank, but click on "Preserve my pre-formatted text". ! ___ Hit the Submit/Refresh button for Step 1. This will bring you back to the file release page. DO NOT do *************** *** 288,292 **** is, you can perform Step 2 of the file release dance... ! * Click on the checkbox next to the file Python-X.YaZ.tgz. Be sure no other box is checked! Then click on the "Add Files and/or Refresh View" button for Step 2. --- 325,329 ---- is, you can perform Step 2 of the file release dance... ! ___ Click on the checkbox next to the file Python-X.YaZ.tgz. Be sure no other box is checked! Then click on the "Add Files and/or Refresh View" button for Step 2. *************** *** 294,304 **** And now, Step 3... ! * There should be exactly two files listed here, one is the tgz file you just added, and the other is the exe file that Tim added earlier. ! * For the tgz file, be sure that the "Processor" field says "Any" and the "File Type" field says "Source .gz". ! * Click on "Update/Refresh" for the .tgz file. ! * For the exe file, make sure that the "Processor" field says "i386" and the "File Type" field says "Other". Tim usually gets this right , but if not, make any necessary changes --- 331,341 ---- And now, Step 3... ! ___ There should be exactly two files listed here, one is the tgz file you just added, and the other is the exe file that Tim added earlier. ! ___ For the tgz file, be sure that the "Processor" field says "Any" and the "File Type" field says "Source .gz". ! ___ Click on "Update/Refresh" for the .tgz file. ! ___ For the exe file, make sure that the "Processor" field says "i386" and the "File Type" field says "Other". Tim usually gets this right , but if not, make any necessary changes *************** *** 310,314 **** announcement to send the SF email notice. ! - Still on SF, click on the "Files" button at the top of the page. Find the release you've just made and click on it -- not on the tgz or exe file, but on the release link under the --- 347,351 ---- announcement to send the SF email notice. ! ___ Still on SF, click on the "Files" button at the top of the page. Find the release you've just made and click on it -- not on the tgz or exe file, but on the release link under the *************** *** 322,326 **** "shownotes" link mentioned earlier. ! - Now click on the "Summary" link at the top of the page and scroll down to the "Latest File Releases" section. Find the package you just made a release for (the Version should be --- 359,363 ---- "shownotes" link mentioned earlier. ! ___ Now click on the "Summary" link at the top of the page and scroll down to the "Latest File Releases" section. Find the package you just made a release for (the Version should be *************** *** 333,337 **** "showfiles" link mentioned earlier. ! - Now you need to go to creosote.python.org and move all the files in place over there. Our policy is that every Python version gets its own directory, but each directory may contain several --- 370,374 ---- "showfiles" link mentioned earlier. ! ___ Now you need to go to creosote.python.org and move all the files in place over there. Our policy is that every Python version gets its own directory, but each directory may contain several *************** *** 345,373 **** So... ! * On creosote, cd to ~ftp/pub/python/X.Y creating it if necessary. ! * Move the previous release files to a directory called "prev" creating the directory if necessary (make sure the directory has g+ws bits on). If this is the first alpha release of a new Python version, skip this step. ! * Move the .tgz file and the .exe file to this directory. Make sure they are world readable. They should also be group writable, and group-owned by webmaster. ! - Update the X.Y/bugs.ht file if necessary. You may need to get BDFL input for this step. ! - Now preview the new-index.ht file once more. IMPORTANT: follow every link on the page to make sure it goes where you expect it to go, and that what you expect to be there is there. ! - If everything looks good, move new-index.ht to index.ht and do a "make install" in this directory. Go up to the parent directory (i.e. the root of the web page hierarchy) and do a "make install" there too. You're release is now live! ! - Now it's time to write the announcement for the mailing lists. This is the fuzzy bit because not much can be automated. You can use one of Guido's earlier announcements as a template, but --- 382,410 ---- So... ! ___ On creosote, cd to ~ftp/pub/python/X.Y creating it if necessary. ! ___ Move the previous release files to a directory called "prev" creating the directory if necessary (make sure the directory has g+ws bits on). If this is the first alpha release of a new Python version, skip this step. ! ___ Move the .tgz file and the .exe file to this directory. Make sure they are world readable. They should also be group writable, and group-owned by webmaster. ! ___ Update the X.Y/bugs.ht file if necessary. It is best to get BDFL input for this step. ! ___ Now preview the new-index.ht file once more. IMPORTANT: follow every link on the page to make sure it goes where you expect it to go, and that what you expect to be there is there. ! ___ If everything looks good, move new-index.ht to index.ht and do a "make install" in this directory. Go up to the parent directory (i.e. the root of the web page hierarchy) and do a "make install" there too. You're release is now live! ! ___ Now it's time to write the announcement for the mailing lists. This is the fuzzy bit because not much can be automated. You can use one of Guido's earlier announcements as a template, but *************** *** 381,390 **** python-dev@python.org ! - Go back to the file releases page on SF and complete Step 4, sending out the email notification. Now it's time to do some cleanup. These steps are very important! ! - Go back to SF, Admin->Edit/Release Files. Click on "Edit Releases" for the package you just added to. For each old release, click on "Edit This Release" and under Step 1, change --- 418,427 ---- python-dev@python.org ! ___ Go back to the file releases page on SF and complete Step 4, sending out the email notification. Now it's time to do some cleanup. These steps are very important! ! ___ Go back to SF, Admin->Edit/Release Files. Click on "Edit Releases" for the package you just added to. For each old release, click on "Edit This Release" and under Step 1, change *************** *** 392,413 **** button. ! - Merge the branch back into the trunk! Now that we've released this branch, we don't need it any more. We've already tagged it so we can always reproduce it. Note that merging branches is a bit of a black art, but here's what's worked for us. ! * Check out a completely clean, virgin working directory of the trunk, by doing this in the directory that is the parent of your branch working directory python-XYaZ: % cvs -d co -d python-clean python/dist/src ! * Run a diff against your branch by doing this in the common parent directory containing both python-clean and python-XYaZ: % diff -r python-clean python-22a2 | grep ^diff | grep -v CVS ! * Take the output of this and stick it in a file, e.g. /tmp/diffcmd.sh ! * Edit diffcmd.sh to get rid of files that you know don't have important changes. You're looking for files that have updates in the branch that haven't made it to the trunk. If you've --- 429,450 ---- button. ! ___ Merge the branch back into the trunk! Now that we've released this branch, we don't need it any more. We've already tagged it so we can always reproduce it. Note that merging branches is a bit of a black art, but here's what's worked for us. ! ___ Check out a completely clean, virgin working directory of the trunk, by doing this in the directory that is the parent of your branch working directory python-XYaZ: % cvs -d co -d python-clean python/dist/src ! ___ Run a diff against your branch by doing this in the common parent directory containing both python-clean and python-XYaZ: % diff -r python-clean python-22a2 | grep ^diff | grep -v CVS ! ___ Take the output of this and stick it in a file, e.g. /tmp/diffcmd.sh ! ___ Edit diffcmd.sh to get rid of files that you know don't have important changes. You're looking for files that have updates in the branch that haven't made it to the trunk. If you've *************** *** 415,423 **** branch, there shouldn't be many of these files. ! * Edit /tmp/diffcmd.sh, changing all the -r's into -u's. Run the /tmp/diffcmd.sh command like so: % sh /tmp/diffcmd.sh > /tmp/pydiff.txt ! * Attempt to patch your python-clean working directory. Do this first, noting that --dry-run does not actually apply any patches, it just makes sure that the patch command runs --- 452,460 ---- branch, there shouldn't be many of these files. ! ___ Edit /tmp/diffcmd.sh, changing all the -r's into -u's. Run the /tmp/diffcmd.sh command like so: % sh /tmp/diffcmd.sh > /tmp/pydiff.txt ! ___ Attempt to patch your python-clean working directory. Do this first, noting that --dry-run does not actually apply any patches, it just makes sure that the patch command runs *************** *** 425,438 **** % patch -p1 --dry-run < /tmp/pydiff.txt ! * If this goes well, run it again, taking out the --dry-run option. If this fails, or if it prompts you for a file to patch, try using -p0 instead of -p1. Otherwise, your diff command was messed up, so try again. ! * cd to python-clean and do a "cvs commit". Use as your log message something like "Merging the rXYaZ-branch tag back into the trunk". ! * Edit the file Include/patchlevel.h so that the PY_VERSION string says something like "X.YaZ+". Note the trailing `+' indicating that the trunk is going to be moving forward with --- 462,475 ---- % patch -p1 --dry-run < /tmp/pydiff.txt ! ___ If this goes well, run it again, taking out the --dry-run option. If this fails, or if it prompts you for a file to patch, try using -p0 instead of -p1. Otherwise, your diff command was messed up, so try again. ! ___ cd to python-clean and do a "cvs commit". Use as your log message something like "Merging the rXYaZ-branch tag back into the trunk". ! ___ Edit the file Include/patchlevel.h so that the PY_VERSION string says something like "X.YaZ+". Note the trailing `+' indicating that the trunk is going to be moving forward with *************** *** 444,448 **** correct values. Commit this change. ! * Now test your clean, merged trunk by doing % make distclean % ./configure --- 481,491 ---- correct values. Commit this change. ! ___ For the extra paranoid, do a completely clean test of the ! release. This includes downloading the tarball from either ! SourceForge or www.python.org. ! ! ___ Make sure the md5 checksums match. Then unpack the tarball, ! and do a clean make test. ! % make distclean % ./configure *************** *** 469,472 **** --- 512,522 ---- You've just made a Python release! + + Actually, there is one more step. You should turn over ownership + of the branch to Jack Jansen. All this means is that now he will + be responsible for making commits to the branch. He's going to + use this to build the MacOS versions. He may send you information + about the Mac release that should be merged into the informational + pages on SourceForge or www.python.org. From bwarsaw@users.sourceforge.net Thu Oct 25 06:19:21 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Wed, 24 Oct 2001 22:19:21 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv25249 Modified Files: pep-0101.txt Log Message: Integrated some of Guido's comments. Index: pep-0101.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0101.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** pep-0101.txt 2001/10/24 23:18:46 1.10 --- pep-0101.txt 2001/10/25 05:19:19 1.11 *************** *** 109,115 **** decide whether the change should also be applied to the branch. ! Note that committers of changes to the trunk SHOULD include a ! in the checkin message, a note indicating the suitability of ! their patch for the branch. If so, it's fairly easy to apply the change by diff'ing the file --- 109,115 ---- decide whether the change should also be applied to the branch. ! Note that committers of changes to the trunk SHOULD include in ! the checkin message, a note indicating the suitability of their ! patch for the branch. If so, it's fairly easy to apply the change by diff'ing the file *************** *** 523,555 **** Windows Notes ! Windows has a GUI installer, various flavors of Windows have "special ! limitations", and the Windows installer also packs precompiled ! "foreign" binaries (Tcl/Tk, expat, etc). So Windows testing is ! tiresome but very necessary. ! Concurrent with uploading the installer, I install Python from it ! twice: once into the default directory suggested by the installer, ! and later into a directory with embedded spaces in its name. For ! each installation, run the full regression suite from a DOS box, and ! both with and without -0. Also try *every* shortcut created under ! Start -> Menu -> the Python group. When trying IDLE this way, verify ! that Help -> Python Documentation works. When trying pydoc this way ! (the "Module Docs" Start menu entry), make sure the "Start Browser" ! button works, and make sure you can search for a random module (I ! use "random" ) and then that the "go to selected" button works. ! It's amazing how much can go wrong here -- and even more amazing how ! often last-second checkins break one of these things. If you're "the ! Windows geek", keep in mind that you're likely the only person ! routinely testing on Windows, and that Windows is simply a mess. ! Repeat all of the above on at least one flavor of Win9x, and one of ! NT/2000. On NT/2000, try both an Admin and a plain User (not Power ! User) account. ! WRT Step 5 above (verify the release media), since by the time release ! files are ready to download I've generally run many Windows tests on ! the installer I uploaded, I usually don't do anything for Step 5 ! except a full byte-comparison ("fc /b" if using a Windows shell) of ! the downloaded file against the file I uploaded. --- 523,561 ---- Windows Notes ! Windows has a GUI installer, various flavors of Windows have ! "special limitations", and the Windows installer also packs ! precompiled "foreign" binaries (Tcl/Tk, expat, etc). So Windows ! testing is tiresome but very necessary. ! Concurrent with uploading the installer, Tim installs Python from ! it twice: once into the default directory suggested by the ! installer, and later into a directory with embedded spaces in its ! name. For each installation, he runs the full regression suite ! from a DOS box, and both with and without -0. ! He also tries *every* shortcut created under Start -> Menu -> the ! Python group. When trying IDLE this way, you need to verify that ! Help -> Python Documentation works. When trying pydoc this way ! (the "Module Docs" Start menu entry), make sure the "Start ! Browser" button works, and make sure you can search for a random ! module (Tim uses "random" ) and then that the "go to ! selected" button works. ! It's amazing how much can go wrong here -- and even more amazing ! how often last-second checkins break one of these things. If ! you're "the Windows geek", keep in mind that you're likely the ! only person routinely testing on Windows, and that Windows is ! simply a mess. ! ! Repeat all of the above on at least one flavor of Win9x, and one ! of NT/2000. On NT/2000, try both an Admin and a plain User (not ! Power User) account. ! ! WRT Step 5 above (verify the release media), since by the time ! release files are ready to download Tim has generally run many ! Windows tests on the installer he uploaded, he usually doesn't do ! anything for Step 5 except a full byte-comparison ("fc /b" if ! using a Windows shell) of the downloaded file against the file he ! uploaded. From loewis@users.sourceforge.net Thu Oct 25 10:04:05 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Thu, 25 Oct 2001 02:04:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.186,1.187 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv10605 Modified Files: socketmodule.c Log Message: After discussion with itojun, it was clarified that Tru64 is in error, and that the work-around should be restricted to that system. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.186 retrieving revision 1.187 diff -C2 -d -r1.186 -r1.187 *** socketmodule.c 2001/10/24 20:37:10 1.186 --- socketmodule.c 2001/10/25 09:04:03 1.187 *************** *** 614,623 **** hints.ai_family = af; error = getaddrinfo(name, NULL, &hints, &res); if (error == EAI_NONAME && af == AF_UNSPEC) { ! /* On OSF/1 V5.1, numeric-to-addr conversion fails if no address family is given. Assume IPv4 for now.*/ hints.ai_family = AF_INET; error = getaddrinfo(name, NULL, &hints, &res); } if (error) { PyGAI_Err(error); --- 614,625 ---- hints.ai_family = af; error = getaddrinfo(name, NULL, &hints, &res); + #if defined(__digital__) && defined(__unix__) if (error == EAI_NONAME && af == AF_UNSPEC) { ! /* On Tru64 V5.1, numeric-to-addr conversion fails if no address family is given. Assume IPv4 for now.*/ hints.ai_family = AF_INET; error = getaddrinfo(name, NULL, &hints, &res); } + #endif if (error) { PyGAI_Err(error); From fdrake@users.sourceforge.net Thu Oct 25 16:12:33 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 25 Oct 2001 08:12:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile,1.228,1.229 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv25672 Modified Files: Makefile Log Message: Update the rules so that changes to the HTML stylesheet cause appropriate work to be done, but do not require the HTML to be re-built. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile,v retrieving revision 1.228 retrieving revision 1.229 diff -C2 -d -r1.228 -r1.229 *** Makefile 2001/10/19 21:12:57 1.228 --- Makefile 2001/10/25 15:12:31 1.229 *************** *** 111,114 **** --- 111,136 ---- PSFILES= $(MANPSFILES) $(HOWTOPSFILES) + HTMLCSSFILES=html/api/api.css \ + html/doc/doc.css \ + html/ext/ext.css \ + html/lib/lib.css \ + html/mac/mac.css \ + html/ref/ref.css \ + html/tut/tut.css \ + html/inst/inst.css \ + html/dist/dist.css + + ISILOCSSFILES=isilo/api/api.css \ + isilo/doc/doc.css \ + isilo/ext/ext.css \ + isilo/lib/lib.css \ + isilo/mac/mac.css \ + isilo/ref/ref.css \ + isilo/tut/tut.css \ + isilo/inst/inst.css \ + isilo/dist/dist.css + + ALLCSSFILES=$(HTMLCSSFILES) $(ISILOCSSFILES) + INDEXFILES=html/api/api.html \ html/doc/doc.html \ *************** *** 239,242 **** --- 261,267 ---- # Python documentation. + $(ALLCSSFILES): html/style.css + cp $< $@ + $(INDEXFILES): $(COMMONPERL) html/about.dat tools/node2label.pl *************** *** 264,294 **** lib/modindex.html mac/modindex.html ! html: $(ALLHTMLFILES) ! api html/api/api.html: $(APIFILES) $(MKHTML) --dir html/api api/api.tex ! doc html/doc/doc.html: $(DOCFILES) $(MKHTML) --dir html/doc doc/doc.tex ! ext html/ext/ext.html: $(EXTFILES) $(MKHTML) --dir html/ext ext/ext.tex ! lib html/lib/lib.html: $(LIBFILES) $(MKHTML) --dir html/lib lib/lib.tex ! mac html/mac/mac.html: $(MACFILES) $(MKHTML) --dir html/mac mac/mac.tex ! ref html/ref/ref.html: $(REFFILES) $(MKHTML) --dir html/ref ref/ref.tex ! tut html/tut/tut.html: $(TUTFILES) $(MKHTML) --dir html/tut --numeric --split 3 tut/tut.tex ! inst html/inst/inst.html: $(INSTFILES) perl/distutils.perl $(MKHTML) --dir html/inst --split 4 inst/inst.tex ! dist html/dist/dist.html: $(DISTFILES) perl/distutils.perl $(MKHTML) --dir html/dist --split 4 dist/dist.tex --- 289,328 ---- lib/modindex.html mac/modindex.html ! html: $(ALLHTMLFILES) $(HTMLCSSFILES) ! api: html/api/api.html html/api/api.css ! html/api/api.html: $(APIFILES) $(MKHTML) --dir html/api api/api.tex ! doc: html/doc/doc.html html/doc/doc.css ! html/doc/doc.html: $(DOCFILES) $(MKHTML) --dir html/doc doc/doc.tex ! ext: html/ext/ext.html html/ext/ext.css ! html/ext/ext.html: $(EXTFILES) $(MKHTML) --dir html/ext ext/ext.tex ! lib: html/lib/lib.html html/lib/lib.css ! html/lib/lib.html: $(LIBFILES) $(MKHTML) --dir html/lib lib/lib.tex ! mac: html/mac/mac.html html/mac/mac.css ! html/mac/mac.html: $(MACFILES) $(MKHTML) --dir html/mac mac/mac.tex ! ref: html/ref/ref.html html/ref/ref.css ! html/ref/ref.html: $(REFFILES) $(MKHTML) --dir html/ref ref/ref.tex ! tut: html/tut/tut.html html/tut/tut.css ! html/tut/tut.html: $(TUTFILES) $(MKHTML) --dir html/tut --numeric --split 3 tut/tut.tex ! inst: html/inst/inst.html html/inst/inst.css ! html/inst/inst.html: $(INSTFILES) perl/distutils.perl $(MKHTML) --dir html/inst --split 4 inst/inst.tex ! dist: html/dist/dist.html html/dist/dist.css ! html/dist/dist.html: $(DISTFILES) perl/distutils.perl $(MKHTML) --dir html/dist --split 4 dist/dist.tex *************** *** 318,354 **** isilo/python-inst-$(RELEASE).pdb ! isilo/python-api-$(RELEASE).pdb: isilo/api/api.html $(MKISILO) "-iPython/C API Reference Manual" \ isilo/api/api.html $@ ! isilo/python-doc-$(RELEASE).pdb: isilo/doc/doc.html $(MKISILO) "-iDocumenting Python" \ isilo/doc/doc.html $@ ! isilo/python-ext-$(RELEASE).pdb: isilo/ext/ext.html $(MKISILO) "-iExtending & Embedding Python" \ isilo/ext/ext.html $@ ! isilo/python-lib-$(RELEASE).pdb: isilo/lib/lib.html $(MKISILO) "-iPython Library Reference" \ isilo/lib/lib.html $@ ! isilo/python-mac-$(RELEASE).pdb: isilo/mac/mac.html $(MKISILO) "-iPython/C API Reference Manual" \ isilo/mac/mac.html $@ ! isilo/python-ref-$(RELEASE).pdb: isilo/ref/ref.html $(MKISILO) "-iPython Reference Manual" \ isilo/ref/ref.html $@ ! isilo/python-tut-$(RELEASE).pdb: isilo/tut/tut.html $(MKISILO) "-iPython Tutorial" \ isilo/tut/tut.html $@ ! isilo/python-dist-$(RELEASE).pdb: isilo/dist/dist.html $(MKISILO) "-iDistributing Python Modules" \ isilo/dist/dist.html $@ ! isilo/python-inst-$(RELEASE).pdb: isilo/inst/inst.html $(MKISILO) "-iInstalling Python Modules" \ isilo/inst/inst.html $@ --- 352,388 ---- isilo/python-inst-$(RELEASE).pdb ! isilo/python-api-$(RELEASE).pdb: isilo/api/api.html isilo/api/api.css $(MKISILO) "-iPython/C API Reference Manual" \ isilo/api/api.html $@ ! isilo/python-doc-$(RELEASE).pdb: isilo/doc/doc.html isilo/doc/doc.css $(MKISILO) "-iDocumenting Python" \ isilo/doc/doc.html $@ ! isilo/python-ext-$(RELEASE).pdb: isilo/ext/ext.html isilo/ext/ext.css $(MKISILO) "-iExtending & Embedding Python" \ isilo/ext/ext.html $@ ! isilo/python-lib-$(RELEASE).pdb: isilo/lib/lib.html isilo/lib/lib.css $(MKISILO) "-iPython Library Reference" \ isilo/lib/lib.html $@ ! isilo/python-mac-$(RELEASE).pdb: isilo/mac/mac.html isilo/mac/mac.css $(MKISILO) "-iPython/C API Reference Manual" \ isilo/mac/mac.html $@ ! isilo/python-ref-$(RELEASE).pdb: isilo/ref/ref.html isilo/ref/ref.css $(MKISILO) "-iPython Reference Manual" \ isilo/ref/ref.html $@ ! isilo/python-tut-$(RELEASE).pdb: isilo/tut/tut.html isilo/tut/tut.css $(MKISILO) "-iPython Tutorial" \ isilo/tut/tut.html $@ ! isilo/python-dist-$(RELEASE).pdb: isilo/dist/dist.html isilo/dist/dist.css $(MKISILO) "-iDistributing Python Modules" \ isilo/dist/dist.html $@ ! isilo/python-inst-$(RELEASE).pdb: isilo/inst/inst.html isilo/inst/inst.css $(MKISILO) "-iInstalling Python Modules" \ isilo/inst/inst.html $@ *************** *** 468,472 **** cd paper-$(PAPER) && zip -q -9 ../$@ *.ps README ! html-$(RELEASE).tar: $(ALLHTMLFILES) cd html && \ tar cf ../html-$(RELEASE).tar *.html */*.css */*.html \ --- 502,506 ---- cd paper-$(PAPER) && zip -q -9 ../$@ *.ps README ! html-$(RELEASE).tar: $(ALLHTMLFILES) $(HTMLCSSFILES) cd html && \ tar cf ../html-$(RELEASE).tar *.html */*.css */*.html \ *************** *** 479,483 **** bzip2 -9 <$? >$@ ! html-$(RELEASE).zip: $(ALLHTMLFILES) rm -f $@ cd html && \ --- 513,517 ---- bzip2 -9 <$? >$@ ! html-$(RELEASE).zip: $(ALLHTMLFILES) $(HTMLCSSFILES) rm -f $@ cd html && \ From fdrake@users.sourceforge.net Thu Oct 25 16:13:32 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 25 Oct 2001 08:13:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools push-docs.sh,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools In directory usw-pr-cvs1:/tmp/cvs-serv25983/tools Modified Files: push-docs.sh Log Message: No need to run make twice here. Index: push-docs.sh =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/push-docs.sh,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** push-docs.sh 2001/08/08 05:41:01 1.12 --- push-docs.sh 2001/10/25 15:13:30 1.13 *************** *** 65,69 **** # now in .../Doc/ - make --no-print-directory || exit $? make --no-print-directory bziphtml || exit $? RELEASE=`grep '^RELEASE=' Makefile | sed 's|RELEASE=||'` --- 65,68 ---- From fdrake@users.sourceforge.net Thu Oct 25 16:14:59 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 25 Oct 2001 08:14:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv conversion.xml,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv26320/tools/sgmlconv Modified Files: conversion.xml Log Message: One more LaTeX-ism that we'd rather ignore. Index: conversion.xml =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/conversion.xml,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** conversion.xml 2001/10/09 18:01:23 1.22 --- conversion.xml 2001/10/25 15:14:57 1.23 *************** *** 875,878 **** --- 875,879 ---- + From bwarsaw@users.sourceforge.net Thu Oct 25 16:41:31 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 08:41:31 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.11,1.12 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv1926 Modified Files: pep-0101.txt Log Message: More Guido feedback Index: pep-0101.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0101.txt,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** pep-0101.txt 2001/10/25 05:19:19 1.11 --- pep-0101.txt 2001/10/25 15:41:29 1.12 *************** *** 104,111 **** version subpart macros just above PY_VERSION, as appropriate. ! ___ For the next approximately 20 hours or so, selectively merge ! stuff from trunk into branch. For each change you see on the ! trunk (i.e. via the python-checkins mailing list), you need to ! decide whether the change should also be applied to the branch. Note that committers of changes to the trunk SHOULD include in --- 104,121 ---- version subpart macros just above PY_VERSION, as appropriate. ! ___ For the next few hours, selectively merge stuff from trunk into ! branch. For each change you see on the trunk (i.e. via the ! python-checkins mailing list), you need to decide whether the ! change should also be applied to the branch. ! ! There is a tension here. Announcing the branch often jogs ! people's natural tendency to procrastinate so some very useful ! patches end up getting checked in at the last moment. But the ! Windows and Docs releases tend to be built many hours before the ! source release, and changes to the branch can force a lot of ! wasted effort to rebuild them. The best advice is to be ! judicious and to consult Fred and Tim before adding anything ! big. You really want to avoid skew between the various platform ! releases. Note that committers of changes to the trunk SHOULD include in *************** *** 123,127 **** do the Windows release and he likes to stay up late. This step can be pretty tedious, so it's best to get to it immediately ! after making the branch. Add high level items new to this release. E.g. if we're --- 133,139 ---- do the Windows release and he likes to stay up late. This step can be pretty tedious, so it's best to get to it immediately ! after making the branch, or even before you've made the branch. ! The sooner the better (but again, watch for new checkins up ! until the release is made!) Add high level items new to this release. E.g. if we're From bwarsaw@users.sourceforge.net Thu Oct 25 16:42:59 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 08:42:59 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.12,1.13 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv2263 Modified Files: pep-0101.txt Log Message: Jack rightly suggests doing the cvs update with -d -P and -A. Index: pep-0101.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0101.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** pep-0101.txt 2001/10/25 15:41:29 1.12 --- pep-0101.txt 2001/10/25 15:42:57 1.13 *************** *** 74,79 **** To create a branch the following steps are taken: ! ___ Do a CVS update with the -A flag, e.g. ! % cvs update -A ___ CVS tag the trunk with the symbolic name "rXYaZ-fork", e.g. --- 74,79 ---- To create a branch the following steps are taken: ! ___ Do a CVS update with the -A, -d, and -P flags, e.g. ! % cvs -q update -d -P -A ___ CVS tag the trunk with the symbolic name "rXYaZ-fork", e.g. From fdrake@users.sourceforge.net Thu Oct 25 16:53:47 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 25 Oct 2001 08:53:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api intro.tex,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv4884/api Modified Files: intro.tex Log Message: Slightly better conformance to the Python C style guide. Index: intro.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/intro.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** intro.tex 2001/10/12 19:01:43 1.1 --- intro.tex 2001/10/25 15:53:44 1.2 *************** *** 251,255 **** \begin{verbatim} ! int set_all(PyObject *target, PyObject *item) { int i, n; --- 251,256 ---- \begin{verbatim} ! int ! set_all(PyObject *target, PyObject *item) { int i, n; *************** *** 294,298 **** \begin{verbatim} ! long sum_list(PyObject *list) { int i, n; --- 295,300 ---- \begin{verbatim} ! long ! sum_list(PyObject *list) { int i, n; *************** *** 314,318 **** \begin{verbatim} ! long sum_sequence(PyObject *sequence) { int i, n; --- 316,321 ---- \begin{verbatim} ! long ! sum_sequence(PyObject *sequence) { int i, n; *************** *** 433,437 **** \begin{verbatim} ! int incr_item(PyObject *dict, PyObject *key) { /* Objects all initialized to NULL for Py_XDECREF */ --- 436,441 ---- \begin{verbatim} ! int ! incr_item(PyObject *dict, PyObject *key) { /* Objects all initialized to NULL for Py_XDECREF */ From bwarsaw@users.sourceforge.net Thu Oct 25 16:58:31 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 08:58:31 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0273.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv6109 Added Files: pep-0273.txt Log Message: PEP 273, Import Modules from Zip Archives, James C. Ahlstrom --- NEW FILE: pep-0273.txt --- PEP: 273 Title: Import Modules from Zip Archives Version: $Revision: 1.1 $ Last-Modified: $Date: 2001/10/25 15:58:29 $ Author: jim@interet.com (James C. Ahlstrom) Status: Draft Type: Standards Track Created: 11-Oct-2001 Post-History: Python-Version: 2.3 Abstract This PEP adds the ability to import compiled Python modules *.py[co] and packages from zip archives. Specification Currently, sys.path is a list of directory names as strings. If this PEP is implemented, an item of sys.path can be a string naming a zip file archive. The zip archive can contain a subdirectory structure to support package imports. The zip archive satisfies imports exactly as a subdirectory would. The implementation is in C code in the Python core and works on all supported Python platforms. Any files may be present in the zip archive, but only files *.pyc, *.pyo and __init__.py[co] are available for import. Zip import of *.py and dynamic modules (*.pyd, *.so) is disallowed. Just as sys.path currently has default directory names, default zip archive names are added too. Otherwise there is no way to import all Python library files from an archive. Reading compressed zip archives requires the zlib module. An import of zlib will be attempted prior to any other imports. If zlib is not available at that time, only uncompressed archives will be readable, even if zlib subsequently becomes available. Subdirectory Equivalence The zip archive must be treated exactly as a subdirectory tree so we can support package imports based on current and future rules. Zip archive files must be created with relative path names. That is, archive file names are of the form: file1, file2, dir1/file3, dir2/dir3/file4. Suppose sys.path contains "/A/B/SubDir" and "/C/D/E/Archive.zip", and we are trying to import modfoo from the Q package. Then import.c will generate a list of paths and extensions and will look for the file. The list of generated paths does not change for zip imports. Suppose import.c generates the path "/A/B/SubDir/Q/R/modfoo.pyc". Then it will also generate the path "/C/D/E/Archive.zip/Q/R/modfoo.pyc". Finding the SubDir path is exactly equivalent to finding "Q/R/modfoo.pyc" in the archive. Suppose you zip up /A/B/SubDir/* and all its subdirectories. Then your zip file will satisfy imports just as your subdirectory did. Well, not quite. You can't satisfy dynamic modules from a zip file. Dynamic modules have extensions like .dll, .pyd, and .so. They are operating system dependent, and probably can't be loaded except from a file. It might be possible to extract the dynamic module from the zip file, write it to a plain file and load it. But that would mean creating temporary files, and dealing with all the dynload_*.c, and that's probably not a good idea. You also can't import source files *.py from a zip archive. The problem here is what to do with the compiled files. Python would normally write these to the same directory as *.py, but surely we don't want to write to the zip file. We could write to the directory of the zip archive, but that would clutter it up, not good if it is /usr/bin for example. We could just fail to write the compiled files, but that makes zip imports very slow, and the user would probably not figure out what is wrong. It is probably best for users to put *.pyc into zip archives in the first place, and this PEP enforces that rule. So the only imports zip archives support are *.pyc and *.pyo, plus the import of __init__.py[co] for packages, and the search of the subdirectory structure for the same. Efficiency The only way to find files in a zip archive is linear search. So for each zip file in sys.path, we search for its names once, and put the names plus other relevant data into a static Python dictionary. The key is the archive name from sys.path joined with the file name (including any subdirectories) within the archive. This is exactly the name generated by import.c, and makes lookup easy. zlib Compressed zip archives require zlib for decompression. Prior to any other imports, we attempt an import of zlib, and set a flag if it is available. All compressed files are invisible unless this flag is true. It could happen that zlib was available later. For example, the import of site.py might add the correct directory to sys.path so a dynamic load succeeds. But compressed files will still be invisible. It is unknown if it can happen that importing site.py can cause zlib to appear, so maybe we're worrying about nothing. On Windows and Linux, the early import of zlib succeeds without site.py. The problem here is the confusion caused by the reverse. Either a zip file satisfies imports or it doesn't. It is silly to say that site.py needs to be uncompressed, and that maybe imports will succeed later. If you don't like this, create uncompressed zip archives or make sure zlib is available, for example, as a built-in module. Or we can write special search logic during zip initialization. Booting Python imports site.py itself, and this imports os, nt, ntpath, stat, and UserDict. It also imports sitecustomize.py which may import more modules. Zip imports must be available before site.py is imported. Just as there are default directories in sys.path, there must be one or more default zip archives too. The problem is what the name should be. The name should be linked with the Python version, so the Python executable can correctly find its corresponding libraries even when there are multiple Python versions on the same machine. This PEP suggests a zip archive name equal to the Python interpreter path with extension ".zip" (eg, /usr/bin/python.zip) which is always prepended to sys.path. So a directory with python and python.zip is complete. This would work fine on Windows, as it is common to put supporting files in the directory of the executable. But it may offend Unix fans, who dislike bin directories being used for libraries. It might be fine to generate different defaults for Windows and Unix if necessary, but the code will be in C, and there is no sense getting complicated. Implementation A C implementation exists which works, but which can be made better. Copyright This document has been placed in the public domain. Local Variables: mode: indented-text indent-tabs-mode: nil fill-column: 70 End: From bwarsaw@users.sourceforge.net Thu Oct 25 17:03:00 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 09:03:00 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.137,1.138 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv7506 Modified Files: pep-0000.txt Log Message: Added PEP 273, Import Modules from Zip Archives, James C. Ahlstrom Also, did some reorganization of the PEP categories: - Under consideration for Python 2.2 -> ... for Python 2.3 - Py-in-the-sky -> Python 2.3 Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.137 retrieving revision 1.138 diff -C2 -d -r1.137 -r1.138 *** pep-0000.txt 2001/10/21 22:55:37 1.137 --- pep-0000.txt 2001/10/25 16:02:58 1.138 *************** *** 49,70 **** S 253 Subtyping Built-in Types van Rossum ! Open PEPs (under consideration for Python 2.2) I 42 Small Feature Requests Hylton - S 237 Unifying Long Integers and Integers Zadka, van Rossum - S 241 Metadata for Python Software Packages Kuchling - S 243 Module Repository Upload Mechanism Reifschneider - S 256 Docstring Processing System Framework Goodger - S 257 Docstring Conventions Goodger, van Rossum - S 258 DPS Generic Implementation Details Goodger - S 262 Database of Installed Python Packages Kuchling - S 263 Defining Python Source Code Encodings Lemburg - S 265 Sorting Dictionaries by Value Griffin - S 267 Optimized Access to Module Namespaces Hylton - S 269 Pgen Module for Python Riehl - S 270 uniq method for list objects Petrone - - Py-in-the-sky PEPs (not considered for Python 2.2) - I 206 2.0 Batteries Included Zadka S 209 Adding Multidimensional Arrays Barrett, Oliphant --- 49,55 ---- S 253 Subtyping Built-in Types van Rossum ! Open PEPs (under consideration for Python 2.3) I 42 Small Feature Requests Hylton I 206 2.0 Batteries Included Zadka S 209 Adding Multidimensional Arrays Barrett, Oliphant *************** *** 79,90 **** --- 64,88 ---- SD 225 Elementwise/Objectwise Operators Zhu, Lielens S 228 Reworking Python's Numeric Model Zadka, van Rossum + S 237 Unifying Long Integers and Integers Zadka, van Rossum S 239 Adding a Rational Type to Python Zadka S 240 Adding a Rational Literal to Python Zadka + S 241 Metadata for Python Software Packages Kuchling S 242 Numeric Kinds Dubois + S 243 Module Repository Upload Mechanism Reifschneider S 245 Python Interface Syntax Pelletier S 246 Object Adaptation Evans S 254 Making Classes Look More Like Types van Rossum + S 256 Docstring Processing System Framework Goodger + S 257 Docstring Conventions Goodger, van Rossum + S 258 DPS Generic Implementation Details Goodger + S 262 Database of Installed Python Packages Kuchling + S 263 Defining Python Source Code Encodings Lemburg + S 265 Sorting Dictionaries by Value Griffin S 266 Optimizing Global Variable/Attribute Access Montanaro + S 267 Optimized Access to Module Namespaces Hylton S 268 Extended HTTP functionality and WebDAV Stein + S 269 Pgen Module for Python Riehl + S 270 uniq method for list objects Petrone + I 273 Import Modules from Zip Archives Ahlstrom Finished PEPs (done, implemented in CVS) *************** *** 228,231 **** --- 226,230 ---- SR 271 Prefixing sys.path by command line option Giacometti I 272 API for Secret-Key Encryption Algorithms Kuchling + I 273 Import Modules from Zip Archives Ahlstrom *************** *** 244,247 **** --- 243,247 ---- name email address ---------------- ------------- + Ahlstrom, James C. jim@interet.com Aahz aahz@pobox.com Ascher, David davida@activestate.com From bwarsaw@users.sourceforge.net Thu Oct 25 17:04:40 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 09:04:40 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.138,1.139 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv7998 Modified Files: pep-0000.txt Log Message: Oops, PEP 273 is a Standards Track PEP Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.138 retrieving revision 1.139 diff -C2 -d -r1.138 -r1.139 *** pep-0000.txt 2001/10/25 16:02:58 1.138 --- pep-0000.txt 2001/10/25 16:04:38 1.139 *************** *** 84,88 **** S 269 Pgen Module for Python Riehl S 270 uniq method for list objects Petrone ! I 273 Import Modules from Zip Archives Ahlstrom Finished PEPs (done, implemented in CVS) --- 84,88 ---- S 269 Pgen Module for Python Riehl S 270 uniq method for list objects Petrone ! S 273 Import Modules from Zip Archives Ahlstrom Finished PEPs (done, implemented in CVS) *************** *** 226,230 **** SR 271 Prefixing sys.path by command line option Giacometti I 272 API for Secret-Key Encryption Algorithms Kuchling ! I 273 Import Modules from Zip Archives Ahlstrom --- 226,230 ---- SR 271 Prefixing sys.path by command line option Giacometti I 272 API for Secret-Key Encryption Algorithms Kuchling ! S 273 Import Modules from Zip Archives Ahlstrom From gvanrossum@users.sourceforge.net Thu Oct 25 19:07:24 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 25 Oct 2001 11:07:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects complexobject.c,2.50,2.51 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv8895 Modified Files: complexobject.c Log Message: complex_subtype_from_string(): move the declaration of s_buffer[] out of the if block where it was before. The name is only used inside that if block, but the storage is referenced outside it via the 's' variable. (This patch was part of SF patch #474590 -- RISC OS support.) Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.50 retrieving revision 2.51 diff -C2 -d -r2.50 -r2.51 *** complexobject.c 2001/10/05 20:51:38 2.50 --- complexobject.c 2001/10/25 18:07:22 2.51 *************** *** 647,650 **** --- 647,653 ---- int sign; char buffer[256]; /* For errors */ + #ifdef Py_USING_UNICODE + char s_buffer[256]; + #endif int len; *************** *** 655,659 **** #ifdef Py_USING_UNICODE else if (PyUnicode_Check(v)) { - char s_buffer[256]; if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) { PyErr_SetString(PyExc_ValueError, --- 658,661 ---- From fdrake@users.sourceforge.net Thu Oct 25 19:11:13 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 25 Oct 2001 11:11:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_sundry.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv9689 Modified Files: test_sundry.py Log Message: Ignore the posixfile deprecation warning for the test suite. Index: test_sundry.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sundry.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_sundry.py 2001/07/11 22:21:17 1.6 --- test_sundry.py 2001/10/25 18:11:10 1.7 *************** *** 1,4 **** --- 1,7 ---- """Do a minimal test of all the modules that aren't otherwise tested.""" + import warnings + warnings.filterwarnings('ignore', '', DeprecationWarning, 'posixfile') + from test_support import verbose From bwarsaw@users.sourceforge.net Thu Oct 25 21:14:03 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 13:14:03 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0234.txt,1.15,1.16 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv7249 Modified Files: pep-0234.txt Log Message: Moved all the Open Issues to Resolved Issues, with a brief explanation of how they were resolved. Mark this PEP as Final. Index: pep-0234.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0234.txt,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** pep-0234.txt 2001/05/05 00:14:56 1.15 --- pep-0234.txt 2001/10/25 20:14:01 1.16 *************** *** 3,7 **** Version: $Revision$ Author: ping@lfw.org (Ka-Ping Yee), guido@python.org (Guido van Rossum) ! Status: Draft Type: Standards Track Python-Version: 2.1 --- 3,7 ---- Version: $Revision$ Author: ping@lfw.org (Ka-Ping Yee), guido@python.org (Guido van Rossum) ! Status: Final Type: Standards Track Python-Version: 2.1 *************** *** 255,262 **** ! Open Issues ! The following questions are still open. - The name iter() is an abbreviation. Alternatives proposed include iterate(), traverse(), but these appear too long. --- 255,323 ---- ! Resolved Issues ! The following topics have been decided by consensus or BDFL ! pronouncement. ! ! - Two alternative spellings for next() have been proposed but ! rejected: __next__(), because it corresponds to a type object ! slot (tp_iternext); and __call__(), because this is the only ! operation. ! ! Arguments against __next__(): while many iterators are used in ! for loops, it is expected that user code will also call next() ! directly, so having to write __next__() is ugly; also, a ! possible extension of the protocol would be to allow for prev(), ! current() and reset() operations; surely we don't want to use ! __prev__(), __current__(), __reset__(). ! ! Arguments against __call__() (the original proposal): taken out ! of context, x() is not very readable, while x.next() is clear; ! there's a danger that every special-purpose object wants to use ! __call__() for its most common operation, causing more confusion ! than clarity. ! ! - Some folks have requested the ability to restart an iterator. ! This should be dealt with by calling iter() on a sequence ! repeatedly, not by the iterator protocol itself. ! ! - It has been questioned whether an exception to signal the end of ! the iteration isn't too expensive. Several alternatives for the ! StopIteration exception have been proposed: a special value End ! to signal the end, a function end() to test whether the iterator ! is finished, even reusing the IndexError exception. ! ! - A special value has the problem that if a sequence ever ! contains that special value, a loop over that sequence will ! end prematurely without any warning. If the experience with ! null-terminated C strings hasn't taught us the problems this ! can cause, imagine the trouble a Python introspection tool ! would have iterating over a list of all built-in names, ! assuming that the special End value was a built-in name! + - Calling an end() function would require two calls per + iteration. Two calls is much more expensive than one call + plus a test for an exception. Especially the time-critical + for loop can test very cheaply for an exception. + + - Reusing IndexError can cause confusion because it can be a + genuine error, which would be masked by ending the loop + prematurely. + + - Some have asked for a standard iterator type. Presumably all + iterators would have to be derived from this type. But this is + not the Python way: dictionaries are mappings because they + support __getitem__() and a handful other operations, not + because they are derived from an abstract mapping type. + + - Regarding "if key in dict": there is no doubt that the + dict.has_keys(x) interpretation of "x in dict" is by far the + most useful interpretation, probably the only useful one. There + has been resistance against this because "x in list" checks + whether x is present among the values, while the proposal makes + "x in dict" check whether x is present among the keys. Given + that the symmetry between lists and dictionaries is very weak, + this argument does not have much weight. + - The name iter() is an abbreviation. Alternatives proposed include iterate(), traverse(), but these appear too long. *************** *** 264,267 **** --- 325,330 ---- e.g. repr(), str(), len(). + Resolution: iter() it is. + - Using the same name for two different operations (getting an iterator from an object and making an iterator for a function *************** *** 270,273 **** --- 333,339 ---- return an iterator, it's easy to remember. + Resolution: the builtin iter() takes an optional argument, which + is the sentinel to look for. + - Once a particular iterator object has raised StopIteration, will it also raise StopIteration on all subsequent next() calls? *************** *** 277,280 **** --- 343,349 ---- iterator implementations (e.g. function-wrapping iterators). + Resolution: once StopIteration is raised, calling it.next() + continues to raise StopIteration. + - It has been proposed that a file object should be its own iterator, with a next() method returning the next line. This *************** *** 284,287 **** --- 353,358 ---- StopIteration" feature proposed in the previous bullet. + Resolution: this has been implemented. + - Some folks have requested extensions of the iterator protocol, e.g. prev() to get the previous item, current() to get the *************** *** 298,301 **** --- 369,374 ---- operations when the are implementable. + Resolution: rejected. + - There is still discussion about whether *************** *** 334,403 **** and found that the latter is only about 7% faster. - - - Resolved Issues - - The following topics have been decided by consensus or BDFL - pronouncement. - - - Two alternative spellings for next() have been proposed but - rejected: __next__(), because it corresponds to a type object - slot (tp_iternext); and __call__(), because this is the only - operation. - - Arguments against __next__(): while many iterators are used in - for loops, it is expected that user code will also call next() - directly, so having to write __next__() is ugly; also, a - possible extension of the protocol would be to allow for prev(), - current() and reset() operations; surely we don't want to use - __prev__(), __current__(), __reset__(). - - Arguments against __call__() (the original proposal): taken out - of context, x() is not very readable, while x.next() is clear; - there's a danger that every special-purpose object wants to use - __call__() for its most common operation, causing more confusion - than clarity. - - - Some folks have requested the ability to restart an iterator. - This should be dealt with by calling iter() on a sequence - repeatedly, not by the iterator protocol itself. - - - It has been questioned whether an exception to signal the end of - the iteration isn't too expensive. Several alternatives for the - StopIteration exception have been proposed: a special value End - to signal the end, a function end() to test whether the iterator - is finished, even reusing the IndexError exception. - - - A special value has the problem that if a sequence ever - contains that special value, a loop over that sequence will - end prematurely without any warning. If the experience with - null-terminated C strings hasn't taught us the problems this - can cause, imagine the trouble a Python introspection tool - would have iterating over a list of all built-in names, - assuming that the special End value was a built-in name! - - - Calling an end() function would require two calls per - iteration. Two calls is much more expensive than one call - plus a test for an exception. Especially the time-critical - for loop can test very cheaply for an exception. - - - Reusing IndexError can cause confusion because it can be a - genuine error, which would be masked by ending the loop - prematurely. ! - Some have asked for a standard iterator type. Presumably all ! iterators would have to be derived from this type. But this is ! not the Python way: dictionaries are mappings because they ! support __getitem__() and a handful other operations, not ! because they are derived from an abstract mapping type. ! ! - Regarding "if key in dict": there is no doubt that the ! dict.has_keys(x) interpretation of "x in dict" is by far the ! most useful interpretation, probably the only useful one. There ! has been resistance against this because "x in list" checks ! whether x is present among the values, while the proposal makes ! "x in dict" check whether x is present among the keys. Given ! that the symmetry between lists and dictionaries is very weak, ! this argument does not have much weight. --- 407,415 ---- and found that the latter is only about 7% faster. ! Resolution: By BDFL pronouncement, "for x in dict" iterates over ! the keys, and dictionaries have iteritems(), iterkeys(), and ! itervalues() to return the different flavors of dictionary ! iterators. From bwarsaw@users.sourceforge.net Thu Oct 25 21:14:34 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 13:14:34 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.139,1.140 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv7417 Modified Files: pep-0000.txt Log Message: Mark PEP 234 as Final. Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.139 retrieving revision 1.140 diff -C2 -d -r1.139 -r1.140 *** pep-0000.txt 2001/10/25 16:04:38 1.139 --- pep-0000.txt 2001/10/25 20:14:32 1.140 *************** *** 106,110 **** SF 230 Warning Framework van Rossum SF 232 Function Attributes Warsaw ! S 234 Iterators Yee, van Rossum SF 235 Import on Case-Insensitive Platforms Peters SF 236 Back to the __future__ Peters --- 106,110 ---- SF 230 Warning Framework van Rossum SF 232 Function Attributes Warsaw ! SF 234 Iterators Yee, van Rossum SF 235 Import on Case-Insensitive Platforms Peters SF 236 Back to the __future__ Peters *************** *** 187,191 **** SF 232 Function Attributes Warsaw SD 233 Python Online Help Prescod ! S 234 Iterators Yee, van Rossum SF 235 Import on Case-Insensitive Platforms Peters SF 236 Back to the __future__ Peters --- 187,191 ---- SF 232 Function Attributes Warsaw SD 233 Python Online Help Prescod ! SF 234 Iterators Yee, van Rossum SF 235 Import on Case-Insensitive Platforms Peters SF 236 Back to the __future__ Peters From gvanrossum@users.sourceforge.net Thu Oct 25 21:17:59 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 25 Oct 2001 13:17:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules selectmodule.c,2.57,2.58 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv8411 Modified Files: selectmodule.c Log Message: Fix SF bug #474538: Memory (reference) leak in poller.register (Dave Brueck) Replace some tortuous code that was trying to be clever but forgot to DECREF the key and value, by more longwinded but obviously correct code. (Inspired by but not copying the fix from SF patch #475033.) Index: selectmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/selectmodule.c,v retrieving revision 2.57 retrieving revision 2.58 diff -C2 -d -r2.57 -r2.58 *** selectmodule.c 2001/10/24 20:37:10 2.57 --- selectmodule.c 2001/10/25 20:17:57 2.58 *************** *** 367,370 **** --- 367,371 ---- PyObject *o, *key, *value; int fd, events = POLLIN | POLLPRI | POLLOUT; + int err; if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) { *************** *** 377,385 **** /* Add entry to the internal dictionary: the key is the file descriptor, and the value is the event mask. */ ! if ( (NULL == (key = PyInt_FromLong(fd))) || ! (NULL == (value = PyInt_FromLong(events))) || ! (PyDict_SetItem(self->dict, key, value)) == -1) { return NULL; } self->ufd_uptodate = 0; --- 378,395 ---- /* Add entry to the internal dictionary: the key is the file descriptor, and the value is the event mask. */ ! key = PyInt_FromLong(fd); ! if (key == NULL) ! return NULL; ! value = PyInt_FromLong(events); ! if (value == NULL) { ! Py_DECREF(key); return NULL; } + err = PyDict_SetItem(self->dict, key, value); + Py_DECREF(key); + Py_DECREF(value); + if (err < 0) + return NULL; + self->ufd_uptodate = 0; From gvanrossum@users.sourceforge.net Thu Oct 25 21:18:37 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 25 Oct 2001 13:18:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.130,1.131 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv8645 Modified Files: ACKS Log Message: Fix SF bug #474538: Memory (reference) leak in poller.register (Dave Brueck) Replace some tortuous code that was trying to be clever but forgot to DECREF the key and value, by more longwinded but obviously correct code. (Inspired by but not copying the fix from SF patch #475033.) Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.130 retrieving revision 1.131 diff -C2 -d -r1.130 -r1.131 *** ACKS 2001/10/23 21:25:24 1.130 --- ACKS 2001/10/25 20:18:35 1.131 *************** *** 55,58 **** --- 55,59 ---- Gary S. Brown Oleg Broytmann + Dave Brueck Stan Bubrouski Erik de Bueger From bwarsaw@users.sourceforge.net Thu Oct 25 21:28:07 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 13:28:07 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0274.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv11455 Added Files: pep-0274.txt Log Message: PEP 274, Dict Comprehensions, Warsaw --- NEW FILE: pep-0274.txt --- PEP: 274 Title: Dict Comprehensions Version: $Revision: 1.1 $ Last-Modified: $Date: 2001/10/25 20:28:05 $ Author: barry@zope.com (Barry A. Warsaw) Status: Draft Type: Standards Track Created: 25-Oct-2001 Python-Version: 2.3 Post-History: Abstract PEP 202 introduces a syntactical extension to Python called the "list comprehension"[1]. This PEP proposes a similar syntactical extension called the "dictionary comprehension" or "dict comprehension" for short. You can use dict comprehensions in ways very similar to list comprehensions, except that they produce Python dictionary objects instead of list objects. Proposed Solution Dict comprehensions are just like list comprehensions, except that you group the expression using curly braces instead of square braces. Also, the left part before the `for' keyword expresses both a key and a value, separated by a colon. (There is an optional part of this PEP that allows you to use a shortcut to express just the value.) The notation is specifically designed to remind you of list comprehensions as applied to dictionaries. Rationale There are times when you have some data arranged as a sequences of length-2 sequences, and you want to turn that into a dictionary. In Python 2.2, the dictionary() constructor will take an optional keyword argument that indicates specifically to interpret a sequences of length-2 sequences as key/value pairs, and turn them into a dictionary. However, the act of turning some data into a sequence of length-2 sequences can be inconvenient or inefficient from a memory or performance standpoint. Also, for some common operations, such as turning a list of things into a set of things for quick duplicate removal or set inclusion tests, a better syntax can help code clarity. As with list comprehensions, an explicit for loop can always be used (and in fact was the only way to do it in earlier versions of Python). But as with list comprehensions, dict comprehensions can provide a more syntactically succinct idiom that the traditional for loop. Examples >>> print {i : chr(65+i) for i in range(4)} {0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'} >>> print {k : v for k, v in someDict.items()} == someDict.copy() 1 >>> print {x.lower() : 1 for x in list_of_email_addrs} {'barry@zope.com' : 1, 'barry@python.org' : 1, 'guido@python.org' : 1} >>> def invert(d): ... return {v : k for k, v in d} ... >>> d = {0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'} >>> print invert(d) {'A' : 0, 'B' : 1, 'C' : 2, 'D' : 4} >>> print {k, v for k in range(4) for v in range(-4, 0, 1)} {0 : -4, 1 : -3, 2 : -2, 3 : -1} Optional Enhancements There is one further shortcut we could adopt. Suppose we wanted to create a set of items, such as in the "list_of_email_addrs" example above. Here, we're simply taking the target of the for loop and turning that into the key for the dict comprehension. The assertion is that this would be a common idiom, so the shortcut below allows for an easy spelling of it, by allow us to omit the "key :" part of the left hand clause: >>> print {1 for x in list_of_email_addrs} {'barry@zope.com' : 1, 'barry@python.org' : 1, 'guido@python.org' : 1} Or say we wanted to map email addresses to the MX record handling their mail: >>> print {mx_for_addr(x) for x in list_of_email_addrs} {'barry@zope.com' : 'mail.zope.com', 'barry@python.org' : 'mail.python.org, 'guido@python.org' : 'mail.python.org, } References [1] PEP 202, List Comprehensions http://www.python.org/peps/pep-0202.html Copyright This document has been placed in the public domain. Local Variables: mode: indented-text indent-tabs-mode: nil fill-column: 70 End: From bwarsaw@users.sourceforge.net Thu Oct 25 21:28:23 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 13:28:23 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.140,1.141 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv11540 Modified Files: pep-0000.txt Log Message: Added PEP 274, Dict Comprehensions, Warsaw Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.140 retrieving revision 1.141 diff -C2 -d -r1.140 -r1.141 *** pep-0000.txt 2001/10/25 20:14:32 1.140 --- pep-0000.txt 2001/10/25 20:28:19 1.141 *************** *** 85,88 **** --- 85,89 ---- S 270 uniq method for list objects Petrone S 273 Import Modules from Zip Archives Ahlstrom + S 274 Dict Comprehensions Warsaw Finished PEPs (done, implemented in CVS) *************** *** 227,230 **** --- 228,232 ---- I 272 API for Secret-Key Encryption Algorithms Kuchling S 273 Import Modules from Zip Archives Ahlstrom + S 274 Dict Comprehensions Warsaw From fdrake@users.sourceforge.net Thu Oct 25 21:42:59 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 25 Oct 2001 13:42:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib xmldom.tex,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv15175 Modified Files: xmldom.tex Log Message: Typo: NamedNodeList --> NamedNodeMap Index: xmldom.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/xmldom.tex,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** xmldom.tex 2001/10/20 04:24:09 1.15 --- xmldom.tex 2001/10/25 20:42:57 1.16 *************** *** 194,198 **** \begin{memberdesc}[Node]{attributes} ! A \class{NamedNodeList} of attribute objects. Only elements have actual values for this; others provide \code{None} for this attribute. This is a read-only attribute. --- 194,198 ---- \begin{memberdesc}[Node]{attributes} ! A \class{NamedNodeMap} of attribute objects. Only elements have actual values for this; others provide \code{None} for this attribute. This is a read-only attribute. From fdrake@users.sourceforge.net Thu Oct 25 21:43:26 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 25 Oct 2001 13:43:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib xmldom.tex,1.13,1.13.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv15298 Modified Files: Tag: release21-maint xmldom.tex Log Message: Typo: NamedNodeList --> NamedNodeMap Index: xmldom.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/xmldom.tex,v retrieving revision 1.13 retrieving revision 1.13.2.1 diff -C2 -d -r1.13 -r1.13.2.1 *** xmldom.tex 2001/04/05 18:30:04 1.13 --- xmldom.tex 2001/10/25 20:43:24 1.13.2.1 *************** *** 194,198 **** \begin{memberdesc}[Node]{attributes} ! A \class{NamedNodeList} of attribute objects. Only elements have actual values for this; others provide \code{None} for this attribute. This is a read-only attribute. --- 194,198 ---- \begin{memberdesc}[Node]{attributes} ! A \class{NamedNodeMap} of attribute objects. Only elements have actual values for this; others provide \code{None} for this attribute. This is a read-only attribute. From akuchling@users.sourceforge.net Thu Oct 25 21:58:19 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Thu, 25 Oct 2001 13:58:19 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0229.txt,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv18552 Modified Files: pep-0229.txt Log Message: Update PEP slightly to reflect what was checked in Index: pep-0229.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0229.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** pep-0229.txt 2001/01/17 03:45:35 1.3 --- pep-0229.txt 2001/10/25 20:58:17 1.4 *************** *** 50,53 **** --- 50,56 ---- Setup automatically. + The patch was checked in for Python 2.1, and has been subsequently + modified. + Implementation *************** *** 93,98 **** Do we need to make it possible to disable the 3 hard-wired modules ! without manually hacking the Makefiles? If yes, perhaps a ! configure switch is sufficient. The Distutils always compile modules as shared libraries. How do --- 96,100 ---- Do we need to make it possible to disable the 3 hard-wired modules ! without manually hacking the Makefiles? [Answer: No.] The Distutils always compile modules as shared libraries. How do From fdrake@users.sourceforge.net Thu Oct 25 22:39:01 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 25 Oct 2001 14:39:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python import.c,2.189,2.190 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv28405 Modified Files: import.c Log Message: Use PyDict_Copy() and PyDict_Update() instead of using PyObject_CallMethod() to call the corresponding methods. This is not a performance improvement since the times are still swamped by disk I/O, but cleans up the code just a little. Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.189 retrieving revision 2.190 diff -C2 -d -r2.189 -r2.190 *** import.c 2001/10/24 20:42:55 2.189 --- import.c 2001/10/25 21:38:59 2.190 *************** *** 393,397 **** if (dict == NULL) return NULL; ! copy = PyObject_CallMethod(dict, "copy", ""); if (copy == NULL) return NULL; --- 393,397 ---- if (dict == NULL) return NULL; ! copy = PyDict_Copy(dict); if (copy == NULL) return NULL; *************** *** 404,408 **** _PyImport_FindExtension(char *name, char *filename) { ! PyObject *dict, *mod, *mdict, *result; if (extensions == NULL) return NULL; --- 404,408 ---- _PyImport_FindExtension(char *name, char *filename) { ! PyObject *dict, *mod, *mdict; if (extensions == NULL) return NULL; *************** *** 416,423 **** if (mdict == NULL) return NULL; ! result = PyObject_CallMethod(mdict, "update", "O", dict); ! if (result == NULL) return NULL; - Py_DECREF(result); if (Py_VerboseFlag) PySys_WriteStderr("import %s # previously loaded (%s)\n", --- 416,421 ---- if (mdict == NULL) return NULL; ! if (PyDict_Update(mdict, dict)) return NULL; if (Py_VerboseFlag) PySys_WriteStderr("import %s # previously loaded (%s)\n", From akuchling@users.sourceforge.net Thu Oct 25 22:40:26 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Thu, 25 Oct 2001 14:40:26 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0229.txt,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv28683 Modified Files: pep-0229.txt Log Message: Removing one open item, and clarifying another. This PEP can now be marked as final. Index: pep-0229.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0229.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pep-0229.txt 2001/10/25 20:58:17 1.4 --- pep-0229.txt 2001/10/25 21:40:24 1.5 *************** *** 104,113 **** [Answer: building a Python binary with the Distutils should be feasible, though no one has implemented it yet. This should be ! done, though the main setup.py will probably need to implement ! its own BuildExt subclass anyway.] ! ! makesetup and the other contents of $(LIBPL)/config need to be ! preserved for compatibility with existing modules; for how many ! versions do we need to keep them around? --- 104,109 ---- [Answer: building a Python binary with the Distutils should be feasible, though no one has implemented it yet. This should be ! done someday, but isn't a pressing priority as messing around with ! the top-level Makefile.pre.in is good enough.] From bwarsaw@users.sourceforge.net Thu Oct 25 22:49:20 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 14:49:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_mimetypes.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv31010/Lib/test Modified Files: test_mimetypes.py Log Message: Applying proposed patch for bug #474583, optional support for non-standard but common types. Including Martin's suggestion to add rejected non-standard types from patch #438790. Specifically, guess_type(), guess_extension(): Both the functions and the methods grow an optional "strict" flag, defaulting to true, which determines whether to recognize non-standard, but commonly found types or not. Also, I sorted, reformatted, and culled duplicates from the big types_map dictionary. Note that there are a few non-equivalent duplicates (e.g. .cdf and .xls) for which the first will just get thrown away. I didn't remove those though. Finally, use of the module as a script as grown the -l and -e options to toggle strictness and to do guess_extension(), respectively. Doc and unittest updates too. Index: test_mimetypes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mimetypes.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_mimetypes.py 2001/09/20 21:33:42 1.2 --- test_mimetypes.py 2001/10/25 21:49:18 1.3 *************** *** 39,42 **** --- 39,54 ---- ".pyunit") + def test_non_standard_types(self): + # First try strict + self.assertEqual(self.db.guess_type('foo.xul', strict=1), + (None, None)) + self.assertEqual(self.db.guess_extension('image/jpg', strict=1), + None) + # And then non-strict + self.assertEqual(self.db.guess_type('foo.xul', strict=0), + ('text/xul', None)) + self.assertEqual(self.db.guess_extension('image/jpg', strict=0), + '.jpg') + def test_main(): From bwarsaw@users.sourceforge.net Thu Oct 25 22:49:20 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 14:49:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libmimetypes.tex,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv31010/Doc/lib Modified Files: libmimetypes.tex Log Message: Applying proposed patch for bug #474583, optional support for non-standard but common types. Including Martin's suggestion to add rejected non-standard types from patch #438790. Specifically, guess_type(), guess_extension(): Both the functions and the methods grow an optional "strict" flag, defaulting to true, which determines whether to recognize non-standard, but commonly found types or not. Also, I sorted, reformatted, and culled duplicates from the big types_map dictionary. Note that there are a few non-equivalent duplicates (e.g. .cdf and .xls) for which the first will just get thrown away. I didn't remove those though. Finally, use of the module as a script as grown the -l and -e options to toggle strictness and to do guess_extension(), respectively. Doc and unittest updates too. Index: libmimetypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libmimetypes.tex,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** libmimetypes.tex 2001/08/04 00:48:49 1.9 --- libmimetypes.tex 2001/10/25 21:49:18 1.10 *************** *** 9,16 **** \indexii{MIME}{content type} ! The \module{mimetypes} converts between a filename or URL and the MIME ! type associated with the filename extension. Conversions are provided ! from filename to MIME type and from MIME type to filename extension; ! encodings are not supported for the later conversion. The module provides one class and a number of convenience functions. --- 9,16 ---- \indexii{MIME}{content type} ! The \module{mimetypes} module converts between a filename or URL and ! the MIME type associated with the filename extension. Conversions are ! provided from filename to MIME type and from MIME type to filename ! extension; encodings are not supported for the latter conversion. The module provides one class and a number of convenience functions. *************** *** 24,43 **** ! \begin{funcdesc}{guess_type}{filename} Guess the type of a file based on its filename or URL, given by \var{filename}. The return value is a tuple \code{(\var{type}, \var{encoding})} where \var{type} is \code{None} if the type can't be ! guessed (no or unknown suffix) or a string of the form \code{'\var{type}/\var{subtype}'}, usable for a MIME ! \mailheader{content-type} header\indexii{MIME}{headers}; and encoding ! is \code{None} for no encoding or the name of the program used to ! encode (e.g. \program{compress} or \program{gzip}). The encoding is ! suitable for use as a \mailheader{Content-Encoding} header, \emph{not} ! as a \mailheader{Content-Transfer-Encoding} header. The mappings are ! table driven. Encoding suffixes are case sensitive; type suffixes are ! first tried case sensitive, then case insensitive. \end{funcdesc} ! \begin{funcdesc}{guess_extension}{type} Guess the extension for a file based on its MIME type, given by \var{type}. --- 24,52 ---- ! \begin{funcdesc}{guess_type}{filename\optional{, strict}} Guess the type of a file based on its filename or URL, given by \var{filename}. The return value is a tuple \code{(\var{type}, \var{encoding})} where \var{type} is \code{None} if the type can't be ! guessed (missing or unknown suffix) or a string of the form \code{'\var{type}/\var{subtype}'}, usable for a MIME ! \mailheader{content-type} header\indexii{MIME}{headers}. ! ! \var{encoding} is \code{None} for no encoding or the name of the ! program used to encode (e.g. \program{compress} or \program{gzip}). ! The encoding is suitable for use as a \mailheader{Content-Encoding} ! header, \emph{not} as a \mailheader{Content-Transfer-Encoding} header. ! The mappings are table driven. Encoding suffixes are case sensitive; ! type suffixes are first tried case sensitively, then case ! insensitively. ! ! Optional \var{strict} is a flag specifying whether the list of known ! MIME types is limited to only the official types \ulink{registered ! with IANA}{http://www.isi.edu/in-notes/iana/assignments/media-types} ! are recognized. When \var{strict} is true (the default), only the ! IANA types are supported; when \var{strict} is false, some additional ! non-standard but commonly used MIME types are also recognized. \end{funcdesc} ! \begin{funcdesc}{guess_extension}{type\optional{, strict}} Guess the extension for a file based on its MIME type, given by \var{type}. *************** *** 47,50 **** --- 56,62 ---- MIME type \var{type} by \function{guess_type()}. If no extension can be guessed for \var{type}, \code{None} is returned. + + Optional \var{strict} has the same meaning as with the + \function{guess_type()} function. \end{funcdesc} *************** *** 99,103 **** --- 111,120 ---- \end{datadesc} + \begin{datadesc}{common_types} + Dictionary mapping filename extensions to non-standard, but commonly + found MIME types. + \end{datadesc} + The \class{MimeTypes} class may be useful for applications which may want more than one MIME-type database: *************** *** 145,154 **** \end{datadesc} ! \begin{methoddesc}{guess_extension}{type} Similar to the \function{guess_extension()} function, using the tables stored as part of the object. \end{methoddesc} ! \begin{methoddesc}{guess_type}{url} Similar to the \function{guess_type()} function, using the tables stored as part of the object. --- 162,177 ---- \end{datadesc} ! \begin{datadesc}{common_types} ! Dictionary mapping filename extensions to non-standard, but commonly ! found MIME types. This is initially a copy of the global ! \code{common_types} defined in the module. ! \end{datadesc} ! ! \begin{methoddesc}{guess_extension}{type\optional{, strict}} Similar to the \function{guess_extension()} function, using the tables stored as part of the object. \end{methoddesc} ! \begin{methoddesc}{guess_type}{url\optional{, strict}} Similar to the \function{guess_type()} function, using the tables stored as part of the object. From bwarsaw@users.sourceforge.net Thu Oct 25 22:49:20 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 14:49:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib mimetypes.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv31010/Lib Modified Files: mimetypes.py Log Message: Applying proposed patch for bug #474583, optional support for non-standard but common types. Including Martin's suggestion to add rejected non-standard types from patch #438790. Specifically, guess_type(), guess_extension(): Both the functions and the methods grow an optional "strict" flag, defaulting to true, which determines whether to recognize non-standard, but commonly found types or not. Also, I sorted, reformatted, and culled duplicates from the big types_map dictionary. Note that there are a few non-equivalent duplicates (e.g. .cdf and .xls) for which the first will just get thrown away. I didn't remove those though. Finally, use of the module as a script as grown the -l and -e options to toggle strictness and to do guess_extension(), respectively. Doc and unittest updates too. Index: mimetypes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mimetypes.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** mimetypes.py 2001/09/07 16:49:12 1.19 --- mimetypes.py 2001/10/25 21:49:18 1.20 *************** *** 3,9 **** This module defines two useful functions: ! guess_type(url) -- guess the MIME type and encoding of a URL. ! guess_extension(type) -- guess the extension for a given MIME type. It also contains the following, for tuning the behavior: --- 3,9 ---- This module defines two useful functions: ! guess_type(url, strict=1) -- guess the MIME type and encoding of a URL. ! guess_extension(type, strict=1) -- guess the extension for a given MIME type. It also contains the following, for tuning the behavior: *************** *** 22,25 **** --- 22,35 ---- read_mime_types(file) -- parse one file, return a dictionary or None + When run as a script, the following command line options are recognized: + + Usage: mimetypes.py [options] type + Options: + --help / -h -- print this message and exit + --lenient / -l -- additionally search of some common, but non-standard + types. + --extension / -e -- guess extension instead of type + + More than one type argument may be given. """ *************** *** 54,61 **** self.suffix_map = suffix_map.copy() self.types_map = types_map.copy() for name in filenames: self.read(name) ! def guess_type(self, url): """Guess the type of a file based on its URL. --- 64,72 ---- self.suffix_map = suffix_map.copy() self.types_map = types_map.copy() + self.common_types = common_types.copy() for name in filenames: self.read(name) ! def guess_type(self, url, strict=1): """Guess the type of a file based on its URL. *************** *** 72,75 **** --- 83,89 ---- mapped to '.tar.gz'. (This is table-driven too, using the dictionary suffix_map.) + + Optional `strict' argument when false adds a bunch of commonly found, + but non-standard types. """ scheme, url = urllib.splittype(url) *************** *** 102,113 **** encoding = None types_map = self.types_map if types_map.has_key(ext): return types_map[ext], encoding elif types_map.has_key(ext.lower()): return types_map[ext.lower()], encoding else: return None, encoding ! def guess_extension(self, type): """Guess the extension for a file based on its MIME type. --- 116,134 ---- encoding = None types_map = self.types_map + common_types = self.common_types if types_map.has_key(ext): return types_map[ext], encoding elif types_map.has_key(ext.lower()): return types_map[ext.lower()], encoding + elif strict: + return None, encoding + elif common_types.has_key(ext): + return common_types[ext], encoding + elif common_types.has_key(ext.lower()): + return common_types[ext.lower()], encoding else: return None, encoding ! def guess_extension(self, type, strict=1): """Guess the extension for a file based on its MIME type. *************** *** 118,121 **** --- 139,145 ---- guess_type(). If no extension can be guessed for `type', None is returned. + + Optional `strict' argument when false adds a bunch of commonly found, + but non-standard types. """ type = type.lower() *************** *** 123,126 **** --- 147,154 ---- if type == stype: return ext + if not strict: + for ext, stype in common_types.items(): + if type == stype: + return ext return None *************** *** 150,154 **** ! def guess_type(url): """Guess the type of a file based on its URL. --- 178,182 ---- ! def guess_type(url, strict=1): """Guess the type of a file based on its URL. *************** *** 164,173 **** to ".tar.gz". (This is table-driven too, using the dictionary suffix_map). """ init() ! return guess_type(url) ! def guess_extension(type): """Guess the extension for a file based on its MIME type. --- 192,204 ---- to ".tar.gz". (This is table-driven too, using the dictionary suffix_map). + + Optional `strict' argument when false adds a bunch of commonly found, but + non-standard types. """ init() ! return guess_type(url, strict) ! def guess_extension(type, strict=1): """Guess the extension for a file based on its MIME type. *************** *** 177,188 **** MIME type `type' by guess_type(). If no extension can be guessed for `type', None is returned. """ init() ! return guess_extension(type) def init(files=None): global guess_extension, guess_type ! global suffix_map, types_map, encodings_map global inited inited = 1 --- 208,222 ---- MIME type `type' by guess_type(). If no extension can be guessed for `type', None is returned. + + Optional `strict' argument when false adds a bunch of commonly found, + but non-standard types. """ init() ! return guess_extension(type, strict) def init(files=None): global guess_extension, guess_type ! global suffix_map, types_map, encodings_map, common_types global inited inited = 1 *************** *** 198,201 **** --- 232,236 ---- guess_extension = db.guess_extension guess_type = db.guess_type + common_types = db.common_types *************** *** 224,355 **** # http://www.isi.edu/in-notes/iana/assignments/media-types # or extensions, i.e. using the x- prefix types_map = { ! '.a': 'application/octet-stream', ! '.ai': 'application/postscript', ! '.aif': 'audio/x-aiff', ! '.aifc': 'audio/x-aiff', ! '.aiff': 'audio/x-aiff', ! '.au': 'audio/basic', ! '.avi': 'video/x-msvideo', ! '.bcpio': 'application/x-bcpio', ! '.bin': 'application/octet-stream', ! '.bmp': 'image/x-ms-bmp', ! '.cdf': 'application/x-netcdf', ! '.cpio': 'application/x-cpio', ! '.csh': 'application/x-csh', ! '.css': 'text/css', ! '.dll': 'application/octet-stream', ! '.doc': 'application/msword', ! '.dvi': 'application/x-dvi', ! '.exe': 'application/octet-stream', ! '.eps': 'application/postscript', ! '.etx': 'text/x-setext', ! '.gif': 'image/gif', ! '.gtar': 'application/x-gtar', ! '.hdf': 'application/x-hdf', ! '.htm': 'text/html', ! '.html': 'text/html', ! '.ief': 'image/ief', ! '.jpe': 'image/jpeg', ! '.jpeg': 'image/jpeg', ! '.jpg': 'image/jpeg', ! '.js': 'application/x-javascript', ! '.latex': 'application/x-latex', ! '.man': 'application/x-troff-man', ! '.me': 'application/x-troff-me', ! '.mif': 'application/x-mif', ! '.mov': 'video/quicktime', ! '.movie': 'video/x-sgi-movie', ! '.mp2': 'audio/mpeg', ! '.mp3': 'audio/mpeg', ! '.mpe': 'video/mpeg', ! '.mpeg': 'video/mpeg', ! '.mpg': 'video/mpeg', ! '.ms': 'application/x-troff-ms', ! '.nc': 'application/x-netcdf', ! '.o': 'application/octet-stream', ! '.obj': 'application/octet-stream', ! '.oda': 'application/oda', ! '.pbm': 'image/x-portable-bitmap', ! '.pdf': 'application/pdf', ! '.pgm': 'image/x-portable-graymap', ! '.pnm': 'image/x-portable-anymap', ! '.png': 'image/png', ! '.ppm': 'image/x-portable-pixmap', ! '.ps': 'application/postscript', ! '.py': 'text/x-python', ! '.pyc': 'application/x-python-code', ! '.pyo': 'application/x-python-code', ! '.qt': 'video/quicktime', ! '.ras': 'image/x-cmu-raster', ! '.rgb': 'image/x-rgb', ! '.rdf': 'application/xml', ! '.roff': 'application/x-troff', ! '.rtx': 'text/richtext', ! '.sgm': 'text/x-sgml', ! '.sgml': 'text/x-sgml', ! '.sh': 'application/x-sh', ! '.shar': 'application/x-shar', ! '.snd': 'audio/basic', ! '.so': 'application/octet-stream', ! '.src': 'application/x-wais-source', '.sv4cpio': 'application/x-sv4cpio', ! '.sv4crc': 'application/x-sv4crc', ! '.t': 'application/x-troff', ! '.tar': 'application/x-tar', ! '.tcl': 'application/x-tcl', ! '.tex': 'application/x-tex', ! '.texi': 'application/x-texinfo', '.texinfo': 'application/x-texinfo', ! '.tif': 'image/tiff', ! '.tiff': 'image/tiff', ! '.tr': 'application/x-troff', ! '.tsv': 'text/tab-separated-values', ! '.txt': 'text/plain', ! '.ustar': 'application/x-ustar', ! '.wav': 'audio/x-wav', ! '.xbm': 'image/x-xbitmap', ! '.xls': 'application/excel', ! '.xml': 'text/xml', ! '.xsl': 'application/xml', ! '.xpm': 'image/x-xpixmap', ! '.xwd': 'image/x-xwindowdump', ! '.zip': 'application/zip', ! '.mp3': 'audio/mpeg', ! '.ra': 'audio/x-pn-realaudio', ! '.pdf': 'application/pdf', ! '.c': 'text/plain', ! '.bat': 'text/plain', ! '.h': 'text/plain', ! '.pl': 'text/plain', ! '.ksh': 'text/plain', ! '.ram': 'application/x-pn-realaudio', ! '.cdf': 'application/x-cdf', ! '.doc': 'application/msword', ! '.dot': 'application/msword', ! '.wiz': 'application/msword', ! '.xlb': 'application/vnd.ms-excel', ! '.xls': 'application/vnd.ms-excel', ! '.ppa': 'application/vnd.ms-powerpoint', ! '.ppt': 'application/vnd.ms-powerpoint', ! '.pps': 'application/vnd.ms-powerpoint', ! '.pot': 'application/vnd.ms-powerpoint', ! '.pwz': 'application/vnd.ms-powerpoint', ! '.eml': 'message/rfc822', ! '.nws': 'message/rfc822', ! '.mht': 'message/rfc822', ! '.mhtml': 'message/rfc822', ! '.css': 'text/css', ! '.p7c': 'application/pkcs7-mime', ! '.p12': 'application/x-pkcs12', ! '.pfx': 'application/x-pkcs12', ! '.js': 'application/x-javascript', ! '.m1v': 'video/mpeg', ! '.mpa': 'video/mpeg', ! '.vcf': 'text/x-vcard', ! '.xml': 'text/xml', } if __name__ == '__main__': import sys ! print guess_type(sys.argv[1]) --- 259,435 ---- # http://www.isi.edu/in-notes/iana/assignments/media-types # or extensions, i.e. using the x- prefix + + # If you add to these, please keep them sorted! types_map = { ! '.a' : 'application/octet-stream', ! '.ai' : 'application/postscript', ! '.aif' : 'audio/x-aiff', ! '.aifc' : 'audio/x-aiff', ! '.aiff' : 'audio/x-aiff', ! '.au' : 'audio/basic', ! '.avi' : 'video/x-msvideo', ! '.bat' : 'text/plain', ! '.bcpio' : 'application/x-bcpio', ! '.bin' : 'application/octet-stream', ! '.bmp' : 'image/x-ms-bmp', ! '.c' : 'text/plain', ! # Duplicates :( ! '.cdf' : 'application/x-cdf', ! '.cdf' : 'application/x-netcdf', ! '.cpio' : 'application/x-cpio', ! '.csh' : 'application/x-csh', ! '.css' : 'text/css', ! '.dll' : 'application/octet-stream', ! '.doc' : 'application/msword', ! '.dot' : 'application/msword', ! '.dvi' : 'application/x-dvi', ! '.eml' : 'message/rfc822', ! '.eps' : 'application/postscript', ! '.etx' : 'text/x-setext', ! '.exe' : 'application/octet-stream', ! '.gif' : 'image/gif', ! '.gtar' : 'application/x-gtar', ! '.h' : 'text/plain', ! '.hdf' : 'application/x-hdf', ! '.htm' : 'text/html', ! '.html' : 'text/html', ! '.ief' : 'image/ief', ! '.jpe' : 'image/jpeg', ! '.jpeg' : 'image/jpeg', ! '.jpg' : 'image/jpeg', ! '.js' : 'application/x-javascript', ! '.ksh' : 'text/plain', ! '.latex' : 'application/x-latex', ! '.m1v' : 'video/mpeg', ! '.man' : 'application/x-troff-man', ! '.me' : 'application/x-troff-me', ! '.mht' : 'message/rfc822', ! '.mhtml' : 'message/rfc822', ! '.mif' : 'application/x-mif', ! '.mov' : 'video/quicktime', ! '.movie' : 'video/x-sgi-movie', ! '.mp2' : 'audio/mpeg', ! '.mp3' : 'audio/mpeg', ! '.mpa' : 'video/mpeg', ! '.mpe' : 'video/mpeg', ! '.mpeg' : 'video/mpeg', ! '.mpg' : 'video/mpeg', ! '.ms' : 'application/x-troff-ms', ! '.nc' : 'application/x-netcdf', ! '.nws' : 'message/rfc822', ! '.o' : 'application/octet-stream', ! '.obj' : 'application/octet-stream', ! '.oda' : 'application/oda', ! '.p12' : 'application/x-pkcs12', ! '.p7c' : 'application/pkcs7-mime', ! '.pbm' : 'image/x-portable-bitmap', ! '.pdf' : 'application/pdf', ! '.pfx' : 'application/x-pkcs12', ! '.pgm' : 'image/x-portable-graymap', ! '.pl' : 'text/plain', ! '.png' : 'image/png', ! '.pnm' : 'image/x-portable-anymap', ! '.pot' : 'application/vnd.ms-powerpoint', ! '.ppa' : 'application/vnd.ms-powerpoint', ! '.ppm' : 'image/x-portable-pixmap', ! '.pps' : 'application/vnd.ms-powerpoint', ! '.ppt' : 'application/vnd.ms-powerpoint', ! '.ps' : 'application/postscript', ! '.pwz' : 'application/vnd.ms-powerpoint', ! '.py' : 'text/x-python', ! '.pyc' : 'application/x-python-code', ! '.pyo' : 'application/x-python-code', ! '.qt' : 'video/quicktime', ! '.ra' : 'audio/x-pn-realaudio', ! '.ram' : 'application/x-pn-realaudio', ! '.ras' : 'image/x-cmu-raster', ! '.rdf' : 'application/xml', ! '.rgb' : 'image/x-rgb', ! '.roff' : 'application/x-troff', ! '.rtx' : 'text/richtext', ! '.sgm' : 'text/x-sgml', ! '.sgml' : 'text/x-sgml', ! '.sh' : 'application/x-sh', ! '.shar' : 'application/x-shar', ! '.snd' : 'audio/basic', ! '.so' : 'application/octet-stream', ! '.src' : 'application/x-wais-source', '.sv4cpio': 'application/x-sv4cpio', ! '.sv4crc' : 'application/x-sv4crc', ! '.t' : 'application/x-troff', ! '.tar' : 'application/x-tar', ! '.tcl' : 'application/x-tcl', ! '.tex' : 'application/x-tex', ! '.texi' : 'application/x-texinfo', '.texinfo': 'application/x-texinfo', ! '.tif' : 'image/tiff', ! '.tiff' : 'image/tiff', ! '.tr' : 'application/x-troff', ! '.tsv' : 'text/tab-separated-values', ! '.txt' : 'text/plain', ! '.ustar' : 'application/x-ustar', ! '.vcf' : 'text/x-vcard', ! '.wav' : 'audio/x-wav', ! '.wiz' : 'application/msword', ! '.xbm' : 'image/x-xbitmap', ! '.xlb' : 'application/vnd.ms-excel', ! # Duplicates :( ! '.xls' : 'application/excel', ! '.xls' : 'application/vnd.ms-excel', ! '.xml' : 'text/xml', ! '.xpm' : 'image/x-xpixmap', ! '.xsl' : 'application/xml', ! '.xwd' : 'image/x-xwindowdump', ! '.zip' : 'application/zip', ! } ! ! # These are non-standard types, commonly found in the wild. They will only ! # match if strict=0 flag is given to the API methods. ! ! # Please sort these too ! common_types = { ! '.jpg' : 'image/jpg', ! '.mid' : 'audio/midi', ! '.midi': 'audio/midi', ! '.pct' : 'image/pict', ! '.pic' : 'image/pict', ! '.pict': 'image/pict', ! '.rtf' : 'application/rtf', ! '.xul' : 'text/xul' } + + def usage(code, msg=''): + print __doc__ + if msg: print msg + sys.exit(code) + + if __name__ == '__main__': import sys ! import getopt ! ! try: ! opts, args = getopt.getopt(sys.argv[1:], 'hle', ! ['help', 'lenient', 'extension']) ! except getopt.error, msg: ! usage(1, msg) ! ! strict = 1 ! extension = 0 ! for opt, arg in opts: ! if opt in ('-h', '--help'): ! usage(0) ! elif opt in ('-l', '--lenient'): ! strict = 0 ! elif opt in ('-e', '--extension'): ! extension = 1 ! for gtype in args: ! if extension: ! guess = guess_extension(gtype, strict) ! if not guess: print "I don't know anything about type", gtype ! else: print guess ! else: ! guess, encoding = guess_type(gtype, strict) ! if not guess: print "I don't know anything about type", gtype ! else: print 'type:', guess, 'encoding:', encoding From bwarsaw@users.sourceforge.net Thu Oct 25 22:53:33 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 14:53:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.298,1.299 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv31985/Misc Modified Files: NEWS Log Message: I went back and figured out the release date for Python 2.2a1. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.298 retrieving revision 1.299 diff -C2 -d -r1.298 -r1.299 *** NEWS 2001/10/24 20:51:44 1.298 --- NEWS 2001/10/25 21:53:30 1.299 *************** *** 776,779 **** --- 776,780 ---- What's New in Python 2.2a1? + Release date: 18-Jul-2001 =========================== From bwarsaw@users.sourceforge.net Thu Oct 25 23:03:20 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 15:03:20 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.141,1.142 pep-0229.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv2426 Modified Files: pep-0000.txt pep-0229.txt Log Message: Mark PEP 229 as Final. Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.141 retrieving revision 1.142 diff -C2 -d -r1.141 -r1.142 *** pep-0000.txt 2001/10/25 20:28:19 1.141 --- pep-0000.txt 2001/10/25 22:03:18 1.142 *************** *** 104,108 **** I 226 Python 2.1 Release Schedule Hylton S 227 Statically Nested Scopes Hylton ! S 229 Using Distutils to Build Python Kuchling SF 230 Warning Framework van Rossum SF 232 Function Attributes Warsaw --- 104,108 ---- I 226 Python 2.1 Release Schedule Hylton S 227 Statically Nested Scopes Hylton ! SF 229 Using Distutils to Build Python Kuchling SF 230 Warning Framework van Rossum SF 232 Function Attributes Warsaw *************** *** 183,187 **** S 227 Statically Nested Scopes Hylton S 228 Reworking Python's Numeric Model Zadka, van Rossum ! S 229 Using Distutils to Build Python Kuchling S 230 Warning Framework van Rossum SR 231 __findattr__() Warsaw --- 183,187 ---- S 227 Statically Nested Scopes Hylton S 228 Reworking Python's Numeric Model Zadka, van Rossum ! SF 229 Using Distutils to Build Python Kuchling S 230 Warning Framework van Rossum SR 231 __findattr__() Warsaw Index: pep-0229.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0229.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pep-0229.txt 2001/10/25 21:40:24 1.5 --- pep-0229.txt 2001/10/25 22:03:18 1.6 *************** *** 3,7 **** Version: $Revision$ Author: akuchlin@mems-exchange.org (A.M. Kuchling) ! Status: Draft Type: Standards Created: 16-Nov-2000 --- 3,7 ---- Version: $Revision$ Author: akuchlin@mems-exchange.org (A.M. Kuchling) ! Status: Final Type: Standards Created: 16-Nov-2000 From jackjansen@users.sourceforge.net Thu Oct 25 23:26:03 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Thu, 25 Oct 2001 15:26:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Distributions readme.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions In directory usw-pr-cvs1:/tmp/cvs-serv7770/Python/Mac/Distributions Modified Files: readme.txt Log Message: Added various tidbits. Index: readme.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/readme.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** readme.txt 2001/06/26 08:06:59 1.5 --- readme.txt 2001/10/25 22:26:00 1.6 *************** *** 3,7 **** These notes are mainly for myself, or for whoever tries to make a MacPython ! distribution when I'm fed up with it. They were last updated for 2.1b2. - Increase fragment version number in PythonCore and PythonCoreCarbon. --- 3,7 ---- These notes are mainly for myself, or for whoever tries to make a MacPython ! distribution when I'm fed up with it. They were last updated for 2.2b1. - Increase fragment version number in PythonCore and PythonCoreCarbon. *************** *** 13,18 **** - Make sure tkresources.rsrc is up-to-date - fullbuild everything with increase-buildno - Update Numeric and build/install it both with Classic and with Carbon python - - Run configurepython - Recompile OSAm and possibly other Contrib stuff - mkdistr binary.include --- 13,18 ---- - Make sure tkresources.rsrc is up-to-date - fullbuild everything with increase-buildno + - Test both classic and Carbon with test.regrtest - Update Numeric and build/install it both with Classic and with Carbon python - Recompile OSAm and possibly other Contrib stuff - mkdistr binary.include *************** *** 20,23 **** --- 20,24 ---- - make distribution archive with Installer Vise Things to make sure of: + - Version number in toplevel folder name - Finder icon positions - Version numbers in "Packages..." window *************** *** 27,32 **** --- 28,43 ---- - Version number in "Internet" -> "Download Sites" - Version number in "Internet" -> "File Groups". + - Check for missing files. Do this by installing everything on your local system, + and comparing the file tree (CodeWarrior Compare is great for this) with + :Mac:Distributions:(vise):binary distribution and ....:dev distribution. + Only the :Lib:plat-xxxx should be missing. Otherwise go back to Installer Vise and + add the missing stuff. Make sure of all settings for the new files (esp. "where" + and "gestalt" are easy to miss). - test on virgin systems (OSX, OS9, OS8 without Carbon). Make sure to test tkinter too. + - Remove the local installation so you don't get confused by it. + - checkin everything except PythonX.Y.vct. + - mkdistr src.include + - Rename "src distribution" and stuffit - Upload - Update README file in ftp directory *************** *** 36,39 **** --- 47,51 ---- pythonmac-sig@python.org python-dev@python.org + - Wait a day or so for catastrophic mistakes, then send an announcement to: python-announce@python.org archivist@info-mac.org *************** *** 41,43 **** http://www.macupdate.com http://guide.apple.com/usindex.html ! http://www.versiontracker.com/ Jack.Jansen@oratrix.com \ No newline at end of file --- 53,58 ---- http://www.macupdate.com http://guide.apple.com/usindex.html ! http://www.versiontracker.com/ (userid Jack.Jansen@oratrix.com) ! - Open PythonX.Y.vct again, use the "remove compressed files" command to trim down ! the size, commit. ! - Remove the subdires under (vise) so you don't get confused by them later. \ No newline at end of file From bwarsaw@users.sourceforge.net Thu Oct 25 23:43:48 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 15:43:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email Message.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv11655/Lib/email Modified Files: Message.py Log Message: A fix for SF bug #472560, extra newlines returned by get_param() when the separating semi-colon shows up on a continuation line (legal, but weird). Bug reported and fixed by Matthew Cowles. Test case and sample email included. Index: Message.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Message.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Message.py 2001/10/09 15:48:29 1.5 --- Message.py 2001/10/25 22:43:45 1.6 *************** *** 18,22 **** SEMISPACE = '; ' ! paramre = re.compile(r';\s*') --- 18,22 ---- SEMISPACE = '; ' ! paramre = re.compile(r'\s*;\s*') From bwarsaw@users.sourceforge.net Thu Oct 25 23:43:48 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 15:43:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_email.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv11655/Lib/test Modified Files: test_email.py Log Message: A fix for SF bug #472560, extra newlines returned by get_param() when the separating semi-colon shows up on a continuation line (legal, but weird). Bug reported and fixed by Matthew Cowles. Test case and sample email included. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_email.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** test_email.py 2001/10/19 04:08:59 1.13 --- test_email.py 2001/10/25 22:43:45 1.14 *************** *** 219,222 **** --- 219,226 ---- eq(msg.get_param('baz', header='x-header'), 'two') + def test_get_param_funky_continuation_lines(self): + msg = self._msgobj('msg_22.txt') + self.assertEqual(msg.get_payload(1).get_param('name'), 'wibble.JPG') + def test_has_key(self): msg = email.message_from_string('Header: exists') From bwarsaw@users.sourceforge.net Thu Oct 25 23:43:48 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 25 Oct 2001 15:43:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/data msg_22.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/data In directory usw-pr-cvs1:/tmp/cvs-serv11655/Lib/test/data Added Files: msg_22.txt Log Message: A fix for SF bug #472560, extra newlines returned by get_param() when the separating semi-colon shows up on a continuation line (legal, but weird). Bug reported and fixed by Matthew Cowles. Test case and sample email included. --- NEW FILE: msg_22.txt --- Mime-Version: 1.0 Message-Id: Date: Tue, 16 Oct 2001 13:59:25 +0300 To: a@example.com From: b@example.com Content-Type: multipart/mixed; boundary="============_-1208892523==_============" --============_-1208892523==_============ Content-Type: text/plain; charset="us-ascii" ; format="flowed" Text text text. --============_-1208892523==_============ Content-Id: Content-Type: image/jpeg; name="wibble.JPG" ; x-mac-type="4A504547" ; x-mac-creator="474B4F4E" Content-Disposition: attachment; filename="wibble.JPG" Content-Transfer-Encoding: base64 /9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAALCAXABIEBAREA g6bCjjw/pIZSjO6FWFpldjySOmCNrO7DBZibUXhTwtCixw+GtAijVdqxxaPp0aKvmGXa qrbBQvms0mAMeYS/3iTV1dG0hHaRNK01XblnWxtVdjkHLMIgTyqnk9VB7CrP2KzIINpa 4O7I+zxYO9WV8jZg71Zlb+8rMDkEirAVQFAUAKAFAAAUAYAUDgADgY6DjpRtXj5RxjHA 4wQRj0wQCMdCAewpaKKK/9k= --============_-1208892523==_============ Content-Id: Content-Type: image/jpeg; name="wibble2.JPG" ; x-mac-type="4A504547" ; x-mac-creator="474B4F4E" Content-Disposition: attachment; filename="wibble2.JPG" Content-Transfer-Encoding: base64 /9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAALCAXABJ0BAREA /8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA W6NFJJBEkU10kKGTcWMDwxuU+0JHvk8qAtOpNwqSR0n8c3BlDyXHlqsUltHEiTvdXLxR 7vMiGDNJAJWkAMk8ZkCFp5G2oo5W++INrbQtNfTQxJAuXlupz9oS4d5Y1W+E2XlWZJJE Y7LWYQxTLE1zuMbfBPxw8X2fibVdIbSbI6nLZxX635t9TjtYreWR7WGKJTLJFFKSlozO 0ShxIXM43uC3/9k= --============_-1208892523==_============ Content-Type: text/plain; charset="us-ascii" ; format="flowed" Text text text. --============_-1208892523==_============-- From fdrake@users.sourceforge.net Fri Oct 26 04:00:41 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 25 Oct 2001 20:00:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libweakref.tex,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv25849/lib Modified Files: libweakref.tex Log Message: Minor textual adjustment, and style-guide conformance (no use of "iff"). Index: libweakref.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libweakref.tex,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** libweakref.tex 2001/10/06 06:10:54 1.12 --- libweakref.tex 2001/10/26 03:00:39 1.13 *************** *** 48,55 **** \exception{TypeError}. ! Weak references support test for equality, but not ordering. If the ! \var{object} is still alive, to references are equal if the objects ! are equal (regardless of the \var{callback}). If the \var{object} ! has been deleted, they are equal iff they are identical. \end{funcdesc} --- 48,56 ---- \exception{TypeError}. ! Weak references support tests for equality, but not ordering. If ! the \var{object} is still alive, two references are equal if the ! objects are equal (regardless of the \var{callback}). If ! \var{object} has been deleted, they are equal only if the references ! being compared are the same reference object. \end{funcdesc} From fdrake@users.sourceforge.net Fri Oct 26 04:04:25 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 25 Oct 2001 20:04:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libdifflib.tex,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv26523/lib Modified Files: libdifflib.tex Log Message: Enforce a bit of markup consistency. When describing a Boolean return value, use "true" and "false" instead of "1" and "0". Style-guide conformance: no "iff" -- to obscure for many readers. ;-( Index: libdifflib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdifflib.tex,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** libdifflib.tex 2001/09/22 21:30:22 1.9 --- libdifflib.tex 2001/10/26 03:04:23 1.10 *************** *** 147,165 **** ! \begin{funcdesc}{IS_LINE_JUNK}{line}: ! ! Return 1 for ignorable line: iff \var{line} is blank or contains a ! single \character{\#}. Used as a default for parameter \var{linejunk} in \function{ndiff()}. - \end{funcdesc} - - \begin{funcdesc}{IS_CHARACTER_JUNK}{ch}: ! Return 1 for ignorable character: iff \var{ch} is a space or tab. ! Used as a default for parameter \var{charjunk} in \function{ndiff()}. - \end{funcdesc} --- 147,163 ---- ! \begin{funcdesc}{IS_LINE_JUNK}{line} ! Return true for ignorable lines. The line \var{line} is ignorable ! if \var{line} is blank or contains a single \character{\#}, ! otherwise it is not ignorable. Used as a default for parameter \var{linejunk} in \function{ndiff()}. \end{funcdesc} ! \begin{funcdesc}{IS_CHARACTER_JUNK}{ch} ! Return true for ignorable characters. The character \var{ch} is ! ignorable if \var{ch} is a space or tab, otherwise it is not ! ignorable. Used as a default for parameter \var{charjunk} in \function{ndiff()}. \end{funcdesc} *************** *** 183,188 **** a one-argument function that takes a sequence element and returns true if and only if the element is ``junk'' and should be ignored. ! \code{None} is equivalent to passing \code{lambda x: 0}, i.e.\ no ! elements are ignored. For example, pass \begin{verbatim} --- 181,187 ---- a one-argument function that takes a sequence element and returns true if and only if the element is ``junk'' and should be ignored. ! Passing \code{None} for \var{b} is equivalent to passing ! \code{lambda x: 0}; in other words, no elements are ignored. For ! example, pass: \begin{verbatim} *************** *** 446,450 **** \var{linejunk}: A function that should accept a single string ! argument, and return true iff the string is junk. The default is module-level function \function{IS_LINE_JUNK()}, which filters out lines without visible characters, except for at most one pound --- 445,449 ---- \var{linejunk}: A function that should accept a single string ! argument, and return true if the string is junk. The default is module-level function \function{IS_LINE_JUNK()}, which filters out lines without visible characters, except for at most one pound From fdrake@users.sourceforge.net Fri Oct 26 04:09:29 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 25 Oct 2001 20:09:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/perl python.perl,1.111,1.112 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory usw-pr-cvs1:/tmp/cvs-serv27440/perl Modified Files: python.perl Log Message: Add yet more markup that let's a stylesheet pick out a small bit of the presentation. This is acceptable since it only occurs in the formatted output and does not affect the document markup. Index: python.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/python.perl,v retrieving revision 1.111 retrieving revision 1.112 diff -C2 -d -r1.111 -r1.112 *** python.perl 2001/10/09 18:01:23 1.111 --- python.perl 2001/10/26 03:09:27 1.112 *************** *** 869,872 **** --- 869,876 ---- } + + $TLSTART = ''; + $TLEND = ''; + sub do_env_cfuncdesc{ local($_) = @_; *************** *** 1048,1052 **** my $excname = next_argument(); my $idx = make_str_index_entry("$excname"); ! return "

    exception $idx\n
    " . $_ . '
    ' } --- 1052,1059 ---- my $excname = next_argument(); my $idx = make_str_index_entry("$excname"); ! return ("
    ${TLSTART}exception$TLEND $idx" ! . "\n
    " ! . $_ ! . '
    '); } *************** *** 1061,1065 **** "$THIS_CLASS ($what in $THIS_MODULE)" ); $idx =~ s/ \(.*\)//; ! return ("
    $what $idx($arg_list)\n
    " . $_ . '
    '); --- 1068,1073 ---- "$THIS_CLASS ($what in $THIS_MODULE)" ); $idx =~ s/ \(.*\)//; ! return ("
    $TLSTART$what$TLEND $idx" ! . "($arg_list)\n
    " . $_ . '
    '); *************** *** 1076,1080 **** "$THIS_CLASS (class in $THIS_MODULE)"); $idx =~ s/ \(.*\)//; ! return ("
    class $idx\n
    " . $_ . '
    '); --- 1084,1088 ---- "$THIS_CLASS (class in $THIS_MODULE)"); $idx =~ s/ \(.*\)//; ! return ("
    ${TLSTART}class$TLEND $idx\n
    " . $_ . '
    '); From gvanrossum@users.sourceforge.net Fri Oct 26 04:25:03 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 25 Oct 2001 20:25:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.187,1.188 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv30548 Modified Files: socketmodule.c Log Message: Add sendall() method, which loops until all data is written or an error occurs, and doesn't return a count. (This is my second patch from SF patch #474307, with small change to the docstring for send().) 2.1.2 "bugfix" candidate. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.187 retrieving revision 1.188 diff -C2 -d -r1.187 -r1.188 *** socketmodule.c 2001/10/25 09:04:03 1.187 --- socketmodule.c 2001/10/26 03:25:00 1.188 *************** *** 67,70 **** --- 67,71 ---- - s.recvfrom(buflen [,flags]) --> string, sockaddr - s.send(string [,flags]) --> nbytes + - s.sendall(string [,flags]) # tries to send everything in a loop - s.sendto(string, [flags,] sockaddr) --> nbytes - s.setblocking(0 | 1) --> None *************** *** 1554,1562 **** static char send_doc[] = ! "send(data[, flags])\n\ \n\ Send a data string to the socket. For the optional flags\n\ ! argument, see the Unix manual."; /* s.sendto(data, [flags,] sockaddr) method */ --- 1555,1598 ---- static char send_doc[] = ! "send(data[, flags]) -> count\n\ \n\ Send a data string to the socket. For the optional flags\n\ ! argument, see the Unix manual. Return the number of bytes\n\ ! sent; this may be less than len(data) if the network is busy."; ! ! ! /* s.sendall(data [,flags]) method */ ! ! static PyObject * ! PySocketSock_sendall(PySocketSockObject *s, PyObject *args) ! { ! char *buf; ! int len, n, flags = 0, total = 0; ! if (!PyArg_ParseTuple(args, "s#|i:sendall", &buf, &len, &flags)) ! return NULL; ! Py_BEGIN_ALLOW_THREADS ! do { ! n = send(s->sock_fd, buf, len, flags); ! if (n < 0) ! break; ! total += n; ! buf += n; ! len -= n; ! } while (len > 0); ! Py_END_ALLOW_THREADS ! if (n < 0) ! return PySocket_Err(); ! Py_INCREF(Py_None); ! return Py_None; ! } + static char sendall_doc[] = + "sendall(data[, flags])\n\ + \n\ + Send a data string to the socket. For the optional flags\n\ + argument, see the Unix manual. This calls send() repeatedly\n\ + until all data is sent. If an error occurs, it's impossible\n\ + to tell how much data has been sent."; + /* s.sendto(data, [flags,] sockaddr) method */ *************** *** 1659,1662 **** --- 1695,1700 ---- {"send", (PyCFunction)PySocketSock_send, METH_VARARGS, send_doc}, + {"sendall", (PyCFunction)PySocketSock_sendall, METH_VARARGS, + sendall_doc}, {"sendto", (PyCFunction)PySocketSock_sendto, METH_VARARGS, sendto_doc}, *************** *** 2693,2697 **** --- 2731,2737 ---- return NULL; + Py_BEGIN_ALLOW_THREADS len = SSL_write(self->ssl, data, len); + Py_END_ALLOW_THREADS if (len > 0) return PyInt_FromLong(len); *************** *** 2718,2722 **** --- 2758,2764 ---- return NULL; + Py_BEGIN_ALLOW_THREADS count = SSL_read(self->ssl, PyString_AsString(buf), len); + Py_END_ALLOW_THREADS if (count <= 0) { Py_DECREF(buf); From gvanrossum@users.sourceforge.net Fri Oct 26 04:38:16 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 25 Oct 2001 20:38:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib CGIHTTPServer.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv384 Modified Files: CGIHTTPServer.py Log Message: Fix two typos, one noted by Noah Spurrier in SF bug #475166, the second noted after a second's thought about what the next line should do. :-( Index: CGIHTTPServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/CGIHTTPServer.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** CGIHTTPServer.py 2001/10/17 06:44:58 1.19 --- CGIHTTPServer.py 2001/10/26 03:38:14 1.20 *************** *** 223,228 **** interp = sys.executable if interp.lower().endswith("w.exe"): ! # On Windows, use python.exe, not python.exe ! interp = interp[:-5] = interp[-4:] cmdline = "%s -u %s" % (interp, cmdline) if '=' not in query and '"' not in query: --- 223,228 ---- interp = sys.executable if interp.lower().endswith("w.exe"): ! # On Windows, use python.exe, not pythonw.exe ! interp = interp[:-5] + interp[-4:] cmdline = "%s -u %s" % (interp, cmdline) if '=' not in query and '"' not in query: From gvanrossum@users.sourceforge.net Fri Oct 26 04:38:48 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 25 Oct 2001 20:38:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.131,1.132 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv479 Modified Files: ACKS Log Message: Fix two typos, one noted by Noah Spurrier in SF bug #475166, the second noted after a second's thought about what the next line should do. :-( Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.131 retrieving revision 1.132 diff -C2 -d -r1.131 -r1.132 *** ACKS 2001/10/25 20:18:35 1.131 --- ACKS 2001/10/26 03:38:46 1.132 *************** *** 398,401 **** --- 398,402 ---- Clay Spence Per Spilling + Noah Spurrier Greg Stein Dan Stromberg From gvanrossum@users.sourceforge.net Fri Oct 26 05:26:14 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 25 Oct 2001 21:26:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.112,2.113 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9797/Objects Modified Files: typeobject.c Log Message: Allow assignment to newinstance.__dict__. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.112 retrieving revision 2.113 diff -C2 -d -r2.112 -r2.113 *** typeobject.c 2001/10/22 00:43:43 2.112 --- typeobject.c 2001/10/26 04:26:11 2.113 *************** *** 675,680 **** } static PyGetSetDef subtype_getsets[] = { ! {"__dict__", subtype_dict, NULL, NULL}, {0}, }; --- 675,703 ---- } + static int + subtype_setdict(PyObject *obj, PyObject *value, void *context) + { + PyObject **dictptr = _PyObject_GetDictPtr(obj); + PyObject *dict; + + if (dictptr == NULL) { + PyErr_SetString(PyExc_AttributeError, + "This object has no __dict__"); + return -1; + } + if (value == NULL || !PyDict_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__dict__ must be set to a dictionary"); + return -1; + } + dict = *dictptr; + Py_INCREF(value); + *dictptr = value; + Py_XDECREF(dict); + return 0; + } + static PyGetSetDef subtype_getsets[] = { ! {"__dict__", subtype_dict, subtype_setdict, NULL}, {0}, }; From gvanrossum@users.sourceforge.net Fri Oct 26 05:26:14 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 25 Oct 2001 21:26:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.93,1.94 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv9797/Lib/test Modified Files: test_descr.py Log Message: Allow assignment to newinstance.__dict__. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.93 retrieving revision 1.94 diff -C2 -d -r1.93 -r1.94 *** test_descr.py 2001/10/22 21:45:25 1.93 --- test_descr.py 2001/10/26 04:26:12 1.94 *************** *** 2085,2088 **** --- 2085,2113 ---- cant(list(), object) + def setdict(): + if verbose: print "Testing __dict__ assignment..." + class C(object): pass + a = C() + a.__dict__ = {'b': 1} + vereq(a.b, 1) + def cant(x, dict): + try: + x.__dict__ = dict + except TypeError: + pass + else: + raise TestFailed, "shouldn't allow %r.__dict__ = %r" % (x, dict) + cant(a, None) + cant(a, []) + cant(a, 1) + try: + del a.__dict__ + except TypeError: + pass + else: + raise TestFailed, "shouldn't allow del %r.__dict__" % (a) + # Classes don't allow __dict__ assignment + cant(C, {}) + def pickles(): if verbose: *************** *** 2392,2395 **** --- 2417,2421 ---- descrdoc() setclass() + setdict() pickles() copies() From gvanrossum@users.sourceforge.net Fri Oct 26 05:31:56 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 25 Oct 2001 21:31:56 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv10990 Modified Files: PLAN.txt Log Message: Update. __dict__ assignment done. Reorder remaining "to do" items by priority. Add tp_cache; add some comments to others. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PLAN.txt,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** PLAN.txt 2001/10/12 17:43:43 1.15 --- PLAN.txt 2001/10/26 04:31:54 1.16 *************** *** 2,18 **** **************************** ! Still to do ! ----------- ! ! Add __del__ handlers? ! Allow assignment to __bases__ and __dict__? Support mixed multiple inheritance from classic and new-style classes? Check for conflicts between base classes. I fear that the rules used to decide whether multiple bases have conflicting instance variables aren't strict enough. I think that sometimes two different classes ! adding __dict__ may be incompatible after all. Check for order conflicts. Suppose there are two base classes X and --- 2,28 ---- **************************** ! Still to do (by priority) ! ------------------------- ! Add __del__ handlers? I asked for a motivation on python-dev and ! nobody piped up. Yet I expect it will be asked for later. Are there ! GC issues? Doesn't the GC make an exception for classic classes with ! a __del__ handler? Support mixed multiple inheritance from classic and new-style classes? + That would be cool and make new-style classes much more usable (it + would remove most of the reasons not to use them for new projects). + How hard would this be? + Do something with the tp_cache slot? This is (was?) intended to cache + all the class attributes from all base classes; a key would be deleted + when the base class attribute is. But the question is, are the + savings worth it? So I may not do this. + Check for conflicts between base classes. I fear that the rules used to decide whether multiple bases have conflicting instance variables aren't strict enough. I think that sometimes two different classes ! adding __dict__ may be incompatible after all. (I may not do this. ! Who cares.) Check for order conflicts. Suppose there are two base classes X and *************** *** 21,28 **** order should the base classes X and Y be searched? This is an order conflict, and should be disallowed; currently the test for this is not ! implemented. Done (mostly) ------------- More performance work -- one particular test, test_descr.inherits(), --- 31,43 ---- order should the base classes X and Y be searched? This is an order conflict, and should be disallowed; currently the test for this is not ! implemented. (I may not do this. Who cares.) + Allow assignment to __bases__? (I don't think there's a demand for + this.) + Done (mostly) ------------- + + Assignment to __dict__. More performance work -- one particular test, test_descr.inherits(), From tim_one@users.sourceforge.net Fri Oct 26 06:06:52 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 25 Oct 2001 22:06:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api abstract.tex,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv13745/python/Doc/api Modified Files: abstract.tex Log Message: Generalize dictionary() to accept a sequence of 2-sequences. At the outer level, the iterator protocol is used for memory-efficiency (the outer sequence may be very large if fully materialized); at the inner level, PySequence_Fast() is used for time-efficiency (these should always be sequences of length 2). dictobject.c, new functions PyDict_{Merge,Update}FromSeq2. These are wholly analogous to PyDict_{Merge,Update}, but process a sequence-of-2- sequences argument instead of a mapping object. For now, I left these functions file static, so no corresponding doc changes. It's tempting to change dict.update() to allow a sequence-of-2-seqs argument too. Also changed the name of dictionary's keyword argument from "mapping" to "x". Got a better name? "mapping_or_sequence_of_pairs" isn't attractive, although more so than "mosop" . abstract.h, abstract.tex: Added new PySequence_Fast_GET_SIZE function, much faster than going thru the all-purpose PySequence_Size. libfuncs.tex: - Document dictionary(). - Fiddle tuple() and list() to admit that their argument is optional. - The long-winded repetitions of "a sequence, a container that supports iteration, or an iterator object" is getting to be a PITA. Many months ago I suggested factoring this out into "iterable object", where the definition of that could include being explicit about generators too (as is, I'm not sure a reader outside of PythonLabs could guess that "an iterator object" includes a generator call). - Please check my curly braces -- I'm going blind <0.9 wink>. abstract.c, PySequence_Tuple(): When PyObject_GetIter() fails, leave its error msg alone now (the msg it produces has improved since PySequence_Tuple was generalized to accept iterable objects, and PySequence_Tuple was also stomping on the msg in cases it shouldn't have even before PyObject_GetIter grew a better msg). Index: abstract.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/abstract.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** abstract.tex 2001/10/12 19:01:43 1.1 --- abstract.tex 2001/10/26 05:06:49 1.2 *************** *** 126,130 **** This is the equivalent of the Python expression \samp{unistr(\var{o})}. Called by the ! \function{unistr()}\bifuncindex{unistr} built-in function. \end{cfuncdesc} --- 126,130 ---- This is the equivalent of the Python expression \samp{unistr(\var{o})}. Called by the ! \function{unistr()}\bifuncindex{unistr} built-in function. \end{cfuncdesc} *************** *** 716,723 **** \begin{cfuncdesc}{PyObject*}{PySequence_Fast_GET_ITEM}{PyObject *o, int i} Return the \var{i}th element of \var{o}, assuming that \var{o} was ! returned by \cfunction{PySequence_Fast()}, and that \var{i} is ! within bounds. The caller is expected to get the length of the ! sequence by calling \cfunction{PySequence_Size()} on \var{o}, since ! lists and tuples are guaranteed to always return their true length. \end{cfuncdesc} --- 716,730 ---- \begin{cfuncdesc}{PyObject*}{PySequence_Fast_GET_ITEM}{PyObject *o, int i} Return the \var{i}th element of \var{o}, assuming that \var{o} was ! returned by \cfunction{PySequence_Fast()}, \var{o} is not \NULL{}, ! and that \var{i} is within bounds. ! \end{cfuncdesc} ! ! \begin{cfuncdesc}{int}{PySequence_Fast_GET_SIZE}{PyObject *o} ! Returns the length of \var{o}, assuming that \var{o} was ! returned by \cfunction{PySequence_Fast()} and that \var{o} is ! not \NULL{}. The size can also be gotten by calling ! \cfunction{PySequence_Size()} on \var{o}, but ! \cfunction{PySequence_Fast_GET_SIZE()} is faster because it can ! assume \var{o} is a list or tuple. \end{cfuncdesc} From tim_one@users.sourceforge.net Fri Oct 26 06:06:52 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 25 Oct 2001 22:06:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include abstract.h,2.37,2.38 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv13745/python/Include Modified Files: abstract.h Log Message: Generalize dictionary() to accept a sequence of 2-sequences. At the outer level, the iterator protocol is used for memory-efficiency (the outer sequence may be very large if fully materialized); at the inner level, PySequence_Fast() is used for time-efficiency (these should always be sequences of length 2). dictobject.c, new functions PyDict_{Merge,Update}FromSeq2. These are wholly analogous to PyDict_{Merge,Update}, but process a sequence-of-2- sequences argument instead of a mapping object. For now, I left these functions file static, so no corresponding doc changes. It's tempting to change dict.update() to allow a sequence-of-2-seqs argument too. Also changed the name of dictionary's keyword argument from "mapping" to "x". Got a better name? "mapping_or_sequence_of_pairs" isn't attractive, although more so than "mosop" . abstract.h, abstract.tex: Added new PySequence_Fast_GET_SIZE function, much faster than going thru the all-purpose PySequence_Size. libfuncs.tex: - Document dictionary(). - Fiddle tuple() and list() to admit that their argument is optional. - The long-winded repetitions of "a sequence, a container that supports iteration, or an iterator object" is getting to be a PITA. Many months ago I suggested factoring this out into "iterable object", where the definition of that could include being explicit about generators too (as is, I'm not sure a reader outside of PythonLabs could guess that "an iterator object" includes a generator call). - Please check my curly braces -- I'm going blind <0.9 wink>. abstract.c, PySequence_Tuple(): When PyObject_GetIter() fails, leave its error msg alone now (the msg it produces has improved since PySequence_Tuple was generalized to accept iterable objects, and PySequence_Tuple was also stomping on the msg in cases it shouldn't have even before PyObject_GetIter grew a better msg). Index: abstract.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/abstract.h,v retrieving revision 2.37 retrieving revision 2.38 diff -C2 -d -r2.37 -r2.38 *** abstract.h 2001/09/08 04:00:11 2.37 --- abstract.h 2001/10/26 05:06:50 2.38 *************** *** 952,956 **** DL_IMPORT(PyObject *) PySequence_List(PyObject *o); - /* Returns the sequence, o, as a list on success, and NULL on failure. --- 952,955 ---- *************** *** 959,967 **** DL_IMPORT(PyObject *) PySequence_Fast(PyObject *o, const char* m); - /* Returns the sequence, o, as a tuple, unless it's already a tuple or list. Use PySequence_Fast_GET_ITEM to access the ! members of this list. Returns NULL on failure. If the object does not support iteration, --- 958,965 ---- DL_IMPORT(PyObject *) PySequence_Fast(PyObject *o, const char* m); /* Returns the sequence, o, as a tuple, unless it's already a tuple or list. Use PySequence_Fast_GET_ITEM to access the ! members of this list, and PySequence_Fast_GET_SIZE to get its length. Returns NULL on failure. If the object does not support iteration, *************** *** 969,975 **** */ #define PySequence_Fast_GET_ITEM(o, i)\ (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i)) - /* Return the ith element of o, assuming that o was returned by --- 967,979 ---- */ + #define PySequence_Fast_GET_SIZE(o) \ + (PyList_Check(o) ? PyList_GET_SIZE(o) : PyTuple_GET_SIZE(o)) + /* + Return the size of o, assuming that o was returned by + PySequence_Fast and is not NULL. + */ + #define PySequence_Fast_GET_ITEM(o, i)\ (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i)) /* Return the ith element of o, assuming that o was returned by From tim_one@users.sourceforge.net Fri Oct 26 06:06:52 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 25 Oct 2001 22:06:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.91,1.92 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv13745/python/Doc/lib Modified Files: libfuncs.tex Log Message: Generalize dictionary() to accept a sequence of 2-sequences. At the outer level, the iterator protocol is used for memory-efficiency (the outer sequence may be very large if fully materialized); at the inner level, PySequence_Fast() is used for time-efficiency (these should always be sequences of length 2). dictobject.c, new functions PyDict_{Merge,Update}FromSeq2. These are wholly analogous to PyDict_{Merge,Update}, but process a sequence-of-2- sequences argument instead of a mapping object. For now, I left these functions file static, so no corresponding doc changes. It's tempting to change dict.update() to allow a sequence-of-2-seqs argument too. Also changed the name of dictionary's keyword argument from "mapping" to "x". Got a better name? "mapping_or_sequence_of_pairs" isn't attractive, although more so than "mosop" . abstract.h, abstract.tex: Added new PySequence_Fast_GET_SIZE function, much faster than going thru the all-purpose PySequence_Size. libfuncs.tex: - Document dictionary(). - Fiddle tuple() and list() to admit that their argument is optional. - The long-winded repetitions of "a sequence, a container that supports iteration, or an iterator object" is getting to be a PITA. Many months ago I suggested factoring this out into "iterable object", where the definition of that could include being explicit about generators too (as is, I'm not sure a reader outside of PythonLabs could guess that "an iterator object" includes a generator call). - Please check my curly braces -- I'm going blind <0.9 wink>. abstract.c, PySequence_Tuple(): When PyObject_GetIter() fails, leave its error msg alone now (the msg it produces has improved since PySequence_Tuple was generalized to accept iterable objects, and PySequence_Tuple was also stomping on the msg in cases it shouldn't have even before PyObject_GetIter grew a better msg). Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.91 retrieving revision 1.92 diff -C2 -d -r1.91 -r1.92 *** libfuncs.tex 2001/10/19 12:02:28 1.91 --- libfuncs.tex 2001/10/26 05:06:50 1.92 *************** *** 176,179 **** --- 176,201 ---- \end{funcdesc} + \begin{funcdesc}{dictionary}{\optional{mapping-or-sequence}} + Return a new dictionary initialized from the optional argument. + If an argument is not specified, return a new empty dictionary. + If the argument is a mapping object, return a dictionary mapping the + same keys to the same values as does the mapping object. + Else the argument must be a sequence, a container that supports + iteration, or an iterator object. The elements of the argument must + each also be of one of those kinds, and each must in turn contain + exactly two objects. The first is used as a key in the new dictionary, + and the second as the key's value. If a given key is seen more than + once, the last value associated with it is retained in the new + dictionary. + For example, these all return a dictionary equal to + \code{\{1: 2, 2: 3\}}: + \code{dictionary(\{1: 2, 2: 3\})}, + \code{dictionary(\{1: 2, 2: 3\}.items()}, + \code{dictionary(\{1: 2, 2: 3\}.iteritems()}, + \code{dictionary(zip((1, 2), (2, 3)))}, + \code{dictionary([[2, 3], [1, 2]])}, and + \code{dictionary([(i-1, i) for i in (2, 3)])}. + \end{funcdesc} + \begin{funcdesc}{dir}{\optional{object}} Without arguments, return the list of names in the current local *************** *** 473,477 **** \end{funcdesc} ! \begin{funcdesc}{list}{sequence} Return a list whose items are the same and in the same order as \var{sequence}'s items. \var{sequence} may be either a sequence, a --- 495,499 ---- \end{funcdesc} ! \begin{funcdesc}{list}{\optional{sequence}} Return a list whose items are the same and in the same order as \var{sequence}'s items. \var{sequence} may be either a sequence, a *************** *** 727,731 **** \end{funcdesc} ! \begin{funcdesc}{tuple}{sequence} Return a tuple whose items are the same and in the same order as \var{sequence}'s items. \var{sequence} may be a sequence, a --- 749,753 ---- \end{funcdesc} ! \begin{funcdesc}{tuple}{\optional{sequence}} Return a tuple whose items are the same and in the same order as \var{sequence}'s items. \var{sequence} may be a sequence, a From tim_one@users.sourceforge.net Fri Oct 26 06:06:52 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 25 Oct 2001 22:06:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.299,1.300 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv13745/python/Misc Modified Files: NEWS Log Message: Generalize dictionary() to accept a sequence of 2-sequences. At the outer level, the iterator protocol is used for memory-efficiency (the outer sequence may be very large if fully materialized); at the inner level, PySequence_Fast() is used for time-efficiency (these should always be sequences of length 2). dictobject.c, new functions PyDict_{Merge,Update}FromSeq2. These are wholly analogous to PyDict_{Merge,Update}, but process a sequence-of-2- sequences argument instead of a mapping object. For now, I left these functions file static, so no corresponding doc changes. It's tempting to change dict.update() to allow a sequence-of-2-seqs argument too. Also changed the name of dictionary's keyword argument from "mapping" to "x". Got a better name? "mapping_or_sequence_of_pairs" isn't attractive, although more so than "mosop" . abstract.h, abstract.tex: Added new PySequence_Fast_GET_SIZE function, much faster than going thru the all-purpose PySequence_Size. libfuncs.tex: - Document dictionary(). - Fiddle tuple() and list() to admit that their argument is optional. - The long-winded repetitions of "a sequence, a container that supports iteration, or an iterator object" is getting to be a PITA. Many months ago I suggested factoring this out into "iterable object", where the definition of that could include being explicit about generators too (as is, I'm not sure a reader outside of PythonLabs could guess that "an iterator object" includes a generator call). - Please check my curly braces -- I'm going blind <0.9 wink>. abstract.c, PySequence_Tuple(): When PyObject_GetIter() fails, leave its error msg alone now (the msg it produces has improved since PySequence_Tuple was generalized to accept iterable objects, and PySequence_Tuple was also stomping on the msg in cases it shouldn't have even before PyObject_GetIter grew a better msg). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.299 retrieving revision 1.300 diff -C2 -d -r1.299 -r1.300 *** NEWS 2001/10/25 21:53:30 1.299 --- NEWS 2001/10/26 05:06:50 1.300 *************** *** 5,8 **** --- 5,13 ---- Type/class unification and new-style classes + - dictionary() now accepts an iterable object producing 2-sequences. + For example, dictionary(d.items()) == d for any dictionary d. The + argument, and the elements of the argument, can be any iterable + objects. + - Methods of built-in types now properly check for keyword arguments (formerly these were silently ignored). The only built-in methods *************** *** 31,34 **** --- 36,43 ---- C API + + - New function PySequence_Fast_GET_SIZE() returns the size of a non- + NULL result from PySequence_Fast(), more quickly than calling + PySequence_Size(). New platforms From tim_one@users.sourceforge.net Fri Oct 26 06:06:52 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 25 Oct 2001 22:06:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.94,1.95 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv13745/python/Lib/test Modified Files: test_descr.py Log Message: Generalize dictionary() to accept a sequence of 2-sequences. At the outer level, the iterator protocol is used for memory-efficiency (the outer sequence may be very large if fully materialized); at the inner level, PySequence_Fast() is used for time-efficiency (these should always be sequences of length 2). dictobject.c, new functions PyDict_{Merge,Update}FromSeq2. These are wholly analogous to PyDict_{Merge,Update}, but process a sequence-of-2- sequences argument instead of a mapping object. For now, I left these functions file static, so no corresponding doc changes. It's tempting to change dict.update() to allow a sequence-of-2-seqs argument too. Also changed the name of dictionary's keyword argument from "mapping" to "x". Got a better name? "mapping_or_sequence_of_pairs" isn't attractive, although more so than "mosop" . abstract.h, abstract.tex: Added new PySequence_Fast_GET_SIZE function, much faster than going thru the all-purpose PySequence_Size. libfuncs.tex: - Document dictionary(). - Fiddle tuple() and list() to admit that their argument is optional. - The long-winded repetitions of "a sequence, a container that supports iteration, or an iterator object" is getting to be a PITA. Many months ago I suggested factoring this out into "iterable object", where the definition of that could include being explicit about generators too (as is, I'm not sure a reader outside of PythonLabs could guess that "an iterator object" includes a generator call). - Please check my curly braces -- I'm going blind <0.9 wink>. abstract.c, PySequence_Tuple(): When PyObject_GetIter() fails, leave its error msg alone now (the msg it produces has improved since PySequence_Tuple was generalized to accept iterable objects, and PySequence_Tuple was also stomping on the msg in cases it shouldn't have even before PyObject_GetIter grew a better msg). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.94 retrieving revision 1.95 diff -C2 -d -r1.94 -r1.95 *** test_descr.py 2001/10/26 04:26:12 1.94 --- test_descr.py 2001/10/26 05:06:50 1.95 *************** *** 179,186 **** d = dictionary({}) vereq(d, {}) ! d = dictionary(mapping={}) vereq(d, {}) d = dictionary({1: 2, 'a': 'b'}) vereq(d, {1: 2, 'a': 'b'}) for badarg in 0, 0L, 0j, "0", [0], (0,): try: --- 179,188 ---- d = dictionary({}) vereq(d, {}) ! d = dictionary(x={}) vereq(d, {}) d = dictionary({1: 2, 'a': 'b'}) vereq(d, {1: 2, 'a': 'b'}) + vereq(d, dictionary(d.items())) + vereq(d, dictionary(x=d.iteritems())) for badarg in 0, 0L, 0j, "0", [0], (0,): try: *************** *** 188,191 **** --- 190,201 ---- except TypeError: pass + except ValueError: + if badarg == "0": + # It's a sequence, and its elements are also sequences (gotta + # love strings ), but they aren't of length 2, so this + # one seemed better as a ValueError than a TypeError. + pass + else: + raise TestFailed("no TypeError from dictionary(%r)" % badarg) else: raise TestFailed("no TypeError from dictionary(%r)" % badarg) *************** *** 195,199 **** pass else: ! raise TestFailed("no TypeError from dictionary(senseless={}") try: --- 205,209 ---- pass else: ! raise TestFailed("no TypeError from dictionary(senseless={})") try: *************** *** 205,213 **** class Mapping: dict = {1:2, 3:4, 'a':1j} - def __getitem__(self, i): - return self.dict[i] - try: dictionary(Mapping()) --- 215,221 ---- class Mapping: + # Lacks a .keys() method; will be added later. dict = {1:2, 3:4, 'a':1j} try: dictionary(Mapping()) *************** *** 218,224 **** Mapping.keys = lambda self: self.dict.keys() ! d = dictionary(mapping=Mapping()) vereq(d, Mapping.dict) def test_dir(): if verbose: --- 226,259 ---- Mapping.keys = lambda self: self.dict.keys() ! Mapping.__getitem__ = lambda self, i: self.dict[i] ! d = dictionary(x=Mapping()) vereq(d, Mapping.dict) + # Init from sequence of iterable objects, each producing a 2-sequence. + class AddressBookEntry: + def __init__(self, first, last): + self.first = first + self.last = last + def __iter__(self): + return iter([self.first, self.last]) + + d = dictionary([AddressBookEntry('Tim', 'Warsaw'), + AddressBookEntry('Barry', 'Peters'), + AddressBookEntry('Tim', 'Peters'), + AddressBookEntry('Barry', 'Warsaw')]) + vereq(d, {'Barry': 'Warsaw', 'Tim': 'Peters'}) + + d = dictionary(zip(range(4), range(1, 5))) + vereq(d, dictionary([(i, i+1) for i in range(4)])) + + # Bad sequence lengths. + for bad in ['tooshort'], ['too', 'long', 'by 1']: + try: + dictionary(bad) + except ValueError: + pass + else: + raise TestFailed("no ValueError from dictionary(%r)" % bad) + def test_dir(): if verbose: *************** *** 1831,1835 **** vereq(tuple(sequence=range(3)), (0, 1, 2)) vereq(list(sequence=(0, 1, 2)), range(3)) ! vereq(dictionary(mapping={1: 2}), {1: 2}) for constructor in (int, float, long, complex, str, unicode, --- 1866,1870 ---- vereq(tuple(sequence=range(3)), (0, 1, 2)) vereq(list(sequence=(0, 1, 2)), range(3)) ! vereq(dictionary(x={1: 2}), {1: 2}) for constructor in (int, float, long, complex, str, unicode, *************** *** 2372,2376 **** a = [] list.__init__(a, sequence=[0, 1, 2]) ! vereq(a, [0, 1, 2]) def test_main(): --- 2407,2411 ---- a = [] list.__init__(a, sequence=[0, 1, 2]) ! vereq(a, [0, 1, 2]) def test_main(): From tim_one@users.sourceforge.net Fri Oct 26 06:06:52 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 25 Oct 2001 22:06:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.86,2.87 dictobject.c,2.114,2.115 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv13745/python/Objects Modified Files: abstract.c dictobject.c Log Message: Generalize dictionary() to accept a sequence of 2-sequences. At the outer level, the iterator protocol is used for memory-efficiency (the outer sequence may be very large if fully materialized); at the inner level, PySequence_Fast() is used for time-efficiency (these should always be sequences of length 2). dictobject.c, new functions PyDict_{Merge,Update}FromSeq2. These are wholly analogous to PyDict_{Merge,Update}, but process a sequence-of-2- sequences argument instead of a mapping object. For now, I left these functions file static, so no corresponding doc changes. It's tempting to change dict.update() to allow a sequence-of-2-seqs argument too. Also changed the name of dictionary's keyword argument from "mapping" to "x". Got a better name? "mapping_or_sequence_of_pairs" isn't attractive, although more so than "mosop" . abstract.h, abstract.tex: Added new PySequence_Fast_GET_SIZE function, much faster than going thru the all-purpose PySequence_Size. libfuncs.tex: - Document dictionary(). - Fiddle tuple() and list() to admit that their argument is optional. - The long-winded repetitions of "a sequence, a container that supports iteration, or an iterator object" is getting to be a PITA. Many months ago I suggested factoring this out into "iterable object", where the definition of that could include being explicit about generators too (as is, I'm not sure a reader outside of PythonLabs could guess that "an iterator object" includes a generator call). - Please check my curly braces -- I'm going blind <0.9 wink>. abstract.c, PySequence_Tuple(): When PyObject_GetIter() fails, leave its error msg alone now (the msg it produces has improved since PySequence_Tuple was generalized to accept iterable objects, and PySequence_Tuple was also stomping on the msg in cases it shouldn't have even before PyObject_GetIter grew a better msg). Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.86 retrieving revision 2.87 diff -C2 -d -r2.86 -r2.87 *** abstract.c 2001/10/22 04:12:44 2.86 --- abstract.c 2001/10/26 05:06:50 2.87 *************** *** 1279,1283 **** it = PyObject_GetIter(v); if (it == NULL) ! return type_error("tuple() argument must support iteration"); /* Guess result size and allocate space. */ --- 1279,1283 ---- it = PyObject_GetIter(v); if (it == NULL) ! return NULL; /* Guess result size and allocate space. */ Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.114 retrieving revision 2.115 diff -C2 -d -r2.114 -r2.115 *** dictobject.c 2001/10/05 20:51:38 2.114 --- dictobject.c 2001/10/26 05:06:50 2.115 *************** *** 994,999 **** /* Update unconditionally replaces existing items. Merge has a 3rd argument 'override'; if set, it acts like Update, ! otherwise it leaves existing items unchanged. */ int PyDict_Update(PyObject *a, PyObject *b) --- 994,1081 ---- /* Update unconditionally replaces existing items. Merge has a 3rd argument 'override'; if set, it acts like Update, ! otherwise it leaves existing items unchanged. ! ! PyDict_{Update,Merge} update/merge from a mapping object. ! ! PyDict_{Update,Merge}FromSeq2 update/merge from any iterable object ! producing iterable objects of length 2. ! */ ! ! static int ! PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override) ! { ! PyObject *it; /* iter(seq2) */ ! int i; /* index into seq2 of current element */ ! PyObject *item; /* seq2[i] */ ! PyObject *fast; /* item as a 2-tuple or 2-list */ ! ! assert(d != NULL); ! assert(PyDict_Check(d)); ! assert(seq2 != NULL); ! ! it = PyObject_GetIter(seq2); ! if (it == NULL) ! return -1; ! ! for (i = 0; ; ++i) { ! PyObject *key, *value; ! int n; ! ! fast = NULL; ! item = PyIter_Next(it); ! if (item == NULL) { ! if (PyErr_Occurred()) ! goto Fail; ! break; ! } ! ! /* Convert item to sequence, and verify length 2. */ ! fast = PySequence_Fast(item, ""); ! if (fast == NULL) { ! if (PyErr_ExceptionMatches(PyExc_TypeError)) ! PyErr_Format(PyExc_TypeError, ! "cannot convert dictionary update " ! "sequence element #%d to a sequence", ! i); ! goto Fail; ! } ! n = PySequence_Fast_GET_SIZE(fast); ! if (n != 2) { ! PyErr_Format(PyExc_ValueError, ! "dictionary update sequence element #%d " ! "has length %d; 2 is required", ! i, n); ! goto Fail; ! } ! ! /* Update/merge with this (key, value) pair. */ ! key = PySequence_Fast_GET_ITEM(fast, 0); ! value = PySequence_Fast_GET_ITEM(fast, 1); ! if (override || PyDict_GetItem(d, key) == NULL) { ! int status = PyDict_SetItem(d, key, value); ! if (status < 0) ! goto Fail; ! } ! Py_DECREF(fast); ! Py_DECREF(item); ! } ! ! i = 0; ! goto Return; ! Fail: ! Py_XDECREF(item); ! Py_XDECREF(fast); ! i = -1; ! Return: ! Py_DECREF(it); ! return i; ! } + static int + PyDict_UpdateFromSeq2(PyObject *d, PyObject *seq2) + { + return PyDict_MergeFromSeq2(d, seq2, 1); + } + int PyDict_Update(PyObject *a, PyObject *b) *************** *** 1700,1720 **** { PyObject *arg = NULL; ! static char *kwlist[] = {"mapping", 0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:dictionary", kwlist, &arg)) ! return -1; ! if (arg != NULL) { ! if (PyDict_Merge(self, arg, 1) < 0) { ! /* An error like "AttributeError: keys" is too ! cryptic in this context. */ ! if (PyErr_ExceptionMatches(PyExc_AttributeError)) { ! PyErr_SetString(PyExc_TypeError, ! "argument must be of a mapping type"); ! } ! return -1; ! } } ! return 0; } --- 1782,1799 ---- { PyObject *arg = NULL; ! static char *kwlist[] = {"x", 0}; ! int result = 0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:dictionary", kwlist, &arg)) ! result = -1; ! ! else if (arg != NULL) { ! if (PyObject_HasAttrString(arg, "keys")) ! result = PyDict_Merge(self, arg, 1); ! else ! result = PyDict_MergeFromSeq2(self, arg, 1); } ! return result; } *************** *** 1726,1731 **** static char dictionary_doc[] = ! "dictionary() -> new empty dictionary\n" ! "dictionary(mapping) -> new dict initialized from mapping's key+value pairs"; PyTypeObject PyDict_Type = { --- 1805,1817 ---- static char dictionary_doc[] = ! "dictionary() -> new empty dictionary.\n" ! "dictionary(mapping) -> new dict initialized from a mapping object's\n" ! " (key, value) pairs.\n" ! "dictionary(seq) -> new dict initialized from the 2-element elements of\n" ! " a sequence; for example, from mapping.items(). seq must be an\n" ! " iterable object, producing iterable objects each producing exactly\n" ! " two objects, the first of which is used as a key and the second as\n" ! " its value. If a given key is seen more than once, the dict retains\n" ! " the last value associated with it."; PyTypeObject PyDict_Type = { From mwh@users.sourceforge.net Fri Oct 26 09:05:50 2001 From: mwh@users.sourceforge.net (Michael Hudson) Date: Fri, 26 Oct 2001 01:05:50 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0264.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv1749 Modified Files: pep-0264.txt Log Message: Update to reflect what actually happened (should have done this ages ago). I think this PEP can now be marked final. Index: pep-0264.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0264.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pep-0264.txt 2001/08/17 22:43:49 1.5 --- pep-0264.txt 2001/10/26 08:05:48 1.6 *************** *** 1,5 **** PEP: 264 Title: Future statements in simulated shells ! Version: 3 Author: Michael Hudson Status: Accepted --- 1,5 ---- PEP: 264 Title: Future statements in simulated shells ! Version: 4 Author: Michael Hudson Status: Accepted *************** *** 70,92 **** compiled in an environment where generators were allowed. ! I will also add a .__all__ attribute to the __future__ module, ! giving a low-effort way of enumerating all the __future__ options ! supported by the running interpreter. I also propose adding a pair of classes to the standard library module codeop. ! One - probably called Compile - will sport a __call__ method which ! will act much like the builtin "compile" of 2.1 with the ! difference that after it has compiled a __future__ statement, it ! "remembers" it and compiles all subsequent code with the ! __future__ option in effect. It will do this by using the new features of the __future__ module mentioned above. ! Objects of the other class added to codeop - probably called ! CommandCompiler or somesuch - will do the job of the existing ! codeop.compile_command function, but in a __future__-aware way. Finally, I propose to modify the class InteractiveInterpreter in --- 70,91 ---- compiled in an environment where generators were allowed. ! I will also add a .all_feature_flags attribute to the __future__ ! module, giving a low-effort way of enumerating all the __future__ ! options supported by the running interpreter. I also propose adding a pair of classes to the standard library module codeop. ! One - Compile - will sport a __call__ method which will act much ! like the builtin "compile" of 2.1 with the difference that after ! it has compiled a __future__ statement, it "remembers" it and ! compiles all subsequent code with the __future__ option in effect. It will do this by using the new features of the __future__ module mentioned above. ! Objects of the other class added to codeop - CommandCompiler - ! will do the job of the existing codeop.compile_command function, ! but in a __future__-aware way. Finally, I propose to modify the class InteractiveInterpreter in *************** *** 108,113 **** Forward Compatibility ! The check for unrecognised bits in compile() will need updating as ! and when more bits are recognised. --- 107,113 ---- Forward Compatibility ! The fiddling that needs to be done to Lib/__future__.py when ! adding a __future_ feature will be a touch more complicated. ! Everything else should just work. *************** *** 120,128 **** Implementation ! I've uploaded a series of (still) preliminary implementations at: http://sourceforge.net/tracker/?func=detail&atid=305470&aid=449043&group_id=5470 ! I still need to do docs (I've done docstrings) and tests. --- 120,128 ---- Implementation ! A series of preliminary implementations are at: http://sourceforge.net/tracker/?func=detail&atid=305470&aid=449043&group_id=5470 ! After light massagin by Tim Peters, they have now been checked in. From sjoerd.mullender@oratrix.com Fri Oct 26 09:53:04 2001 From: sjoerd.mullender@oratrix.com (Sjoerd Mullender) Date: Fri, 26 Oct 2001 10:53:04 +0200 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.12,1.13 In-Reply-To: Your message of Thu, 25 Oct 2001 08:42:59 -0700. References: Message-ID: <20011026085305.7B061305652@bireme.oratrix.nl> Eh, that was that other Oratrix guy who suggested this... On Thu, Oct 25 2001 Barry Warsaw wrote: > Update of /cvsroot/python/python/nondist/peps > In directory usw-pr-cvs1:/tmp/cvs-serv2263 > > Modified Files: > pep-0101.txt > Log Message: > Jack rightly suggests doing the cvs update with -d -P and -A. > > > Index: pep-0101.txt > =================================================================== > RCS file: /cvsroot/python/python/nondist/peps/pep-0101.txt,v > retrieving revision 1.12 > retrieving revision 1.13 > diff -C2 -d -r1.12 -r1.13 > *** pep-0101.txt 2001/10/25 15:41:29 1.12 > --- pep-0101.txt 2001/10/25 15:42:57 1.13 > *************** > *** 74,79 **** > To create a branch the following steps are taken: > > ! ___ Do a CVS update with the -A flag, e.g. > ! % cvs update -A > > ___ CVS tag the trunk with the symbolic name "rXYaZ-fork", e.g. > --- 74,79 ---- > To create a branch the following steps are taken: > > ! ___ Do a CVS update with the -A, -d, and -P flags, e.g. > ! % cvs -q update -d -P -A > > ___ CVS tag the trunk with the symbolic name "rXYaZ-fork", e.g. > > > _______________________________________________ > Python-checkins mailing list > Python-checkins@python.org > http://mail.python.org/mailman/listinfo/python-checkins > -- Sjoerd Mullender From fdrake@users.sourceforge.net Fri Oct 26 12:27:56 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 04:27:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libweakref.tex,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv26940/lib Modified Files: libweakref.tex Log Message: Typo: destuction --> destruction Reported by Thomas Heller. Index: libweakref.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libweakref.tex,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** libweakref.tex 2001/10/26 03:00:39 1.13 --- libweakref.tex 2001/10/26 11:27:54 1.14 *************** *** 249,253 **** PyObject_ClearWeakRefs((PyObject *) inst); ! /* Proceed with object destuction normally. */ } \end{verbatim} --- 249,253 ---- PyObject_ClearWeakRefs((PyObject *) inst); ! /* Proceed with object destruction normally. */ } \end{verbatim} From jackjansen@users.sourceforge.net Fri Oct 26 13:53:56 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Fri, 26 Oct 2001 05:53:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Unsupported/PythonScript - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Unsupported/PythonScript In directory usw-pr-cvs1:/tmp/cvs-serv2294/PythonScript Log Message: Directory /cvsroot/python/python/dist/src/Mac/Unsupported/PythonScript added to the repository From jackjansen@users.sourceforge.net Fri Oct 26 13:55:41 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Fri, 26 Oct 2001 05:55:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Contrib/PythonScript PyScriptTest.py,1.1.1.1,NONE PythonScript.py,1.2,NONE ReadMe.txt,1.2,NONE baepack.py,1.3,NONE baetools.py,1.2,NONE baetypes.py,1.3,NONE getaete.py,1.2,NONE printaete.py,1.2,NONE testeudora.py,1.1.1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Contrib/PythonScript In directory usw-pr-cvs1:/tmp/cvs-serv2683/Contrib/PythonScript Removed Files: PyScriptTest.py PythonScript.py ReadMe.txt baepack.py baetools.py baetypes.py getaete.py printaete.py testeudora.py Log Message: Moved PythonScript to unsupported at Bill Bedford's request. It'll go away completely next release, unless someone complains. --- PyScriptTest.py DELETED --- --- PythonScript.py DELETED --- --- ReadMe.txt DELETED --- --- baepack.py DELETED --- --- baetools.py DELETED --- --- baetypes.py DELETED --- --- getaete.py DELETED --- --- printaete.py DELETED --- --- testeudora.py DELETED --- From jackjansen@users.sourceforge.net Fri Oct 26 13:55:42 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Fri, 26 Oct 2001 05:55:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Unsupported/PythonScript PyScriptTest.py,NONE,1.1 PythonScript.py,NONE,1.1 ReadMe.txt,NONE,1.1 baepack.py,NONE,1.1 baetools.py,NONE,1.1 baetypes.py,NONE,1.1 getaete.py,NONE,1.1 printaete.py,NONE,1.1 testeudora.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Unsupported/PythonScript In directory usw-pr-cvs1:/tmp/cvs-serv2683/Unsupported/PythonScript Added Files: PyScriptTest.py PythonScript.py ReadMe.txt baepack.py baetools.py baetypes.py getaete.py printaete.py testeudora.py Log Message: Moved PythonScript to unsupported at Bill Bedford's request. It'll go away completely next release, unless someone complains. --- NEW FILE: PyScriptTest.py --- ''' Minimal test module '''# import sys import PythonScript SIGNATURE = 'MACS' TIMEOUT = 10*60*60 PythonScript.PsScript(SIGNATURE, TIMEOUT) p = PythonScript.PyScript ev = PythonScript.PsEvents pc = PythonScript.PsClass pp = PythonScript.PsProperties startup = str(p(ev.Get, pc.Desktopobject(1).Startup_disk().Name())) print 'startup',startup, type(startup) print p(ev.Get, pc.Disk(startup).Folder(7).File(1).Name()) print p(ev.Get, pc.Disk(1).Name()) print p(ev.Get, pc.Disk('every').Name()) print p(ev.Make, None, New='Alias_file', At=pp.Desktop(''), To=pp.System_folder(1)) sys.exit(1) --- NEW FILE: PythonScript.py --- """ Python script a module to comunicate with apple events v 0.1a2 v.0.2 16 april 1998 """ import sys import getaete import baetools import baetypes from Carbon import AE import AppleEvents import macfs from types import * #from aetypes import InstanceType from aepack import AEDescType ordinal = { 'every': 'all ', 'first' : 'firs', 'last' : 'last', 'any' : 'any ', 'middle' : 'midd'} Error = 'PythonScript.Error' class PsEvents: pass class PsClasses: def __getattr__(self, name): try: return DCItem(name, self) except: pass def __repr__(self): if self.form != 'prop': t = type(self.seld) if t == StringType: self.form = 'name' elif baetypes.IsRange(self.seld): self.form = 'rang' elif baetypes.IsComparison(self.seld) or baetypes.IsLogical(self.seld): self.form = 'test' elif t == TupleType: # Breakout: specify both form and seld in a tuple # (if you want ID or rele or somesuch) self.form, self.seld = self.seld elif t == IntType: self.form = 'indx' else: pass if self.seld in ordinal.keys(): self.seld = baetypes.Ordinal(ordinal[self.seld]) self.form = 'indx' s = "baetypes.ObjectSpecifier(%s, %s, %s" % (`self.want`, `self.form`, `self.seld`) if `self.fr`: s = s + ", %s)" % `self.fr` else: s = s + ")" return s def __str__(self): return self.want def template(self, seld=None, fr=None): self.seld = seld self.fr = fr def template1(self, which, fr=None): self.want = 'prop' self.form = 'prop' self.fr = fr class DCItem: def __init__(self, comp, fr): self.compclass = comp self.fr = fr def __call__(self, which=None): if which: self.compclass = eval('PsClass.%s' % self.compclass) else: try: self.compclass = eval('PsProperties.%s' % self.compclass) except AttributeError: self.compclass = eval('PsClass.%s' % self.compclass) return self.compclass(which, self.fr) class PsClass: pass class PsProperties: pass class PsEnumerations: pass def PsScript(sig=None, Timeout=0, Ignoring=0): elements = {} if sig: target, sig = Signature(sig) pyscript = getaete.Getaete(sig) else: target, sig = Signature('Pyth') pyscript = getaete.Getaete() setattr(PyScript, 'timeout', Timeout) setattr(PyScript, 'ignoring', Ignoring) setattr(PyScript, 'target', target) for key, value in pyscript[0].items(): setattr(PsEvents, key, value) for key, value in pyscript[1].items(): CreateClass(key, 'PsClasses', value) for val in value[2]: CreateProperty(val[0], 'PsClasses', `val[1]`) if value[3]: for val in value[3]: if val[0] not in elements.keys(): elements[val[0]] = val[1] elif len(val[1]) > len(elements[val[0]]): elements[val[0]] = val[1] for key, value in pyscript[2].items(): for val in value: setattr(PsEnumerations, val[0], val[1]) def CreateClass(newClassName, superClassName, value): parentDict = PsClass.__dict__ exec "class %s(%s): pass" % (newClassName, superClassName) in \ globals(), parentDict newClassObj = parentDict[newClassName] newClassObj.__init__ = template exec "setattr(newClassObj, 'want', %s)" % `value[0]` if value[2] and value[2][0][0] == 'every': exec "setattr(newClassObj, 'plur', 1)" def CreateProperty(newClassName, superClassName, value): parentDict = PsProperties.__dict__ exec "class %s(%s): pass" % (newClassName, superClassName) in \ globals(), parentDict newClassObj = parentDict[newClassName] if newClassName == 'Every': value = "baetypes.mkOrdinal('every')" newClassObj.__init__ = template1 exec "setattr(newClassObj, 'seld', %s)" % value def Signature(signature): if type(signature) == AEDescType: target = signature elif type(signature) == InstanceType and hasattr(signature, '__aepack__'): target = signature.__aepack__() elif type(signature) == StringType: if len(signature) == 4: target = AE.AECreateDesc(AppleEvents.typeApplSignature, signature) target_signature = signature else: #This should ready be made persistant, so PythonScript 'remembered' where applications were fss, ok = macfs.PromptGetFile('Find the aplication %s' % signature, 'APPL') if ok: target_signature = fss.GetCreatorType()[0] target = AE.AECreateDesc(AppleEvents.typeApplSignature, target_signature) else: raise TypeError, "signature should be 4-char string or AEDesc" return target, target_signature class PyScript(PsEvents): def __init__(self, name, obj=None, **args): desc, code, subcode, rply, message, keywds = name # print 'code', code # print 'subcode', subcode # print 'rply', rply # print 'message', message # print 'keywds', keywds # print 'name', name # print 'obj', obj # print 'args', args self.code = code self.subcode = subcode self.attributes ={} self.arguments = {} if keywds: self.arguments = self.keyargs(keywds, args) self.arguments['----'] = self.keyfms(message[0], obj) ##XXXX Eudora needs this XXXX## if self.arguments['----'] == None: del self.arguments['----'] # print 'arguments', self.arguments if self.ignoring or rply[0] == 'null': self.send_flags = AppleEvents.kAENoReply else: self.send_flags = AppleEvents.kAEWaitReply self.send_priority = AppleEvents.kAENormalPriority if self.timeout: self.send_timeout = self.timeout else: self.send_timeout = AppleEvents.kAEDefaultTimeout def keyargs(self, ats, args): # print 'keyargs', ats, args output = {} for arg in args.keys(): for at in ats: if at[0] == arg: output[at[1]] = self.keyfms(at[2][0], args[arg]) return output def keyfms(self, key, value): # print 'keyfms', 'key', key, `value` if key == 'obj ' or key == 'insl': return eval(`value`) elif key == 'TEXT': return value elif key == 'null': return elif key == 'bool': return baetypes.mkboolean(value) elif key == 'type': try: val = eval('PsClass.%s()' % value) return baetypes.mktype(str(val)) except: return baetypes.mktype(value) else: print "I don't know what to put here -- script.keyargs" print key, `value` sys.exit[1] def newevent(self, code, subcode, parameters = {}, attributes = {}): """Create a complete structure for an apple event""" # print code, subcode, parameters, attributes event = AE.AECreateAppleEvent(code, subcode, self.target, AppleEvents.kAutoGenerateReturnID, AppleEvents.kAnyTransactionID) baetools.packevent(event, parameters, attributes) return event def sendevent(self, event): """Send a pre-created appleevent, await the reply and unpack it""" reply = event.AESend(self.send_flags, self.send_priority, self.send_timeout) parameters, attributes = baetools.unpackevent(reply) return reply, parameters, attributes def send(self, code, subcode, parameters = {}, attributes = {}): """Send an appleevent given code/subcode/pars/attrs and unpack the reply""" # print code, subcode, parameters, attributes return self.sendevent(self.newevent(code, subcode, parameters, attributes)) def __str__(self): _reply, _arguments, _attributes = self.send(self.code, self.subcode, self.arguments, self.attributes) if _arguments.has_key('errn'): raise baetools.Error, baetools.decodeerror(_arguments) # XXXX Optionally decode result if _arguments.has_key('----'): return str(_arguments['----']) else: return def test(): Simp = 'Hermit:Applications:SimpleText' PsScript('MACS', Timeout=60*60*3) # PsScript('CSOm', Timeout=60*60*3) # PsScript('', Timeout=60*60*3) # PyScript('macsoup') ev = PsEvents ps = PsClass # print PsProperties.__dict__ # y = script(ev.Open, File('Hermit:Desktop Folder:Lincolnshire Imp'), using=Application_file(Simp)) # print baetypes.NProperty('prop', 'prop', 'pnam', baetypes.ObjectSpecifier('cdis', 'indx', 1, None)) # y = PyScript(ev.Get, Disk("Hermit").Folder(7).File(1).Name()) # y = PyScript(ev.Get, Disk("Hermit").Size(), As='Integer') # y = PyScript(ev.Get, ps.Desktopobject(1).Startup_disk()) # y = PyScript(ev.Get, Mailbox(1).File(), as='TEXT') # print 'y', y, type(y) if __name__ == '__main__': test() # sys.exit(1) --- NEW FILE: ReadMe.txt --- PythonScript ------------ v0.5 beta 1 24/04/98 author: Bill Bedford, This suite of modules is a first attempt at writing a more user friendly python/appleevent interface. The files in the suite are: PythonScript ------------ Loads three dictionaries generated by getaete into __dict__'s of three classes and thus gives us direct assess to all the methods in the aete. Each method now contains all the information needed to build apple events. The general usage is >>>PythonScript.PsScript(SIGNATURE, TIMEOUT, IGNORING) where SIGNATURE is the target application TIMEOUT is in ticks and IGNORING is a boolean and determines whether the script waits for a reply from the target before going on to the next event >>>PythonScript.PyScript(Event, Object, keywdarg1..., keywdarg2...etc) Object is a appleevent object specifier and is of the form PythonScript.PsClass.Class1(arg).Class2(arg)ƒ.Property() All applescript event, class and property names are capitalised to distinguish them from python methods. getaete ------- Reads the aete of the target application and returns it as a list of three dictionaries, which represent all the events, properties and enumeration in the aete. (the fourth dictionary, comparisons, has never been implemented in applescript so I have not used it) It also reads the applescript aeut and adds any suites that are missing (ie where the application author has set his suite to inherit from the aeut.) and the applescript suite, which gives the language methods printaete --------- Produces a text file with the aete set out in a human readable form, similar to the Open Dictionary command in the applescript editor. baetools, baepack, baetypes --------------------------- These are direct equivalents of aetools, aepack, aetypes in the standard distribution. Some methods and classes have been enhanced others are redundant PyScriptTest, testeudora ------------------------ A couple of test scripts. Testeudora is an updated version of the one in the standard distribution. Still To Do (in no particular order) ----------- These modules are much slower than applescript. I believe they could be made faster by rewriting the aete parser in getaete and/or by putting in some form of persistent storage so that the class dictionaries can be cached. The parsing of the appleevent replies need rewriting. Support for the use of scripting additions. A Python aeut needs to be written, much of the applescript one is redundant in python. Probably a few other things I haven't thought of yet. --- NEW FILE: baepack.py --- """Tools for use in AppleEvent clients and servers: conversion between AE types and python types pack(x) converts a Python object to an AEDesc object unpack(desc) does the reverse coerce(x, wanted_sample) coerces a python object to another python object """ # # This code was originally written by Guido, and modified/extended by Jack # to include the various types that were missing. The reference used is # Apple Event Registry, chapter 9. # import struct import string import types from string import strip from types import * from Carbon import AE from Carbon.AppleEvents import * import MacOS import macfs import StringIO import baetypes from baetypes import mkenum, mktype import calldll OSL = calldll.getlibrary('ObjectSupportLib') # These ones seem to be missing from AppleEvents # (they're in AERegistry.h) #typeColorTable = 'clrt' #typeDrawingArea = 'cdrw' #typePixelMap = 'cpix' #typePixelMapMinus = 'tpmm' #typeRotation = 'trot' #typeTextStyles = 'tsty' #typeStyledText = 'STXT' #typeAEText = 'tTXT' #typeEnumeration = 'enum' # # Some AE types are immedeately coerced into something # we like better (and which is equivalent) # unpacker_coercions = { typeComp : typeExtended, typeColorTable : typeAEList, typeDrawingArea : typeAERecord, typeFixed : typeExtended, typeFloat : typeExtended, typePixelMap : typeAERecord, typeRotation : typeAERecord, typeStyledText : typeAERecord, typeTextStyles : typeAERecord, }; # # Some python types we need in the packer: # AEDescType = type(AE.AECreateDesc('TEXT', '')) _sample_fss = macfs.FSSpec(':') _sample_alias = _sample_fss.NewAliasMinimal() FSSType = type(_sample_fss) AliasType = type(_sample_alias) def pack(x, forcetype = None): """Pack a python object into an AE descriptor""" # print 'aepack', x, type(x), forcetype # if type(x) == TupleType: # forcetype, x = x if forcetype: print x, forcetype if type(x) is StringType: return AE.AECreateDesc(forcetype, x) else: return pack(x).AECoerceDesc(forcetype) if x == None: return AE.AECreateDesc('null', '') t = type(x) if t == AEDescType: return x if t == FSSType: return AE.AECreateDesc('fss ', x.data) if t == AliasType: return AE.AECreateDesc('alis', x.data) if t == IntType: return AE.AECreateDesc('long', struct.pack('l', x)) if t == FloatType: # # XXXX (note by Guido) Weird thing -- Think C's "double" is 10 bytes, but # struct.pack('d') return 12 bytes (and struct.unpack requires # them, too). The first 2 bytes seem to be repeated... # Probably an alignment problem # XXXX (note by Jack) haven't checked this under MW # # return AE.AECreateDesc('exte', struct.pack('d', x)[2:]) return AE.AECreateDesc('exte', struct.pack('d', x)) if t == StringType: return AE.AECreateDesc('TEXT', x) if t == ListType: list = AE.AECreateList('', 0) for item in x: list.AEPutDesc(0, pack(item)) return list if t == DictionaryType: record = AE.AECreateList('', 1) for key, value in x.items(): record.AEPutParamDesc(key, pack(value)) return record if t == InstanceType and hasattr(x, '__aepack__'): return x.__aepack__() return AE.AECreateDesc('TEXT', repr(x)) # Copout def unpack(desc): """Unpack an AE descriptor to a python object""" t = desc.type # print t if unpacker_coercions.has_key(t): desc = desc.AECoerceDesc(unpacker_coercions[t]) t = desc.type # This is a guess by Jack.... if t == typeAEList: l = [] for i in range(desc.AECountItems()): keyword, item = desc.AEGetNthDesc(i+1, '****') l.append(unpack(item)) return l if t == typeAERecord: d = {} for i in range(desc.AECountItems()): keyword, item = desc.AEGetNthDesc(i+1, '****') d[keyword] = unpack(item) return d if t == typeAEText: record = desc.AECoerceDesc('reco') return mkaetext(unpack(record)) if t == typeAlias: return macfs.RawAlias(desc.data) # typeAppleEvent returned as unknown if t == typeBoolean: return struct.unpack('b', desc.data)[0] if t == typeChar: return desc.data # typeColorTable coerced to typeAEList # typeComp coerced to extended # typeData returned as unknown # typeDrawingArea coerced to typeAERecord if t == typeEnumeration: return mkenum(desc.data) # typeEPS returned as unknown if t == typeExtended: # print desc, type(desc), len(desc) data = desc.data # print `data[:8]`, type(data), len(data[:8]) # print struct.unpack('=d', data[:8])[0] # print string.atoi(data), type(data), len(data) # print struct.calcsize(data) # XXX See corresponding note for pack() # return struct.unpack('d', data[:2] + data)[0] return struct.unpack('d', data[:8])[0] if t == typeFalse: return 0 # typeFixed coerced to extended # typeFloat coerced to extended if t == typeFSS: return macfs.RawFSSpec(desc.data) if t == typeInsertionLoc: record = desc.AECoerceDesc('reco') return mkinsertionloc(unpack(record)) # typeInteger equal to typeLongInteger if t == typeIntlText: script, language = struct.unpack('hh', desc.data[:4]) return baetypes.IntlText(script, language, desc.data[4:]) if t == typeIntlWritingCode: script, language = struct.unpack('hh', desc.data) return baetypes.IntlWritingCode(script, language) if t == typeKeyword: return mkkeyword(desc.data) # typeLongFloat is equal to typeFloat if t == typeLongInteger: # print t, struct.unpack('l', desc.data) return struct.unpack('l', desc.data)[0] if t == typeNull: return None if t == typeMagnitude: v = struct.unpack('l', desc.data) if v < 0: v = 0x100000000L + v return v if t == typeObjectSpecifier: from Carbon import Res # print desc, type(desc) # print desc.__members__ # print desc.data, desc.type # print unpack(desc) # getOSL = calldll.newcall(OSL.AEResolve, 'OSErr', 'InHandle', 'InShort')#, 'InString') # print 'OSL', getOSL(rdesc, 0)#, desc.data) record = desc.AECoerceDesc('reco') # print record return mkobject(unpack(record)) # typePict returned as unknown # typePixelMap coerced to typeAERecord # typePixelMapMinus returned as unknown # typeProcessSerialNumber returned as unknown if t == typeQDPoint: v, h = struct.unpack('hh', desc.data) return baetypes.QDPoint(v, h) if t == typeQDRectangle: v0, h0, v1, h1 = struct.unpack('hhhh', desc.data) return baetypes.QDRectangle(v0, h0, v1, h1) if t == typeRGBColor: r, g, b = struct.unpack('hhh', desc.data) return baetypes.RGBColor(r, g, b) # typeRotation coerced to typeAERecord # typeScrapStyles returned as unknown # typeSessionID returned as unknown if t == typeShortFloat: return struct.unpack('f', desc.data)[0] if t == typeShortInteger: # print t, desc.data # print struct.unpack('h', desc.data)[0] return struct.unpack('h', desc.data)[0] # typeSMFloat identical to typeShortFloat # typeSMInt indetical to typeShortInt # typeStyledText coerced to typeAERecord if t == typeTargetID: return mktargetid(desc.data) # typeTextStyles coerced to typeAERecord # typeTIFF returned as unknown if t == typeTrue: return 1 if t == typeType: # print t, desc.data return mktype(desc.data) # # The following are special # if t == 'rang': record = desc.AECoerceDesc('reco') return mkrange(unpack(record)) if t == 'cmpd': record = desc.AECoerceDesc('reco') return mkcomparison(unpack(record)) if t == 'logi': record = desc.AECoerceDesc('reco') return mklogical(unpack(record)) return mkunknown(desc.type, desc.data) def coerce(data, egdata): """Coerce a python object to another type using the AE coercers""" pdata = pack(data) pegdata = pack(egdata) pdata = pdata.AECoerceDesc(pegdata.type) return unpack(pdata) # # Helper routines for unpack # def mktargetid(data): sessionID = getlong(data[:4]) name = mkppcportrec(data[4:4+72]) location = mklocationnamerec(data[76:76+36]) rcvrName = mkppcportrec(data[112:112+72]) return sessionID, name, location, rcvrName def mkppcportrec(rec): namescript = getword(rec[:2]) name = getpstr(rec[2:2+33]) portkind = getword(rec[36:38]) if portkind == 1: ctor = rec[38:42] type = rec[42:46] identity = (ctor, type) else: identity = getpstr(rec[38:38+33]) return namescript, name, portkind, identity def mklocationnamerec(rec): kind = getword(rec[:2]) stuff = rec[2:] if kind == 0: stuff = None if kind == 2: stuff = getpstr(stuff) return kind, stuff def mkunknown(type, data): return baetypes.Unknown(type, data) def getpstr(s): return s[1:1+ord(s[0])] def getlong(s): return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3]) def getword(s): return (ord(s[0])<<8) | (ord(s[1])<<0) def mkkeyword(keyword): return baetypes.Keyword(keyword) def mkrange(dict): return baetypes.Range(dict['star'], dict['stop']) def mkcomparison(dict): return baetypes.Comparison(dict['obj1'], dict['relo'].enum, dict['obj2']) def mklogical(dict): return baetypes.Logical(dict['logc'], dict['term']) def mkstyledtext(dict): return baetypes.StyledText(dict['ksty'], dict['ktxt']) def mkaetext(dict): return baetypes.AEText(dict[keyAEScriptTag], dict[keyAEStyles], dict[keyAEText]) def mkinsertionloc(dict): return baetypes.InsertionLoc(dict[keyAEObject], dict[keyAEPosition]) def mkobject(dict): want = dict['want'].type form = dict['form'].enum seld = dict['seld'] fr = dict['from'] if form in ('name', 'indx', 'rang', 'test'): if want == 'text': return baetypes.Text(seld, fr) if want == 'cha ': return baetypes.Character(seld, fr) if want == 'cwor': return baetypes.Word(seld, fr) if want == 'clin': return baetypes.Line(seld, fr) if want == 'cpar': return baetypes.Paragraph(seld, fr) if want == 'cwin': return baetypes.Window(seld, fr) if want == 'docu': return baetypes.Document(seld, fr) if want == 'file': return baetypes.File(seld, fr) if want == 'cins': return baetypes.InsertionPoint(seld, fr) if want == 'prop' and form == 'prop' and baetypes.IsType(seld): return baetypes.Property(seld.type, fr) return baetypes.ObjectSpecifier(want, form, seld, fr) def _test(): """Test program. Pack and unpack various things""" objs = [ 'a string', 12, 12.0, None, ['a', 'list', 'of', 'strings'], {'key1': 'value1', 'key2':'value2'}, macfs.FSSpec(':'), macfs.FSSpec(':').NewAliasMinimal(), baetypes.Enum('enum'), baetypes.Type('type'), baetypes.Keyword('kwrd'), baetypes.Range(1, 10), baetypes.Comparison(1, '< ', 10), baetypes.Logical('not ', 1), # Cannot do StyledText # Cannot do AEText baetypes.IntlText(0, 0, 'international text'), baetypes.IntlWritingCode(0,0), baetypes.QDPoint(50,100), baetypes.QDRectangle(50,100,150,200), baetypes.RGBColor(0x7000, 0x6000, 0x5000), baetypes.Unknown('xxxx', 'unknown type data'), baetypes.Character(1), baetypes.Character(2, baetypes.Line(2)), ] for o in objs: print 'BEFORE', o, `o` print type(o) packed = pack(o) unpacked = unpack(packed) print 'AFTER ', unpacked, `unpacked` import sys sys.exit(1) if __name__ == '__main__': _test() --- NEW FILE: baetools.py --- """Tools for use in AppleEvent clients and servers. pack(x) converts a Python object to an AEDesc object unpack(desc) does the reverse packevent(event, parameters, attributes) sets params and attrs in an AEAppleEvent record unpackevent(event) returns the parameters and attributes from an AEAppleEvent record Plus... Lots of classes and routines that help representing AE objects, ranges, conditionals, logicals, etc., so you can write, e.g.: x = Character(1, Document("foobar")) and pack(x) will create an AE object reference equivalent to AppleScript's character 1 of document "foobar" Some of the stuff that appears to be exported from this module comes from other files: the pack stuff from aepack, the objects from aetypes. """ from types import * from Carbon import AE from Carbon import AppleEvents import MacOS import sys from baetypes import * from baepack import pack, unpack, coerce, AEDescType Error = 'baetools.Error' # Special code to unpack an AppleEvent (which is *not* a disguised record!) # Note by Jack: No??!? If I read the docs correctly it *is*.... aekeywords = [ 'tran', 'rtid', 'evcl', 'evid', 'addr', 'optk', 'timo', 'inte', # this attribute is read only - will be set in AESend 'esrc', # this attribute is read only 'miss', # this attribute is read only 'from' # new in 1.0.1 ] def missed(ae): try: desc = ae.AEGetAttributeDesc('miss', 'keyw') except AE.Error, msg: return None return desc.data def unpackevent(ae): parameters = {} while 1: key = missed(ae) if not key: break parameters[key] = unpack(ae.AEGetParamDesc(key, '****')) attributes = {} for key in aekeywords: try: desc = ae.AEGetAttributeDesc(key, '****') except (AE.Error, MacOS.Error), msg: if msg[0] != -1701 and msg[0] != -1704: raise sys.exc_type, sys.exc_value continue attributes[key] = unpack(desc) return parameters, attributes def packevent(ae, parameters = {}, attributes = {}): for key, value in parameters.items(): ae.AEPutParamDesc(key, pack(value)) for key, value in attributes.items(): ae.AEPutAttributeDesc(key, pack(value)) # # Support routine for automatically generated Suite interfaces # These routines are also useable for the reverse function. # def keysubst(arguments, keydict): """Replace long name keys by their 4-char counterparts, and check""" ok = keydict.values() for k in arguments.keys(): if keydict.has_key(k): v = arguments[k] del arguments[k] arguments[keydict[k]] = v elif k != '----' and k not in ok: raise TypeError, 'Unknown keyword argument: %s'%k def enumsubst(arguments, key, edict): """Substitute a single enum keyword argument, if it occurs""" if not arguments.has_key(key): return v = arguments[key] ok = edict.values() if edict.has_key(v): arguments[key] = edict[v] elif not v in ok: raise TypeError, 'Unknown enumerator: %s'%v def decodeerror(arguments): """Create the 'best' argument for a raise MacOS.Error""" errn = arguments['errn'] err_a1 = errn if arguments.has_key('errs'): err_a2 = arguments['errs'] else: err_a2 = MacOS.GetErrorString(errn) if arguments.has_key('erob'): err_a3 = arguments['erob'] else: err_a3 = None return (err_a1, err_a2, err_a3) class TalkTo: """An AE connection to an application""" def __init__(self, signature, start=0, timeout=0): """Create a communication channel with a particular application. Addressing the application is done by specifying either a 4-byte signature, an AEDesc or an object that will __aepack__ to an AEDesc. """ self.target_signature = None if type(signature) == AEDescType: self.target = signature elif type(signature) == InstanceType and hasattr(signature, '__aepack__'): self.target = signature.__aepack__() elif type(signature) == StringType and len(signature) == 4: self.target = AE.AECreateDesc(AppleEvents.typeApplSignature, signature) self.target_signature = signature else: raise TypeError, "signature should be 4-char string or AEDesc" self.send_flags = AppleEvents.kAEWaitReply self.send_priority = AppleEvents.kAENormalPriority if timeout: self.send_timeout = timeout else: self.send_timeout = AppleEvents.kAEDefaultTimeout if start: self.start() def start(self): """Start the application, if it is not running yet""" self.send_flags = AppleEvents.kAENoReply _launch(self.target_signature) def newevent(self, code, subcode, parameters = {}, attributes = {}): """Create a complete structure for an apple event""" event = AE.AECreateAppleEvent(code, subcode, self.target, AppleEvents.kAutoGenerateReturnID, AppleEvents.kAnyTransactionID) # print parameters, attributes packevent(event, parameters, attributes) return event def sendevent(self, event): """Send a pre-created appleevent, await the reply and unpack it""" reply = event.AESend(self.send_flags, self.send_priority, self.send_timeout) parameters, attributes = unpackevent(reply) return reply, parameters, attributes def send(self, code, subcode, parameters = {}, attributes = {}): """Send an appleevent given code/subcode/pars/attrs and unpack the reply""" return self.sendevent(self.newevent(code, subcode, parameters, attributes)) # # The following events are somehow "standard" and don't seem to appear in any # suite... # def activate(self): """Send 'activate' command""" self.send('misc', 'actv') def _get(self, _object, as=None, _attributes={}): """_get: get data from an object Required argument: the object Keyword argument _attributes: AppleEvent attribute dictionary Returns: the data """ _code = 'core' _subcode = 'getd' _arguments = {'----':_object} if as: _arguments['rtyp'] = mktype(as) _reply, _arguments, _attributes = self.send(_code, _subcode, _arguments, _attributes) if _arguments.has_key('errn'): raise Error, decodeerror(_arguments) if _arguments.has_key('----'): return _arguments['----'] # Tiny Finder class, for local use only class _miniFinder(TalkTo): def open(self, _object, _attributes={}, **_arguments): """open: Open the specified object(s) Required argument: list of objects to open Keyword argument _attributes: AppleEvent attribute dictionary """ _code = 'aevt' _subcode = 'odoc' if _arguments: raise TypeError, 'No optional args expected' _arguments['----'] = _object _reply, _arguments, _attributes = self.send(_code, _subcode, _arguments, _attributes) if _arguments.has_key('errn'): raise aetools.Error, aetools.decodeerror(_arguments) # XXXX Optionally decode result if _arguments.has_key('----'): return _arguments['----'] #pass _finder = _miniFinder('MACS') def _launch(appfile): """Open a file thru the finder. Specify file by name or fsspec""" _finder.open(_application_file(('ID ', appfile))) class _application_file(ComponentItem): """application file - An application's file on disk""" want = 'appf' _application_file._propdict = { } _application_file._elemdict = { } # Test program # XXXX Should test more, really... def test(): target = AE.AECreateDesc('sign', 'quil') ae = AE.AECreateAppleEvent('aevt', 'oapp', target, -1, 0) print unpackevent(ae) raw_input(":") ae = AE.AECreateAppleEvent('core', 'getd', target, -1, 0) obj = Character(2, Word(1, Document(1))) print obj print repr(obj) packevent(ae, {'----': obj}) params, attrs = unpackevent(ae) print params['----'] raw_input(":") if __name__ == '__main__': test() sys.exit(1) --- NEW FILE: baetypes.py --- """aetypes - Python objects representing various AE types.""" from Carbon.AppleEvents import * import struct from types import * import string # # convoluted, since there are cyclic dependencies between this file and # aetools_convert. # def pack(*args): from aepack import pack return apply(pack, args) def IsSubclass(cls, base): """Test whether CLASS1 is the same as or a subclass of CLASS2""" # Loop to optimize for single inheritance while 1: if cls is base: return 1 if len(cls.__bases__) <> 1: break cls = cls.__bases__[0] # Recurse to cope with multiple inheritance for c in cls.__bases__: if IsSubclass(c, base): return 1 return 0 def IsInstance(x, cls): """Test whether OBJECT is an instance of (a subclass of) CLASS""" return type(x) is InstanceType and IsSubclass(x.__class__, cls) def nice(s): """'nice' representation of an object""" if type(s) is StringType: return repr(s) else: return str(s) class Unknown: """An uninterpreted AE object""" def __init__(self, type, data): self.type = type self.data = data def __repr__(self): return "Unknown(%s, %s)" % (`self.type`, `self.data`) def __aepack__(self): return pack(self.data, self.type) class Enum: """An AE enumeration value""" def __init__(self, enum): self.enum = "%-4.4s" % str(enum) def __repr__(self): return "Enum(%s)" % `self.enum` def __str__(self): return string.strip(self.enum) def __aepack__(self): return pack(self.enum, typeEnumeration) def IsEnum(x): return IsInstance(x, Enum) def mkenum(enum): # print enum if IsEnum(enum): return enum return Enum(enum) class Boolean: """An AE boolean value""" def __init__(self, bool): if bool: self.bool = "%-4.4s" % str(typeTrue) else: self.bool = "%-4.4s" % str(typeFalse) def __repr__(self): return "Boolean(%s)" % self.bool def __str__(self): return self.bool def __aepack__(self): if self.bool == 'true': return pack('', typeTrue) else: return pack('', typeFalse) def IsBoolean(x): return IsInstance(x, Boolean) def mkboolean(bool): # print bool if IsBoolean(bool): return bool return Boolean(bool) class Type: """An AE 4-char typename object""" def __init__(self, _type): self.type = "%-4.4s" % str(_type) def __repr__(self): return "Type(%s)" % `self.type` def __str__(self): return string.strip(self.type) def __aepack__(self): # print self.type, typeType return pack(self.type, typeType) def IsType(x): return IsInstance(x, Type) def mktype(_type): # Should check for apple ID codes, will allow if IsType(_type): return _type if type(_type) <> StringType: return _type if len(_type) <> 4: return Type(eval('type' + _type)) return Type(_type) class Keyword: """An AE 4-char keyword object""" def __init__(self, keyword): self.keyword = "%-4.4s" % str(keyword) def __repr__(self): return "Keyword(%s)" % `self.keyword` def __str__(self): return string.strip(self.keyword) def __aepack__(self): return pack(self.keyword, typeKeyword) def IsKeyword(x): return IsInstance(x, Keyword) class Range: """An AE range object""" def __init__(self, start, stop): self.start = start self.stop = stop def __repr__(self): return "Range(%s, %s)" % (`self.start`, `self.stop`) def __str__(self): return "%s thru %s" % (nice(self.start), nice(self.stop)) def __aepack__(self): return pack({'star': self.start, 'stop': self.stop}, 'rang') def IsRange(x): return IsInstance(x, Range) class Comparison: """An AE Comparison""" def __init__(self, obj1, relo, obj2): self.obj1 = obj1 self.relo = "%-4.4s" % str(relo) self.obj2 = obj2 def __repr__(self): return "Comparison(%s, %s, %s)" % (`self.obj1`, `self.relo`, `self.obj2`) def __str__(self): return "%s %s %s" % (nice(self.obj1), string.strip(self.relo), nice(self.obj2)) def __aepack__(self): return pack({'obj1': self.obj1, 'relo': mkenum(self.relo), 'obj2': self.obj2}, 'cmpd') def IsComparison(x): return IsInstance(x, Comparison) class NComparison(Comparison): # The class attribute 'relo' must be set in a subclass def __init__(self, obj1, obj2): Comparison.__init__(obj1, self.relo, obj2) class Ordinal: """An AE Ordinal""" def __init__(self, ord): self.ord = ord def __repr__(self): return "baetypes.Ordinal(%s)" % `self.ord` def __str__(self): return "%s" % (string.strip(self.ord)) def __aepack__(self): return pack(self.ord, typeAbsoluteOrdinal) def IsOrdinal(x): # print 'IsOrdinal', x, IsInstance(x, Ordinal) return IsInstance(x, Ordinal) def mkOrdinal(Ord): if IsOrdinal(Ord): return Ord return Ordinal(Ord) class NOrdinal(Ordinal): # The class attribute 'abso' must be set in a subclass def __init__(self ): # print 'NOrdinal', self.abso Ordinal.__init__(self, self.abso) class Logical: """An AE logical expression object""" def __init__(self, logc, term): self.logc = "%-4.4s" % str(logc) self.term = term def __repr__(self): return "Logical(%s, %s)" % (`self.logc`, `self.term`) def __str__(self): if type(self.term) == ListType and len(self.term) == 2: return "%s %s %s" % (nice(self.term[0]), string.strip(self.logc), nice(self.term[1])) else: return "%s(%s)" % (string.strip(self.logc), nice(self.term)) def __aepack__(self): return pack({'logc': mkenum(self.logc), 'term': self.term}, 'logi') def IsLogical(x): return IsInstance(x, Logical) class StyledText: """An AE object respresenting text in a certain style""" def __init__(self, style, text): self.style = style self.text = text def __repr__(self): return "StyledText(%s, %s)" % (`self.style`, `self.text`) def __str__(self): return self.text def __aepack__(self): return pack({'ksty': self.style, 'ktxt': self.text}, 'STXT') def IsStyledText(x): return IsInstance(x, StyledText) class AEText: """An AE text object with style, script and language specified""" def __init__(self, script, style, text): self.script = script self.style = style self.text = text def __repr__(self): return "AEText(%s, %s, %s)" % (`self.script`, `self.style`, `self.text`) def __str__(self): return self.text def __aepack__(self): return pack({keyAEScriptTag: self.script, keyAEStyles: self.style, keyAEText: self.text}, typeAEText) def IsAEText(x): return IsInstance(x, AEText) class IntlText: """A text object with script and language specified""" def __init__(self, script, language, text): self.script = script self.language = language self.text = text def __repr__(self): return "IntlText(%s, %s, %s)" % (`self.script`, `self.language`, `self.text`) def __str__(self): return self.text def __aepack__(self): return pack(struct.pack('hh', self.script, self.language)+self.text, typeIntlText) def IsIntlText(x): return IsInstance(x, IntlText) class IntlWritingCode: """An object representing script and language""" def __init__(self, script, language): self.script = script self.language = language def __repr__(self): return "IntlWritingCode(%s, %s)" % (`self.script`, `self.language`) def __str__(self): return "script system %d, language %d"%(self.script, self.language) def __aepack__(self): return pack(struct.pack('hh', self.script, self.language), typeIntlWritingCode) def IsIntlWritingCode(x): return IsInstance(x, IntlWritingCode) class QDPoint: """A point""" def __init__(self, v, h): self.v = v self.h = h def __repr__(self): return "QDPoint(%s, %s)" % (`self.v`, `self.h`) def __str__(self): return "(%d, %d)"%(self.v, self.h) def __aepack__(self): return pack(struct.pack('hh', self.v, self.h), typeQDPoint) def IsQDPoint(x): return IsInstance(x, QDPoint) class QDRectangle: """A rectangle""" def __init__(self, v0, h0, v1, h1): self.v0 = v0 self.h0 = h0 self.v1 = v1 self.h1 = h1 def __repr__(self): return "QDRectangle(%s, %s, %s, %s)" % (`self.v0`, `self.h0`, `self.v1`, `self.h1`) def __str__(self): return "(%d, %d)-(%d, %d)"%(self.v0, self.h0, self.v1, self.h1) def __aepack__(self): return pack(struct.pack('hhhh', self.v0, self.h0, self.v1, self.h1), typeQDRectangle) def IsQDRectangle(x): return IsInstance(x, QDRectangle) class RGBColor: """An RGB color""" def __init__(self, r, g, b): self.r = r self.g = g self.b = b def __repr__(self): return "RGBColor(%s, %s, %s)" % (`self.r`, `self.g`, `self.b`) def __str__(self): return "0x%x red, 0x%x green, 0x%x blue"% (self.r, self.g, self.b) def __aepack__(self): return pack(struct.pack('hhh', self.r, self.g, self.b), typeRGBColor) def IsRGBColor(x): return IsInstance(x, RGBColor) class ObjectSpecifier: """A class for constructing and manipulation AE object specifiers in python. An object specifier is actually a record with four fields: key type description --- ---- ----------- 'want' type 4-char class code of thing we want, e.g. word, paragraph or property 'form' enum how we specify which 'want' thing(s) we want, e.g. by index, by range, by name, or by property specifier 'seld' any which thing(s) we want, e.g. its index, its name, or its property specifier 'from' object the object in which it is contained, or null, meaning look for it in the application Note that we don't call this class plain "Object", since that name is likely to be used by the application. """ def __init__(self, want, form, seld, fr = None): self.want = want self.form = form self.seld = seld self.fr = fr def __repr__(self): s = "ObjectSpecifier(%s, %s, %s" % (`self.want`, `self.form`, `self.seld`) if self.fr: s = s + ", %s)" % `self.fr` else: s = s + ")" return s def __aepack__(self): return pack({'want': mktype(self.want), 'form': mkenum(self.form), 'seld': self.seld, 'from': self.fr}, 'obj ') def IsObjectSpecifier(x): return IsInstance(x, ObjectSpecifier) # Backwards compatability, sigh... class Property(ObjectSpecifier): def __init__(self, which, fr = None, want='prop'): ObjectSpecifier.__init__(self, want, 'prop', mktype(which), fr) def __repr__(self): if self.fr: return "Property_r(%s, %s)" % (`self.seld.type`, `self.fr`) else: return "Property_r(%s)" % `self.seld.type` def __str__(self): if self.fr: return "Property %s of %s" % (str(self.seld), str(self.fr)) else: return "Property_s %s" % str(self.seld) class NProperty(ObjectSpecifier): # Subclasses *must* self baseclass attributes: # want is the type of this property # which is the property name of this property def __init__(self, want, form, seld, fr = None): ObjectSpecifier.__init__(self, want, form, mktype(seld), fr) class SelectableItem(ObjectSpecifier): def __init__(self, want, seld, fr = None): t = type(seld) if t == StringType: form = 'name' elif IsRange(seld): form = 'rang' elif IsComparison(seld) or IsLogical(seld): form = 'test' elif t == TupleType: # Breakout: specify both form and seld in a tuple # (if you want ID or rele or somesuch) form, seld = seld else: form = 'indx' ObjectSpecifier.__init__(self, want, form, seld, fr) class ComponentItem(SelectableItem): # Derived classes *must* set the *class attribute* 'want' to some constant # Also, dictionaries _propdict and _elemdict must be set to map property # and element names to the correct classes def __init__(self, want, which, fr = None): SelectableItem.__init__(self, want, which, fr) def __repr__(self): if not self.fr: return "%s(%s)" % (self.__class__.__name__, `self.seld`) return "%s(%s, %s)" % (self.__class__.__name__, `self.seld`, `self.fr`) def __str__(self): seld = self.seld if type(seld) == StringType: ss = repr(seld) elif IsRange(seld): start, stop = seld.start, seld.stop if type(start) == InstanceType == type(stop) and \ start.__class__ == self.__class__ == stop.__class__: ss = str(start.seld) + " thru " + str(stop.seld) else: ss = str(seld) else: ss = str(seld) s = "%s %s" % (self.__class__.__name__, ss) if self.fr: s = s + " of %s" % str(self.fr) return s # def __getattr__(self, name): # print name # if self._elemdict.has_key(name): # cls = self._elemdict[name] # return DelayedComponentItem(cls, self) # if self._propdict.has_key(name): # cls = self._propdict[name] # return cls(self) # raise AttributeError, name class DelayedComponentItem: def __init__(self, compclass, fr): self.compclass = compclass self.fr = fr def __call__(self, which): return self.compclass(which, self.fr) def __repr__(self): return "%s(???, %s)" % (self.__class__.__name__, `self.fr`) def __str__(self): return "selector for element %s of %s"%(self.__class__.__name__, str(self.fr)) template = """ class %s(ComponentItem): want = '%s' """ exec template % ("Text", 'text') exec template % ("Character", 'cha ') exec template % ("Word", 'cwor') exec template % ("Line", 'clin') exec template % ("paragraph", 'cpar') exec template % ("Window", 'cwin') exec template % ("Document", 'docu') exec template % ("File", 'file') exec template % ("InsertionPoint", 'cins') --- NEW FILE: getaete.py --- """ Produces a 3 dictionaries from application aete's to be read by PythonScript v.02 january 31, 1998 added support for inheriting suites from aeut v.03 february 16, 1998 changes to identify v.04 february 26, 1998 simplified decode v.05 23/04/98 simplified _launch """ import baetools import macpath import sys import os import MacOS import StringIO import types from MACFS import * import macfs import string from Carbon.Res import * import struct # for testing only app ='CSOm' #'ezVu'# 'nwSP'#MACS'# #Restrict the application suites to the dialect we want to use. LANG = 0 # 0 = English, 1 = French, 11 = Japanese lang = {0:'English', 1:'French', 11:'Japanese'} #The following are neaded to open the application aete kASAppleScriptSuite = 'ascr' kGetAETE = 'gdte' attributes = {} arguments = {} class AETE(baetools.TalkTo): pass def Getaete(app): try: data = openaete(app) except MacOS.Error, msg: if msg[0] == -609: _launch(app) data = openaete(app) data = decode(data['----'].data) data = compileaete(data) return data def decode(data): """Decode an aete into a python data structure""" f = StringIO.StringIO(data) aete = generic(getaete, f) return aete def simplify(item): """Recursively replace singleton tuples by their constituent item""" if type(item) is types.ListType: return map(simplify, item) elif type(item) == types.TupleType and len(item) == 2: return simplify(item[1]) else: return item ## Here follows the aete resource decoder. ## It is presented bottom-up instead of top-down because there are direct ## references to the lower-level part-decoders from the high-level part-decoders. # def getflag(f, *args): m = '' c = f.read(2) print `c` if not c: raise EOFError, 'in getflag' + str(args) for n in c: m = m + `ord(n)` def getbyte(f, *args): c = f.read(1) if not c: raise EOFError, 'in getbyte' + str(args) return ord(c) def getword(f, *args): getalign(f) s = f.read(2) if len(s) < 2: raise EOFError, 'in getword' + str(args) return (ord(s[0])<<8) | ord(s[1]) def getlong(f, *args): getalign(f) s = f.read(4) if len(s) < 4: raise EOFError, 'in getlong' + str(args) return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3]) def getostype(f, *args): getalign(f) s = f.read(4) if len(s) < 4: raise EOFError, 'in getostype' + str(args) return s def getpstr(f, *args): c = f.read(1) if len(c) < 1: raise EOFError, 'in getpstr[1]' + str(args) nbytes = ord(c) if nbytes == 0: return '' s = f.read(nbytes) if len(s) < nbytes: raise EOFError, 'in getpstr[2]' + str(args) return s def getalign(f): if f.tell() & 1: c = f.read(1) ##if c <> '\0': ## print 'align:', `c` def getlist(f, description, getitem): count = getword(f) list = [] for i in range(count): list.append(generic(getitem, f)) getalign(f) return list def alt_generic(what, f, *args): print "generic", `what`, args res = vageneric(what, f, args) print '->', `res` return res def generic(what, f, *args): if type(what) == types.FunctionType: return apply(what, (f,) + args) if type(what) == types.ListType: record = [] for thing in what: item = apply(generic, thing[:1] + (f,) + thing[1:]) record.append(item) return record return "BAD GENERIC ARGS: %s" % `what` getdata = [ (getostype, "type"), (getpstr, "description"), (getword, "flags") ] getargument = [ (getpstr, "name"), (getostype, "keyword"), (getdata, "what") ] getevent = [ (getpstr, "name"), (getpstr, "description"), (getostype, "suite code"), (getostype, "event code"), (getdata, "returns"), (getdata, "accepts"), (getlist, "optional arguments", getargument) ] getproperty = [ (getpstr, "name"), (getostype, "code"), (getdata, "what") ] getelement = [ (getostype, "type"), (getlist, "keyform", getostype) ] getclass = [ (getpstr, "name"), (getostype, "class code"), (getpstr, "description"), (getlist, "properties", getproperty), (getlist, "elements", getelement) ] getcomparison = [ (getpstr, "operator name"), (getostype, "operator ID"), (getpstr, "operator comment"), ] getenumerator = [ (getpstr, "enumerator name"), (getostype, "enumerator ID"), (getpstr, "enumerator comment") ] getenumeration = [ (getostype, "enumeration ID"), (getlist, "enumerator", getenumerator) ] getsuite = [ (getpstr, "suite name"), (getpstr, "suite description"), (getostype, "suite ID"), (getword, "suite level"), (getword, "suite version"), (getlist, "events", getevent), (getlist, "classes", getclass), (getlist, "comparisons", getcomparison), (getlist, "enumerations", getenumeration) ] getaete = [ (getbyte, "major version in BCD"), (getbyte, "minor version in BCD"), (getword, "language code"), (getword, "script code"), (getlist, "suites", getsuite) ] def compileaete(aete): """Generate dictionary for a full aete resource.""" [major, minor, language, script, suites] = aete suitedict = {} gsuites = openaeut() for gsuite in gsuites: if gsuite[0] == 'AppleScript Suite': suite = gsuite suite = compilesuite(suite) suitedict[identify(suite[0])] = suite[1:] for suite in suites: if language == LANG: suitecode = suite[2] if suite[5] == []: for gsuite in gsuites: if suitecode == gsuite[2]: suite = gsuite suite = compilesuite(suite) suitedict[identify(suite[0])] = suite[1:] suitedict = combinesuite(suitedict) return suitedict def compilesuite(suite): """Generate dictionary for a single suite""" [name, desc, code, level, version, events, classes, comps, enums] = suite eventdict ={} classdict = {} enumdict ={} for event in events: if event[6]: for ev in event[6]: ev[0] = identify(ev[:2]) eventdict[identify(event[:2])] = event[1:] for klass in classes: if klass[3]: for kl in klass[3]: kl[0] = identify(kl[:2]) classdict[identify(klass[:2])] = klass[1:] for enum in enums: enumdict[enum[0]] = enum[1] return name, eventdict, classdict, enumdict def combinesuite(suite): """Combines suite dictionaries to seperate event, class, enumeration dictionaries """ suitelist = [] eventDict ={} classDict ={} enumDict ={} for value in suite.values(): for key in value[0].keys(): val = value[0][key] eventDict[key] = val for key in value[1].keys(): val = value[1][key] if key in classDict.keys(): nval = classDict[key][2] val[2] = val[2] + nval classDict[key] = val for key in value[2].keys(): val = value[2][key] enumDict[key] = val return eventDict, classDict, enumDict illegal_ids = [ "for", "in", "from", "and", "or", "not", "print", "class", "return", "def", "name", 'data' ] def identify(str): """Turn any string into an identifier: - replace space by _ - remove ',' and '-' capitalise """ if not str[0]: if str[1] == 'c@#!': return "Every" else: return 'Any' rv = string.replace(str[0], ' ', '_') rv = string.replace(rv, '-', '') rv = string.replace(rv, ',', '') rv = string.capitalize(rv) return rv def openaete(app): """open and read the aete of the target application""" arguments['----'] = LANG _aete = AETE(app) _reply, _arguments, _attributes = _aete.send(kASAppleScriptSuite, kGetAETE, arguments, attributes) if _arguments.has_key('errn'): raise baetools.Error, baetools.decodeerror(_arguments) return _arguments def openaeut(): """Open and read a aeut file. XXXXX This has been temporarily hard coded until a Python aeut is written XXXX""" fullname = dialect rf = OpenRFPerm(fullname, 0, 1) try: UseResFile(rf) resources = [] for i in range(Count1Resources('aeut')): res = Get1IndResource('aeut', 1+i) resources.append(res) for res in resources: data = res.data data = decode(data)[4] finally: CloseResFile(rf) return data def dialect(): """find the correct Dialect file""" dialect = lang[LANG] + " Dialect" try: ##System 8 vRefNum, dirID = macfs.FindFolder(kOnSystemDisk, kScriptingAdditionsFolderType, 0) fss = macfs.FSSpec((vRefNum, dirID, '')) fss = fss.as_pathname() except macfs.error: ##Sytem 7 vRefNum, dirID = macfs.FindFolder(kOnSystemDisk, kExtensionFolderType, 0) fss = macfs.FSSpec((vRefNum, dirID, '')) fss = fss.as_pathname() fss = macpath.join(fss, "Scripting Additions") fss = macpath.join(fss, "Dialect") fss = macpath.join(fss, dialect) return fss #def openosax(): # """Open and read the aetes of osaxen in the scripting additions folder""" # # # System 7.x # aete = [] # vRefNum, dirID = macfs.FindFolder(kOnSystemDisk, kExtensionFolderType, 0) # fss = macfs.FSSpec((vRefNum, dirID, '')) # fss = fss.as_pathname() # osax = macpath.join(fss, "Scripting Additions") # for file in os.listdir(osax): # fullname = macpath.join(osax, file) # print fullname # rf = OpenRFPerm(fullname, 0, 1) # try: # UseResFile(rf) # resources = [] # for i in range(Count1Resources('aete')): # res = Get1IndResource('aete', 1+i) # resources.append(res) # for res in resources: # data = res.data # data = decode(data)[4] # finally: # CloseResFile(rf) # aete.append(data) # print data #The following should be replaced by direct access to a python 'aeut' def _launch(appfile): """Open a file thru the finder. Specify file by name or fsspec""" # from PythonScript import PyScript import baetypes _finder = AETE('MACS') parameters ={} parameters['----'] = eval("baetypes.ObjectSpecifier('%s', '%s', %s)" % ('appf', 'ID ', `appfile`)) _reply, _arguments, _attributes = _finder.send( 'aevt', 'odoc', parameters , attributes = {}) if _arguments.has_key('errn'): raise baetools.Error, baetools.decodeerror(_arguments) # XXXX Optionally decode result if _arguments.has_key('----'): return _arguments['----'] if __name__ == '__main__': # import profile # profile.run('Getaete(app)', 'Getaeteprof') Getaete(app) # openosax() # openaete('ascr') # sys.exit(1) --- NEW FILE: printaete.py --- """ Produces a human readable file of an application's aete v.02 january 29, 1998 bug fix Main() v.03 january 31, 1998 added support for inheriting suites from aeut v.04 april 16, 1998 Changed identify to match getaete """ import aetools import sys import MacOS import StringIO import types import macfs import string import macpath from Carbon.Res import * # for testing only app = 'MACS'#CSOm'#'nwSP'#'ezVu'# #Dialect file hard coded as a tempoary measure DIALECT = 'Hermit:System Folder:Scripting Additions:Dialects:English Dialect' #Restrict the application suites to the dialect we want to use. LANG = 0 # 0 = English, 1 = French, 11 = Japanese #The following are neaded to open the application aete kASAppleScriptSuite = 'ascr' kGetAETE = 'gdte' attributes = {} arguments = {} class AETE(aetools.TalkTo): pass def Main(appl): fss, ok = macfs.PromptGetFile('Application to work on', 'FNDR', 'APPL')# if not ok: return app = fss.GetCreatorType()[0] path = macpath.split(sys.argv[0])[0] appname = macpath.split(fss.as_pathname())[1] appname = appname + '.aete' appname = macpath.join(path, appname) try: data = Getaete(app) except MacOS.Error, msg: if msg[0] == -609: _launch(app) data = Getaete(app) # print data data = decode(data['----'].data) data = compileaete(data, appname) def decode(data): """Decode an aete into a python data structure""" f = StringIO.StringIO(data) aete = generic(getaete, f) aete = simplify(aete) return aete def simplify(item): """Recursively replace singleton tuples by their constituent item""" if type(item) is types.ListType: return map(simplify, item) elif type(item) == types.TupleType and len(item) == 2: return simplify(item[1]) else: return item ## Here follows the aete resource decoder. ## It is presented bottom-up instead of top-down because there are direct ## references to the lower-level part-decoders from the high-level part-decoders. # def getbyte(f, *args): c = f.read(1) if not c: raise EOFError, 'in getbyte' + str(args) return ord(c) def getword(f, *args): getalign(f) s = f.read(2) if len(s) < 2: raise EOFError, 'in getword' + str(args) return (ord(s[0])<<8) | ord(s[1]) def getlong(f, *args): getalign(f) s = f.read(4) if len(s) < 4: raise EOFError, 'in getlong' + str(args) return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3]) def getostype(f, *args): getalign(f) s = f.read(4) if len(s) < 4: raise EOFError, 'in getostype' + str(args) return s def getpstr(f, *args): c = f.read(1) if len(c) < 1: raise EOFError, 'in getpstr[1]' + str(args) nbytes = ord(c) if nbytes == 0: return '' s = f.read(nbytes) if len(s) < nbytes: raise EOFError, 'in getpstr[2]' + str(args) return s def getalign(f): if f.tell() & 1: c = f.read(1) ##if c <> '\0': ## print 'align:', `c` def getlist(f, description, getitem): count = getword(f) list = [] for i in range(count): list.append(generic(getitem, f)) getalign(f) return list def alt_generic(what, f, *args): print "generic", `what`, args res = vageneric(what, f, args) print '->', `res` return res def generic(what, f, *args): if type(what) == types.FunctionType: return apply(what, (f,) + args) if type(what) == types.ListType: record = [] for thing in what: # print thing item = apply(generic, thing[:1] + (f,) + thing[1:]) record.append((thing[1], item)) return record return "BAD GENERIC ARGS: %s" % `what` getdata = [ (getostype, "type"), (getpstr, "description"), (getword, "flags") ] getargument = [ (getpstr, "name"), (getostype, "keyword"), (getdata, "what") ] getevent = [ (getpstr, "name"), (getpstr, "description"), (getostype, "suite code"), (getostype, "event code"), (getdata, "returns"), (getdata, "accepts"), (getlist, "optional arguments", getargument) ] getproperty = [ (getpstr, "name"), (getostype, "code"), (getdata, "what") ] getelement = [ (getostype, "type"), (getlist, "keyform", getostype) ] getclass = [ (getpstr, "name"), (getostype, "class code"), (getpstr, "description"), (getlist, "properties", getproperty), (getlist, "elements", getelement) ] getcomparison = [ (getpstr, "operator name"), (getostype, "operator ID"), (getpstr, "operator comment"), ] getenumerator = [ (getpstr, "enumerator name"), (getostype, "enumerator ID"), (getpstr, "enumerator comment") ] getenumeration = [ (getostype, "enumeration ID"), (getlist, "enumerator", getenumerator) ] getsuite = [ (getpstr, "suite name"), (getpstr, "suite description"), (getostype, "suite ID"), (getword, "suite level"), (getword, "suite version"), (getlist, "events", getevent), (getlist, "classes", getclass), (getlist, "comparisons", getcomparison), (getlist, "enumerations", getenumeration) ] getaete = [ (getword, "major/minor version in BCD"), (getword, "language code"), (getword, "script code"), (getlist, "suites", getsuite) ] def compileaete(aete, appname): """Generate dictionary file for a full aete resource.""" [version, language, script, suites] = aete major, minor = divmod(version, 256) fp = open(appname, 'w') fp.write('%s:\n' % (appname)) fp.write("AETE resource version %d/%d, language %d, script %d\n" % \ (major, minor, language, script)) fp.write('\n\n') gsuites = openaeut() for suite in suites: if language == LANG: suitecode = suite[2] if suite[5] == []: for gsuite in gsuites: if suitecode == gsuite[2]: suite = gsuite [name, desc, code, level, version, events, classes, comps, enums] = suite fp.write('\n%s Suite: %s\n' % (name, desc)) fp.write('\n\tEvents:\n') for event in events: fp.write('\n\t%s: %s\n' % (identify(event[0]), event[1])) fp.write('\t\t%s: %s -- %s\n' % (identify(event[0]), event[5][1], event[5][0])) fp.write('\t\tResult: %s -- %s\n' % (event[4][1], event[4][0])) for ev in event[6]: fp.write('\t\t\t%s: %s -- %s\n' % (identify(ev[0]), ev[2][0], ev[2][1])) fp.write('\n\tClasses') for klass in classes: fp.write('\n\t%s: %s\n' % (identify(klass[0]), klass[2])) if klass[3]: if not klass[3][0][0]: continue fp.write('\t\tProperties\n') for cl in klass[3]: fp.write('\t\t\t%s: %s -- %s\n' % (identify(cl[0]), cl[2][1], cl[2][0]))#,, cl[3][3][1])) if klass[4]: fp.write('\n\t\t\tElements\n') for cl in klass[4]: fp.write('\t\t\t\t%s: %s\n' % (identify(cl[0]), cl[1])) illegal_ids = [ "for", "in", "from", "and", "or", "not", "print", "class", "return", "def", "name" ] def identify(str): """Turn any string into an identifier: - replace space by _ - prepend _ if the result is a python keyword """ rv = string.replace(str, ' ', '_') rv = string.replace(rv, '-', '') rv = string.replace(rv, ',', '') rv = string.capitalize(rv) return rv def Getaete(app): '''Read the target aete''' arguments['----'] = LANG _aete = AETE(app) _reply, _arguments, _attributes = _aete.send('ascr', 'gdte', arguments, attributes) if _arguments.has_key('errn'): raise aetools.Error, aetools.decodeerror(_arguments) return _arguments def openaeut(): """Open and read a aeut file. XXXXX This has been temporarily hard coded until a Python aeut is written XXXX""" fullname = DIALECT rf = OpenRFPerm(fullname, 0, 1) try: UseResFile(rf) resources = [] for i in range(Count1Resources('aeut')): res = Get1IndResource('aeut', 1+i) resources.append(res) for res in resources: data = res.data data = decode(data)[3] finally: CloseResFile(rf) return data #The following should be replaced by direct access to a python 'aeut' class _miniFinder(aetools.TalkTo): def open(self, _object, _attributes={}, **_arguments): """open: Open the specified object(s) Required argument: list of objects to open Keyword argument _attributes: AppleEvent attribute dictionary """ _code = 'aevt' _subcode = 'odoc' if _arguments: raise TypeError, 'No optional args expected' _arguments['----'] = _object _reply, _arguments, _attributes = self.send(_code, _subcode, _arguments, _attributes) if _arguments.has_key('errn'): raise aetools.Error, aetools.decodeerror(_arguments) # XXXX Optionally decode result if _arguments.has_key('----'): return _arguments['----'] _finder = _miniFinder('MACS') def _launch(appfile): """Open a file thru the finder. Specify file by name or fsspec""" _finder.open(_application_file(('ID ', appfile))) class _application_file(aetools.ComponentItem): """application file - An application's file on disk""" want = 'appf' _application_file._propdict = { } _application_file._elemdict = { } Main(app) sys.exit(1) --- NEW FILE: testeudora.py --- """A test program that allows us to control Eudora""" import sys import MacOS import PythonScript # The Creator signature of eudora: SIGNATURE="CSOm" TIMEOUT = 10*60*60 def main(): PythonScript.PsScript(SIGNATURE, TIMEOUT) talker = PythonScript.PyScript ev = PythonScript.PsEvents pc = PythonScript.PsClass while 1: print 'get, put, name (of first folder), list (foldernames), quit (eudora) or exit (this program) ?' line = sys.stdin.readline() try: if line[0] == 'g': print 'check' print talker(ev.Activate) print talker(ev.Connect, Checking=1) elif line[0] == 'p': print talker(ev.Connect, Sending=1) elif line[0] == 'n': id = talker(ev.Get, pc.Mail_folder("").Mailbox(1).Name()) print "It is called", id, "\n" elif line[0] == 'l': id = talker(ev.Count, pc.Mail_folder(""), Each='Mailbox') print "There are", id, "mailboxes" elif line[0] == 'q': print talker(ev.Quit) elif line[0] == 'e': break except MacOS.Error, arg: if arg[0] == -609: print 'Connection invalid, is eudora running?' else: print 'MacOS Error:', arg[1] main() From guido@python.org Fri Oct 26 14:29:37 2001 From: guido@python.org (Guido van Rossum) Date: Fri, 26 Oct 2001 09:29:37 -0400 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.12,1.13 In-Reply-To: Your message of "Fri, 26 Oct 2001 10:53:04 +0200." <20011026085305.7B061305652@bireme.oratrix.nl> References: <20011026085305.7B061305652@bireme.oratrix.nl> Message-ID: <200110261329.JAA18570@cj20424-a.reston1.va.home.com> > Eh, that was that other Oratrix guy who suggested this... You mean there's more than one of you? That's outright scary! --Guido van Rossum (home page: http://www.python.org/~guido/) From jack@oratrix.nl Fri Oct 26 14:55:16 2001 From: jack@oratrix.nl (Jack Jansen) Date: Fri, 26 Oct 2001 15:55:16 +0200 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.12,1.13 In-Reply-To: Message by Guido van Rossum , Fri, 26 Oct 2001 09:29:37 -0400 , <200110261329.JAA18570@cj20424-a.reston1.va.home.com> Message-ID: <20011026135516.EAFBF303181@snelboot.oratrix.nl> > > Eh, that was that other Oratrix guy who suggested this... > > You mean there's more than one of you? That's outright scary! You of all people shouldn't say that. Right after we'd seen "Guido van Rossum" off to the US suddenly this "Just van Rossum" turns up. And I betcha that in a couple more years the python-dev list will be infested with "Barely van Rossum", "Sort-of van Rossum" and "Almost-but-not-quite van Rossum" too! -- Jack Jansen | ++++ stop the execution of Mumia Abu-Jamal ++++ Jack.Jansen@oratrix.com | ++++ if you agree copy these lines to your sig ++++ www.cwi.nl/~jack | see http://www.xs4all.nl/~tank/spg-l/sigaction.htm From guido@python.org Fri Oct 26 15:00:50 2001 From: guido@python.org (Guido van Rossum) Date: Fri, 26 Oct 2001 10:00:50 -0400 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.12,1.13 In-Reply-To: Your message of "Fri, 26 Oct 2001 15:55:16 +0200." <20011026135516.EAFBF303181@snelboot.oratrix.nl> References: <20011026135516.EAFBF303181@snelboot.oratrix.nl> Message-ID: <200110261400.KAA18806@cj20424-a.reston1.va.home.com> > > > Eh, that was that other Oratrix guy who suggested this... > > > > You mean there's more than one of you? That's outright scary! > > You of all people shouldn't say that. Right after we'd seen "Guido > van Rossum" off to the US suddenly this "Just van Rossum" turns > up. And I betcha that in a couple more years the python-dev list > will be infested with "Barely van Rossum", "Sort-of van Rossum" and > "Almost-but-not-quite van Rossum" too! Actually, the next one's going to be called "Little van Rossum". He's due next week. I will go in hiding for about a month once he's born (actually as soon as my wife goes in labor). His nickname will be Also van Rossum. :-) --Guido van Rossum (home page: http://www.python.org/~guido/) From fdrake@acm.org Fri Oct 26 15:06:19 2001 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Fri, 26 Oct 2001 10:06:19 -0400 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.12,1.13 In-Reply-To: <200110261400.KAA18806@cj20424-a.reston1.va.home.com> References: <20011026135516.EAFBF303181@snelboot.oratrix.nl> <200110261400.KAA18806@cj20424-a.reston1.va.home.com> Message-ID: <15321.28123.358455.264700@grendel.zope.com> Guido van Rossum writes: > Actually, the next one's going to be called "Little van Rossum". > He's due next week. I will go in hiding for about a month once he's > born (actually as soon as my wife goes in labor). His nickname will > be Also van Rossum. :-) Some of us, of course, will call him Finally van Rossum! -Fred -- Fred L. Drake, Jr. PythonLabs at Zope Corporation From fdrake@users.sourceforge.net Fri Oct 26 15:16:25 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 07:16:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/perl l2hinit.perl,1.56,1.57 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory usw-pr-cvs1:/tmp/cvs-serv22426/perl Modified Files: l2hinit.perl Log Message: Clean up the tables of child links generated by stock LaTeX2HTML so we get consistent (lack of) vertical space between sections, and remove some of the unnecessary cruft that was added in (finally we get to *remove* something that got generated!). Index: l2hinit.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/l2hinit.perl,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -d -r1.56 -r1.57 *** l2hinit.perl 2001/10/22 16:57:49 1.56 --- l2hinit.perl 2001/10/26 14:16:23 1.57 *************** *** 183,186 **** --- 183,194 ---- } + sub add_child_links { + my $toc = add_real_child_links(@_); + $toc =~ s|\s*||g; + $toc =~ s/ NAME=\"tex2html\d+\"\s*href=/ href=/gi; + $toc =~ s|(\s*
    )?||gi; + return $toc; + } + sub get_version_text { if ($PACKAGE_VERSION ne '' && $t_date) { From bwarsaw@users.sourceforge.net Fri Oct 26 15:36:24 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 26 Oct 2001 07:36:24 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0264.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv3243 Modified Files: pep-0264.txt Log Message: Mark as Final Index: pep-0264.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0264.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pep-0264.txt 2001/10/26 08:05:48 1.6 --- pep-0264.txt 2001/10/26 14:36:22 1.7 *************** *** 1,7 **** PEP: 264 ! Title: Future statements in simulated shells ! Version: 4 Author: Michael Hudson ! Status: Accepted Type: Standards Track Requires: 236 --- 1,8 ---- PEP: 264 ! Title: Future statements in simulated shells ! Version: $Revision$ ! Last-Modified: $Date$ Author: Michael Hudson ! Status: Final Type: Standards Track Requires: 236 *************** *** 10,13 **** --- 11,15 ---- Post-History: 30-Jul-2001 + Abstract *************** *** 130,133 **** --- 132,136 ---- This document has been placed in the public domain. + From bwarsaw@users.sourceforge.net Fri Oct 26 15:37:09 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 26 Oct 2001 07:37:09 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.142,1.143 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv3760 Modified Files: pep-0000.txt Log Message: Mark PEP 264 as Final Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.142 retrieving revision 1.143 diff -C2 -d -r1.142 -r1.143 *** pep-0000.txt 2001/10/25 22:03:18 1.142 --- pep-0000.txt 2001/10/26 14:37:06 1.143 *************** *** 115,119 **** SF 260 Simplify xrange() van Rossum S 261 Support for "wide" Unicode characters Prescod ! SA 264 Future statements in simulated shells Hudson Empty PEPs (or containing only an abstract) --- 115,119 ---- SF 260 Simplify xrange() van Rossum S 261 Support for "wide" Unicode characters Prescod ! SF 264 Future statements in simulated shells Hudson Empty PEPs (or containing only an abstract) *************** *** 218,222 **** S 262 Database of Installed Python Packages Kuchling S 263 Defining Python Source Code Encodings Lemburg ! SA 264 Future statements in simulated shells Hudson S 265 Sorting Dictionaries by Value Griffin S 266 Optimizing Global Variable/Attribute Access Montanaro --- 218,222 ---- S 262 Database of Installed Python Packages Kuchling S 263 Defining Python Source Code Encodings Lemburg ! SF 264 Future statements in simulated shells Hudson S 265 Sorting Dictionaries by Value Griffin S 266 Optimizing Global Variable/Attribute Access Montanaro From akuchling@users.sourceforge.net Fri Oct 26 15:54:18 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Fri, 26 Oct 2001 07:54:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc Makefile.pre.in,1.21,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv15642 Removed Files: Makefile.pre.in Log Message: Delete Makefile.pre.in (BDFL pronouncement) --- Makefile.pre.in DELETED --- From gvanrossum@users.sourceforge.net Fri Oct 26 15:56:08 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 26 Oct 2001 07:56:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.300,1.301 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv17656 Modified Files: NEWS Log Message: Some news. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.300 retrieving revision 1.301 diff -C2 -d -r1.300 -r1.301 *** NEWS 2001/10/26 05:06:50 1.300 --- NEWS 2001/10/26 14:56:06 1.301 *************** *** 5,8 **** --- 5,12 ---- Type/class unification and new-style classes + - Assignment to object.__dict__ is now possible, for objects that are + instances of new-style classes that have a __dict__ (unless the base + class forbids it). + - dictionary() now accepts an iterable object producing 2-sequences. For example, dictionary(d.items()) == d for any dictionary d. The *************** *** 16,22 **** Core and builtins Extension modules ! - Various bugfixes to the curses module. Library --- 20,34 ---- Core and builtins + - Clarified the error messages for unsupported operands to an operator + (like 1 + ''). + Extension modules ! - The socket module defines a new method for socket objects, ! sendall(). This is like send() but may make multiple calls to ! send() until all data has been sent. ! ! - Various bugfixes to the curses module. There is now a test suite ! for the curses module (you have to run it manually). Library From gvanrossum@users.sourceforge.net Fri Oct 26 16:01:18 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 26 Oct 2001 08:01:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc README,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv21206 Modified Files: README Log Message: Updated this README to reality. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/README,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** README 2001/08/19 21:18:04 1.15 --- README 2001/10/26 15:01:16 1.16 *************** *** 2,8 **** ======================== ! This directory contains files that wouldn't fit in elsewhere, in ! particular the UNIX manual page, an Emacs mode for Python source code, ! and a list of Frequently Asked Questions (and their answers). Some documents are only of historic importance. --- 2,6 ---- ======================== ! This directory contains files that wouldn't fit in elsewhere. Some documents are only of historic importance. *************** *** 11,23 **** ACKS Acknowledgements ! AIX-NOTES Notes for building Python on AIX (all new!) ! BLURB A quick description of Python for newcomers ! BLURB.LUTZ A testimonial from a converted Tcl/Perl hacker :-) ! BLURB.WINDOWS First announcement of Python for Windows HISTORY News from previous releases -- oldest last HPUX-NOTES Notes about dynamic loading under HP-UX - HYPE More hype about Python - Makefile Used for administrative chores like cleaning up - Makefile.pre.in Generic Makefile template for building extensions NEWS News for this release PURIFY.README Information for Purify users --- 9,17 ---- ACKS Acknowledgements ! AIX-NOTES Notes for building Python on AIX ! BeOS-NOTES Notes for building on BeOS ! BeOS-setup.py setup.py replacement for BeOS, see BeOS-NOTES HISTORY News from previous releases -- oldest last HPUX-NOTES Notes about dynamic loading under HP-UX NEWS News for this release PURIFY.README Information for Purify users *************** *** 25,38 **** README The file you're reading now RFD Request For Discussion about a Python newsgroup cheatsheet Quick summary of Python by Ken Manheimer - comparisons (Old) comparisons to some other languages - editline-fix A news article on how to fix R$'s editline for Python - faq2html FAQ to HTML converter by Ka-Ping Yee find_recursionlimit.py Script to find a value for sys.maxrecursionlimit ! fixfuncptrs.sh Shell script to fix function pointer initializers indent.pro GNU indent profile approximating my C style python-mode.el Emacs mode for editing Python programs python.man UNIX man page for the python interpreter - renumber.py Script to renumber the sections in the FAQ setuid-prog.c C helper program for set-uid Python scripts unicode.txt Marc-Andre Lemburg's specification of the Unicode API --- 19,29 ---- README The file you're reading now RFD Request For Discussion about a Python newsgroup + RPM (Old) tools to build RPMs cheatsheet Quick summary of Python by Ken Manheimer find_recursionlimit.py Script to find a value for sys.maxrecursionlimit ! gdbinit Handy stuff to put in your .gdbinit file, if you use gdb indent.pro GNU indent profile approximating my C style python-mode.el Emacs mode for editing Python programs python.man UNIX man page for the python interpreter setuid-prog.c C helper program for set-uid Python scripts unicode.txt Marc-Andre Lemburg's specification of the Unicode API From fdrake@users.sourceforge.net Fri Oct 26 16:04:36 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 08:04:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.92,1.93 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv23541/lib Modified Files: libfuncs.tex Log Message: Some style changes and typo fixes. Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.92 retrieving revision 1.93 diff -C2 -d -r1.92 -r1.93 *** libfuncs.tex 2001/10/26 05:06:50 1.92 --- libfuncs.tex 2001/10/26 15:04:33 1.93 *************** *** 190,199 **** For example, these all return a dictionary equal to \code{\{1: 2, 2: 3\}}: ! \code{dictionary(\{1: 2, 2: 3\})}, ! \code{dictionary(\{1: 2, 2: 3\}.items()}, ! \code{dictionary(\{1: 2, 2: 3\}.iteritems()}, ! \code{dictionary(zip((1, 2), (2, 3)))}, ! \code{dictionary([[2, 3], [1, 2]])}, and ! \code{dictionary([(i-1, i) for i in (2, 3)])}. \end{funcdesc} --- 190,202 ---- For example, these all return a dictionary equal to \code{\{1: 2, 2: 3\}}: ! ! \begin{itemize} ! \item \code{dictionary(\{1: 2, 2: 3\})} ! \item \code{dictionary(\{1: 2, 2: 3\}.items())} ! \item \code{dictionary(\{1: 2, 2: 3\}.iteritems())} ! \item \code{dictionary(zip((1, 2), (2, 3)))} ! \item \code{dictionary([[2, 3], [1, 2]])} ! \item \code{dictionary([(i-1, i) for i in (2, 3)])} ! \end{itemize} \end{funcdesc} From barry@zope.com Fri Oct 26 16:07:46 2001 From: barry@zope.com (Barry A. Warsaw) Date: Fri, 26 Oct 2001 11:07:46 -0400 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.12,1.13 References: <200110261329.JAA18570@cj20424-a.reston1.va.home.com> <20011026135516.EAFBF303181@snelboot.oratrix.nl> Message-ID: <15321.31810.281555.439877@anthem.wooz.org> >>>>> "JJ" == Jack Jansen writes: JJ> You of all people shouldn't say that. Right after we'd seen JJ> "Guido van Rossum" off to the US suddenly this "Just van JJ> Rossum" turns up. And I betcha that in a couple more years the JJ> python-dev list will be infested with "Barely van Rossum", JJ> "Sort-of van Rossum" and "Almost-but-not-quite van Rossum" JJ> too! I've also heard rumors of a Barry van Rossum. From guido@python.org Fri Oct 26 16:09:07 2001 From: guido@python.org (Guido van Rossum) Date: Fri, 26 Oct 2001 11:09:07 -0400 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.12,1.13 In-Reply-To: Your message of "Fri, 26 Oct 2001 11:07:46 EDT." <15321.31810.281555.439877@anthem.wooz.org> References: <200110261329.JAA18570@cj20424-a.reston1.va.home.com> <20011026135516.EAFBF303181@snelboot.oratrix.nl> <15321.31810.281555.439877@anthem.wooz.org> Message-ID: <200110261509.LAA19301@cj20424-a.reston1.va.home.com> > I've also heard rumors of a Barry van Rossum. That must've been when you had a delirium. --Guido van Rossum (home page: http://www.python.org/~guido/) From fredrik@pythonware.com Fri Oct 26 17:00:01 2001 From: fredrik@pythonware.com (Fredrik Lundh) Date: Fri, 26 Oct 2001 18:00:01 +0200 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.12,1.13 References: <200110261329.JAA18570@cj20424-a.reston1.va.home.com> <20011026135516.EAFBF303181@snelboot.oratrix.nl> <15321.31810.281555.439877@anthem.wooz.org> <200110261509.LAA19301@cj20424-a.reston1.va.home.com> Message-ID: <034301c15e37$45e5e0f0$0900a8c0@spiff> > > I've also heard rumors of a Barry van Rossum. > > That must've been when you had a delirium. http://www.communisat.com/sky99/skydive.htm "photos by barry van rossum" http://freeweb.pdq.net/skydivehou/Fbarry.htm "website designed by barry van rossum" (judging from the website design, he's not a real van rossum ;-) From barry@zope.com Fri Oct 26 17:02:59 2001 From: barry@zope.com (Barry A. Warsaw) Date: Fri, 26 Oct 2001 12:02:59 -0400 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.12,1.13 References: <200110261329.JAA18570@cj20424-a.reston1.va.home.com> <20011026135516.EAFBF303181@snelboot.oratrix.nl> <15321.31810.281555.439877@anthem.wooz.org> <200110261509.LAA19301@cj20424-a.reston1.va.home.com> <034301c15e37$45e5e0f0$0900a8c0@spiff> Message-ID: <15321.35123.591468.966279@anthem.wooz.org> Oh yeah, skydiving. That's me alright. Right up my alley. From fdrake@users.sourceforge.net Fri Oct 26 17:21:34 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 09:21:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.87,2.88 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv3454/Objects Modified Files: abstract.c Log Message: Added two new functions to conveniently call functions/methods from C. PyObject_CallFunctionObArgs() and PyObject_CallMethodObArgs() have the advantage that no format strings need to be parsed. The CallMethod variant also avoids creating a new string object in order to retrieve a method from an object as well. Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.87 retrieving revision 2.88 diff -C2 -d -r2.87 -r2.88 *** abstract.c 2001/10/26 05:06:50 2.87 --- abstract.c 2001/10/26 16:21:32 2.88 *************** *** 1759,1762 **** --- 1759,1838 ---- + static PyObject * + obargs_mktuple(va_list va) + { + int i, n = 0; + va_list countva; + PyObject *result, *tmp; + + #ifdef VA_LIST_IS_ARRAY + memcpy(countva, va, sizeof(va_list)); + #else + countva = va; + #endif + + while (((PyObject *)va_arg(countva, PyObject *)) != NULL) + ++n; + result = PyTuple_New(n); + if (result != NULL && n > 0) { + for (i = 0; i < n; ++i) { + tmp = (PyObject *)va_arg(va, PyObject *); + PyTuple_SET_ITEM(result, i, tmp); + Py_INCREF(tmp); + } + } + return result; + } + + PyObject * + PyObject_CallMethodObArgs(PyObject *callable, PyObject *name, ...) + { + PyObject *args, *tmp; + va_list vargs; + + if (callable == NULL || name == NULL) + return null_error(); + + callable = PyObject_GetAttr(callable, name); + if (callable == NULL) + return NULL; + + /* count the args */ + va_start(vargs, name); + args = obargs_mktuple(vargs); + va_end(vargs); + if (args == NULL) { + Py_DECREF(callable); + return NULL; + } + tmp = PyObject_Call(callable, args, NULL); + Py_DECREF(args); + Py_DECREF(callable); + + return tmp; + } + + PyObject * + PyObject_CallFunctionObArgs(PyObject *callable, ...) + { + PyObject *args, *tmp; + va_list vargs; + + if (callable == NULL) + return null_error(); + + /* count the args */ + va_start(vargs, callable); + args = obargs_mktuple(vargs); + va_end(vargs); + if (args == NULL) + return NULL; + tmp = PyObject_Call(callable, args, NULL); + Py_DECREF(args); + + return tmp; + } + + /* isinstance(), issubclass() */ From fdrake@users.sourceforge.net Fri Oct 26 17:21:34 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 09:21:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include abstract.h,2.38,2.39 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv3454/Include Modified Files: abstract.h Log Message: Added two new functions to conveniently call functions/methods from C. PyObject_CallFunctionObArgs() and PyObject_CallMethodObArgs() have the advantage that no format strings need to be parsed. The CallMethod variant also avoids creating a new string object in order to retrieve a method from an object as well. Index: abstract.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/abstract.h,v retrieving revision 2.38 retrieving revision 2.39 diff -C2 -d -r2.38 -r2.39 *** abstract.h 2001/10/26 05:06:50 2.38 --- abstract.h 2001/10/26 16:21:32 2.39 *************** *** 300,304 **** /* - Call a callable Python object, callable_object, with arguments and keywords arguments. The 'args' argument can not be --- 300,303 ---- *************** *** 311,315 **** /* - Call a callable Python object, callable_object, with arguments given by the tuple, args. If no arguments are --- 310,313 ---- *************** *** 344,352 **** success, or NULL on failure. This is the equivalent of the Python expression: o.method(args). - Note that Special method names, such as "__add__", - "__getitem__", and so on are not supported. The specific - abstract-object routines for these must be used. */ --- 342,370 ---- success, or NULL on failure. This is the equivalent of the Python expression: o.method(args). + */ + DL_IMPORT(PyObject *) PyObject_CallFunctionObArgs(PyObject *callable, + ...); + + /* + Call a callable Python object, callable_object, with a + variable number of C arguments. The C arguments are provided + as PyObject * values; 'n' specifies the number of arguments + present. Returns the result of the call on success, or NULL + on failure. This is the equivalent of the Python expression: + apply(o,args). + */ + + + DL_IMPORT(PyObject *) PyObject_CallMethodObArgs(PyObject *o, + PyObject *m, ...); + + /* + Call the method named m of object o with a variable number of + C arguments. The C arguments are provided as PyObject * values; + 'n' specifies the number of arguments present. Returns the + result of the call on success, or NULL on failure. This is the + equivalent of the Python expression: o.method(args). */ From fdrake@users.sourceforge.net Fri Oct 26 17:29:24 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 09:29:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api refcounts.dat,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv8428/api Modified Files: refcounts.dat Log Message: Added refcount data for PyObject_CallFunctionObArgs() and PyObject_CallMethodObArgs(). Index: refcounts.dat =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/refcounts.dat,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** refcounts.dat 2001/09/24 15:29:47 1.33 --- refcounts.dat 2001/10/26 16:29:22 1.34 *************** *** 720,723 **** --- 720,727 ---- PyObject_CallFunction::...:: + PyObject_CallFunctionObArgs:PyObject*::+1: + PyObject_CallFunctionObArgs:PyObject*:callable:0: + PyObject_CallFunctionObArgs::...:: + PyObject_CallMethod:PyObject*::+1: PyObject_CallMethod:PyObject*:o:0: *************** *** 725,728 **** --- 729,737 ---- PyObject_CallMethod:char*:format:: PyObject_CallMethod::...:: + + PyObject_CallMethodObArgs:PyObject*::+1: + PyObject_CallMethodObArgs:PyObject*:o:0: + PyObject_CallMethodObArgs:char*:name:: + PyObject_CallMethodObArgs::...:: PyObject_CallObject:PyObject*::+1: From fdrake@users.sourceforge.net Fri Oct 26 17:38:41 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 09:38:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api abstract.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv16090/api Modified Files: abstract.tex Log Message: Added docs for PyObject_CallFunctionObArgs() and PyObject_CallMethodObArgs(). Minor cleanups & markup consistency fixes. Index: abstract.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/abstract.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** abstract.tex 2001/10/26 05:06:49 1.2 --- abstract.tex 2001/10/26 16:38:38 1.3 *************** *** 184,197 **** \end{cfuncdesc} ! \begin{cfuncdesc}{PyObject*}{PyObject_CallFunction}{PyObject *callable_object, ! char *format, ...} ! Call a callable Python object \var{callable_object}, with a variable number of C arguments. The C arguments are described using a \cfunction{Py_BuildValue()} style format string. The format may be \NULL, indicating that no arguments are provided. Returns the result of the call on success, or \NULL{} on failure. This is the ! equivalent of the Python expression ! \samp{apply(\var{callable_object}\var{args})} or ! \samp{\var{callable_object}(*\var{args})}. \bifuncindex{apply} \end{cfuncdesc} --- 184,196 ---- \end{cfuncdesc} ! \begin{cfuncdesc}{PyObject*}{PyObject_CallFunction}{PyObject *callable, ! char *format, \moreargs} ! Call a callable Python object \var{callable}, with a variable number of C arguments. The C arguments are described using a \cfunction{Py_BuildValue()} style format string. The format may be \NULL, indicating that no arguments are provided. Returns the result of the call on success, or \NULL{} on failure. This is the ! equivalent of the Python expression \samp{apply(\var{callable}, ! \var{args})} or \samp{\var{callable}(*\var{args})}. \bifuncindex{apply} \end{cfuncdesc} *************** *** 199,203 **** \begin{cfuncdesc}{PyObject*}{PyObject_CallMethod}{PyObject *o, ! char *method, char *format, ...} Call the method named \var{m} of object \var{o} with a variable number of C arguments. The C arguments are described by a --- 198,203 ---- \begin{cfuncdesc}{PyObject*}{PyObject_CallMethod}{PyObject *o, ! char *method, char *format, ! \moreargs} Call the method named \var{m} of object \var{o} with a variable number of C arguments. The C arguments are described by a *************** *** 205,212 **** indicating that no arguments are provided. Returns the result of the call on success, or \NULL{} on failure. This is the equivalent of ! the Python expression \samp{\var{o}.\var{method}(\var{args})}. Note ! that special method names, such as \method{__add__()}, ! \method{__getitem__()}, and so on are not supported. The specific ! abstract-object routines for these must be used. \end{cfuncdesc} --- 205,233 ---- indicating that no arguments are provided. Returns the result of the call on success, or \NULL{} on failure. This is the equivalent of ! the Python expression \samp{\var{o}.\var{method}(\var{args})}. ! \end{cfuncdesc} ! ! ! \begin{cfuncdesc}{PyObject*}{PyObject_CallFunctionObArgs}{PyObject *callable, ! \moreargs, ! \code{NULL}} ! Call a callable Python object \var{callable}, with a variable ! number of \ctype{PyObject*} arguments. The arguments are provided ! as a variable number of parameters followed by \NULL. ! Returns the result of the call on success, or \NULL{} on failure. ! \versionadded{2.2} ! \end{cfuncdesc} ! ! ! \begin{cfuncdesc}{PyObject*}{PyObject_CallMethodObArgs}{PyObject *o, ! PyObject *name, ! \moreargs, ! \code{NULL}} ! Calls a method of the object \var{o}, where the name of the method ! is given as a Python string object in \var{name}. It is called with ! a variable number of \ctype{PyObject*} arguments. The arguments are ! provided as a variable number of parameters followed by \NULL. ! Returns the result of the call on success, or \NULL{} on failure. ! \versionadded{2.2} \end{cfuncdesc} From fdrake@users.sourceforge.net Fri Oct 26 18:40:24 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 10:40:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libweakref.tex,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv6801/lib Modified Files: libweakref.tex Log Message: Many, many small fixes and improvements, most suggested by Detlef Lannert. Index: libweakref.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libweakref.tex,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** libweakref.tex 2001/10/26 11:27:54 1.14 --- libweakref.tex 2001/10/26 17:40:22 1.15 *************** *** 15,18 **** --- 15,21 ---- \dfn{weak references} to objects. + In the discussion which follows, the term \dfn{referent} means the + object which is referred to by a weak reference. + XXX --- need to say more here! *************** *** 25,34 **** \begin{funcdesc}{ref}{object\optional{, callback}} ! Return a weak reference to \var{object}. If \var{callback} is provided, it will be called when the object is about to be finalized; the weak reference object will be passed as the only parameter to the callback; the referent will no longer be available. - The original object can be retrieved by calling the reference - object, if the referent is still alive. It is allowable for many weak references to be constructed for the --- 28,38 ---- \begin{funcdesc}{ref}{object\optional{, callback}} ! Return a weak reference to \var{object}. The original object can be ! retrieved by calling the reference object if the referent is still ! alive; if the referent is no longer alive, calling the reference ! object will cause \code{None} to be returned. If \var{callback} is provided, it will be called when the object is about to be finalized; the weak reference object will be passed as the only parameter to the callback; the referent will no longer be available. It is allowable for many weak references to be constructed for the *************** *** 49,56 **** Weak references support tests for equality, but not ordering. If ! the \var{object} is still alive, two references are equal if the ! objects are equal (regardless of the \var{callback}). If ! \var{object} has been deleted, they are equal only if the references ! being compared are the same reference object. \end{funcdesc} --- 53,61 ---- Weak references support tests for equality, but not ordering. If ! the referents are still alive, two references have the same ! equalality relationship as their referents (regardless of the ! \var{callback}). If either referent has been deleted, the ! references are equal only if the reference objects are the same ! object. \end{funcdesc} *************** *** 90,94 **** Mapping class that references values weakly. Entries in the dictionary will be discarded when no strong reference to the value ! exists anymore. \end{classdesc} --- 95,99 ---- Mapping class that references values weakly. Entries in the dictionary will be discarded when no strong reference to the value ! exists any more. \end{classdesc} *************** *** 159,163 **** \begin{verbatim} ! o = ref() if o is None: # referent has been garbage collected --- 164,169 ---- \begin{verbatim} ! # r is a weak reference object ! o = r() if o is None: # referent has been garbage collected *************** *** 170,174 **** Using a separate test for ``liveness'' creates race conditions in threaded applications; another thread can cause a weak reference to ! become invalidated before the \method{get()} method is called; the idiom shown above is safe in threaded applications as well as single-threaded applications. --- 176,180 ---- Using a separate test for ``liveness'' creates race conditions in threaded applications; another thread can cause a weak reference to ! become invalidated before the weak reference is called; the idiom shown above is safe in threaded applications as well as single-threaded applications. *************** *** 190,197 **** def remember(obj): ! _id2obj_dict[id(obj)] = obj ! def id2obj(id): ! return _id2obj_dict(id) \end{verbatim} --- 196,205 ---- def remember(obj): ! oid = id(obj) ! _id2obj_dict[oid] = obj ! return oid ! def id2obj(oid): ! return _id2obj_dict[oid] \end{verbatim} *************** *** 206,210 **** For an object to be weakly referencable, the extension must include a ! \ctype{PyObject *} field in the instance structure for the use of the weak reference mechanism; it must be initialized to \NULL{} by the object's constructor. It must also set the \member{tp_weaklistoffset} --- 214,218 ---- For an object to be weakly referencable, the extension must include a ! \ctype{PyObject*} field in the instance structure for the use of the weak reference mechanism; it must be initialized to \NULL{} by the object's constructor. It must also set the \member{tp_weaklistoffset} *************** *** 237,241 **** The only further addition is that the destructor needs to call the weak reference manager to clear any weak references. This should be ! done before any other parts of the destruction have occurred: \begin{verbatim} --- 245,250 ---- The only further addition is that the destructor needs to call the weak reference manager to clear any weak references. This should be ! done before any other parts of the destruction have occurred, but is ! only required if the weak reference list is non-\NULL: \begin{verbatim} *************** *** 243,251 **** instance_dealloc(PyInstanceObject *inst) { ! /* Allocate tempories if needed, but do not begin destruction just yet. */ ! PyObject_ClearWeakRefs((PyObject *) inst); /* Proceed with object destruction normally. */ --- 252,261 ---- instance_dealloc(PyInstanceObject *inst) { ! /* Allocate temporaries if needed, but do not begin destruction just yet. */ ! if (inst->in_weakreflist != NULL) ! PyObject_ClearWeakRefs((PyObject *) inst); /* Proceed with object destruction normally. */ From fdrake@users.sourceforge.net Fri Oct 26 18:56:53 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 10:56:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects classobject.c,2.153,2.154 funcobject.c,2.46,2.47 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12022 Modified Files: classobject.c funcobject.c Log Message: Be smarter about clearing the weakref lists for instances, instance methods, and functions: we only need to call PyObject_ClearWeakRefs() if the weakref list is non-NULL. Since these objects are common but weakrefs are still unusual, saving the call at deallocation time makes a lot of sense. Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.153 retrieving revision 2.154 diff -C2 -d -r2.153 -r2.154 *** classobject.c 2001/10/22 02:00:09 2.153 --- classobject.c 2001/10/26 17:56:51 2.154 *************** *** 586,590 **** #endif _PyObject_GC_UNTRACK(inst); ! PyObject_ClearWeakRefs((PyObject *) inst); /* Temporarily resurrect the object. */ --- 586,591 ---- #endif _PyObject_GC_UNTRACK(inst); ! if (inst->in_weakreflist != NULL) ! PyObject_ClearWeakRefs((PyObject *) inst); /* Temporarily resurrect the object. */ *************** *** 2072,2076 **** { _PyObject_GC_UNTRACK(im); ! PyObject_ClearWeakRefs((PyObject *)im); Py_DECREF(im->im_func); Py_XDECREF(im->im_self); --- 2073,2078 ---- { _PyObject_GC_UNTRACK(im); ! if (im->im_weakreflist != NULL) ! PyObject_ClearWeakRefs((PyObject *)im); Py_DECREF(im->im_func); Py_XDECREF(im->im_self); Index: funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.46 retrieving revision 2.47 diff -C2 -d -r2.46 -r2.47 *** funcobject.c 2001/10/05 20:51:38 2.46 --- funcobject.c 2001/10/26 17:56:51 2.47 *************** *** 271,275 **** { _PyObject_GC_UNTRACK(op); ! PyObject_ClearWeakRefs((PyObject *) op); Py_DECREF(op->func_code); Py_DECREF(op->func_globals); --- 271,276 ---- { _PyObject_GC_UNTRACK(op); ! if (op->func_weakreflist != NULL) ! PyObject_ClearWeakRefs((PyObject *) op); Py_DECREF(op->func_code); Py_DECREF(op->func_globals); From fdrake@users.sourceforge.net Fri Oct 26 19:02:30 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 11:02:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sgmllib.py,1.38,1.39 markupbase.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv13570 Modified Files: sgmllib.py markupbase.py Log Message: Re-arrange things and remove some unused variables/imports to keep pychecker happy. (This does not cover everything it complained about, though.) Index: sgmllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sgmllib.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** sgmllib.py 2001/09/24 20:15:51 1.38 --- sgmllib.py 2001/10/26 18:02:28 1.39 *************** *** 424,428 **** def unknown_charref(self, ref): pass def unknown_entityref(self, ref): pass - def unknown_decl(self, data): pass --- 424,427 ---- Index: markupbase.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/markupbase.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** markupbase.py 2001/10/13 15:59:47 1.3 --- markupbase.py 2001/10/26 18:02:28 1.4 *************** *** 14,17 **** --- 14,26 ---- by the SGML/HTML and XHTML parsers.""" + def __init__(self): + if self.__class__ is ParserBase: + raise RuntimeError( + "markupbase.ParserBase must be subclassed") + + def error(self, message): + raise NotImplementedError( + "subclasses of ParserBase must override error()") + def reset(self): self.lineno = 1 *************** *** 47,51 **** # declaration (""). rawdata = self.rawdata - import sys j = i + 2 assert rawdata[i:j] == "' if '>' in rawdata[j:]: return string.find(rawdata, ">", j) + 1 --- 171,179 ---- # Internal -- scan past ' + rawdata = self.rawdata if '>' in rawdata[j:]: return string.find(rawdata, ">", j) + 1 *************** *** 305,306 **** --- 312,317 ---- self.updatepos(declstartpos, i) self.error("expected name token") + + # To be overridden -- handlers for unknown objects + def unknown_decl(self, data): + pass From bwarsaw@users.sourceforge.net Fri Oct 26 19:07:47 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 26 Oct 2001 11:07:47 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0251.txt,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv15207 Modified Files: pep-0251.txt Log Message: 2.2b1 was released. Index: pep-0251.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0251.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pep-0251.txt 2001/10/18 17:50:46 1.6 --- pep-0251.txt 2001/10/26 18:07:45 1.7 *************** *** 30,34 **** 12-Dec-2001: 2.2c1 (release candidate) 14-Nov-2001: 2.2b2 ! 19-Oct-2001: 2.2b1 28-Sep-2001: 2.2a4 [Released] 7-Sep-1001: 2.2a3 [Released] --- 30,34 ---- 12-Dec-2001: 2.2c1 (release candidate) 14-Nov-2001: 2.2b2 ! 19-Oct-2001: 2.2b1 [Released] 28-Sep-2001: 2.2a4 [Released] 7-Sep-1001: 2.2a3 [Released] From fdrake@users.sourceforge.net Fri Oct 26 19:37:29 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 11:37:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libuserdict.tex,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv24531/lib Modified Files: libuserdict.tex Log Message: Add notes pointing out that these classes are kept for backward compatibility and suggeest that new code that does not require compatibility with older Python versions subclass dictionary, list, or str. Index: libuserdict.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libuserdict.tex,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** libuserdict.tex 2000/10/10 22:00:03 1.19 --- libuserdict.tex 2001/10/26 18:37:27 1.20 *************** *** 5,8 **** --- 5,13 ---- \modulesynopsis{Class wrapper for dictionary objects.} + \note{This module is available for backward compatibility only. If + you are writing code that does not need to work with versions of + Python earlier than Python 2.2, please consider subclassing directly + from the built-in \class{dictionary} type.} + This module defines a class that acts as a wrapper around dictionary objects. It is a useful base class for *************** *** 39,42 **** --- 44,52 ---- + \note{This module is available for backward compatibility only. If + you are writing code that does not need to work with versions of + Python earlier than Python 2.2, please consider subclassing directly + from the built-in \class{list} type.} + This module defines a class that acts as a wrapper around list objects. It is a useful base class for *************** *** 92,95 **** --- 102,112 ---- \moduleauthor{Peter Funk}{pf@artcom-gmbh.de} \sectionauthor{Peter Funk}{pf@artcom-gmbh.de} + + \note{This \class{UserString} class from this module is available for + backward compatibility only. If you are writing code that does not + need to work with versions of Python earlier than Python 2.2, please + consider subclassing directly from the built-in \class{str} type + instead of using \class{UserString} (there is no built-in equivalent + to \class{MutableString}).} This module defines a class that acts as a wrapper around string From fdrake@users.sourceforge.net Fri Oct 26 19:57:16 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 11:57:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libstdtypes.tex,1.72,1.73 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv29654/lib Modified Files: libstdtypes.tex Log Message: Explain what [].insert() does when the target index is negative. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.72 retrieving revision 1.73 diff -C2 -d -r1.72 -r1.73 *** libstdtypes.tex 2001/10/20 04:24:09 1.72 --- libstdtypes.tex 2001/10/26 18:57:14 1.73 *************** *** 840,852 **** \lineiii{\var{s}.insert(\var{i}, \var{x})} {same as \code{\var{s}[\var{i}:\var{i}] = [\var{x}]} ! if \code{\var{i} >= 0}}{} \lineiii{\var{s}.pop(\optional{\var{i}})} ! {same as \code{\var{x} = \var{s}[\var{i}]; del \var{s}[\var{i}]; return \var{x}}}{(4)} \lineiii{\var{s}.remove(\var{x})} {same as \code{del \var{s}[\var{s}.index(\var{x})]}}{(3)} \lineiii{\var{s}.reverse()} ! {reverses the items of \var{s} in place}{(5)} \lineiii{\var{s}.sort(\optional{\var{cmpfunc}})} ! {sort the items of \var{s} in place}{(5), (6)} \end{tableiii} \indexiv{operations on}{mutable}{sequence}{types} --- 840,852 ---- \lineiii{\var{s}.insert(\var{i}, \var{x})} {same as \code{\var{s}[\var{i}:\var{i}] = [\var{x}]} ! if \code{\var{i} >= 0}}{(4)} \lineiii{\var{s}.pop(\optional{\var{i}})} ! {same as \code{\var{x} = \var{s}[\var{i}]; del \var{s}[\var{i}]; return \var{x}}}{(5)} \lineiii{\var{s}.remove(\var{x})} {same as \code{del \var{s}[\var{s}.index(\var{x})]}}{(3)} \lineiii{\var{s}.reverse()} ! {reverses the items of \var{s} in place}{(6)} \lineiii{\var{s}.sort(\optional{\var{cmpfunc}})} ! {sort the items of \var{s} in place}{(6), (7)} \end{tableiii} \indexiv{operations on}{mutable}{sequence}{types} *************** *** 875,888 **** \var{s}. ! \item[(4)] The \method{pop()} method is only supported by the list and array types. The optional argument \var{i} defaults to \code{-1}, so that by default the last item is removed and returned. ! \item[(5)] The \method{sort()} and \method{reverse()} methods modify the list in place for economy of space when sorting or reversing a large list. To remind you that they operate by side effect, they don't return the sorted or reversed list. ! \item[(6)] The \method{sort()} method takes an optional argument specifying a comparison function of two arguments (list items) which should return a negative, zero or positive number depending on whether --- 875,892 ---- \var{s}. ! \item[(4)] When a negative index is passed as the first parameter to ! the \method{insert()} method, the new element is prepended to the ! sequence. ! ! \item[(5)] The \method{pop()} method is only supported by the list and array types. The optional argument \var{i} defaults to \code{-1}, so that by default the last item is removed and returned. ! \item[(6)] The \method{sort()} and \method{reverse()} methods modify the list in place for economy of space when sorting or reversing a large list. To remind you that they operate by side effect, they don't return the sorted or reversed list. ! \item[(7)] The \method{sort()} method takes an optional argument specifying a comparison function of two arguments (list items) which should return a negative, zero or positive number depending on whether From fdrake@users.sourceforge.net Fri Oct 26 20:48:08 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 12:48:08 -0700 Subject: [Python-checkins] CVS: python/dist/src Makefile.pre.in,1.65,1.66 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv14741 Modified Files: Makefile.pre.in Log Message: Now that Misc/Makefile.pre.in is gone, do not attempt to install it. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.65 retrieving revision 1.66 diff -C2 -d -r1.65 -r1.66 *** Makefile.pre.in 2001/10/20 14:21:44 1.65 --- Makefile.pre.in 2001/10/26 19:48:06 1.66 *************** *** 702,706 **** $(INSTALL_SCRIPT) $(srcdir)/Modules/makesetup $(LIBPL)/makesetup $(INSTALL_SCRIPT) $(srcdir)/install-sh $(LIBPL)/install-sh - $(INSTALL_DATA) $(srcdir)/Misc/Makefile.pre.in $(LIBPL)/Makefile.pre.in @if [ -s Modules/python.exp -a \ "`echo $(MACHDEP) | sed 's/^\(...\).*/\1/'`" = "aix" ]; then \ --- 702,705 ---- From fdrake@users.sourceforge.net Fri Oct 26 20:50:29 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 12:50:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib minidom-example.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv15618 Modified Files: minidom-example.py Log Message: Remove unused variable. Index: minidom-example.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/minidom-example.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** minidom-example.py 2001/09/02 06:07:36 1.1 --- minidom-example.py 2001/10/26 19:50:26 1.2 *************** *** 19,23 **** dom = xml.dom.minidom.parseString(document) - space = " " def getText(nodelist): rc = "" --- 19,22 ---- From bwarsaw@users.sourceforge.net Fri Oct 26 20:51:30 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 26 Oct 2001 12:51:30 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0273.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv15994 Modified Files: pep-0273.txt Log Message: Updated Post-History: Index: pep-0273.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0273.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pep-0273.txt 2001/10/25 15:58:29 1.1 --- pep-0273.txt 2001/10/26 19:51:28 1.2 *************** *** 7,11 **** Type: Standards Track Created: 11-Oct-2001 ! Post-History: Python-Version: 2.3 --- 7,11 ---- Type: Standards Track Created: 11-Oct-2001 ! Post-History: 26-Oct-2001 Python-Version: 2.3 From fdrake@users.sourceforge.net Fri Oct 26 21:09:51 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 13:09:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib xmldom.tex,1.16,1.17 xmldomminidom.tex,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv22864/lib Modified Files: xmldom.tex xmldomminidom.tex Log Message: Fix up a number of small problems with the DOM documentation. There's still a lot to do, but it's better now. Index: xmldom.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/xmldom.tex,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** xmldom.tex 2001/10/25 20:42:57 1.16 --- xmldom.tex 2001/10/26 20:09:49 1.17 *************** *** 115,120 **** % Should the Node documentation go here? ! In addition, \module{xml.dom} contains the \class{Node}, and the DOM ! exceptions. \subsection{Objects in the DOM \label{dom-objects}} --- 115,127 ---- % Should the Node documentation go here? ! In addition, \module{xml.dom} contains a base \class{Node} class and ! the DOM exception classes. The \class{Node} class provided by this ! module does not implement any of the methods or attributes defined by ! the DOM specification; concrete DOM implementations must provide ! those. The \class{Node} class provided as part of this module does ! provide the constants used for the \member{nodeType} attribute on ! concrete \class{Node} objects; they are located within the class ! rather than at the module level to conform with the DOM ! specifications. \subsection{Objects in the DOM \label{dom-objects}} *************** *** 359,363 **** the information) is available from a \class{DocumentType} object. The \class{DocumentType} for a document is available from the ! \class{Document} object's \member{doctype} attribute. \class{DocumentType} is a specialization of \class{Node}, and adds the --- 366,373 ---- the information) is available from a \class{DocumentType} object. The \class{DocumentType} for a document is available from the ! \class{Document} object's \member{doctype} attribute; if there is no ! \code{DOCTYPE} declaration for the document, the document's ! \member{doctype} attribute will be set to \code{None} instead of an ! instance of this interface. \class{DocumentType} is a specialization of \class{Node}, and adds the *************** *** 382,387 **** \begin{memberdesc}[DocumentType]{name} The name of the root element as given in the \code{DOCTYPE} ! declaration, if present. If the was no \code{DOCTYPE} declaration, ! this will be \code{None}. \end{memberdesc} --- 392,396 ---- \begin{memberdesc}[DocumentType]{name} The name of the root element as given in the \code{DOCTYPE} ! declaration, if present. \end{memberdesc} *************** *** 590,594 **** There are also experimental methods that give this class more mapping behavior. You can use them or you can use the standardized ! \method{getAttribute*()}-family methods on the \class{Element} objects. --- 599,604 ---- There are also experimental methods that give this class more mapping behavior. You can use them or you can use the standardized ! \method{getAttribute*()} family of methods on the \class{Element} ! objects. Index: xmldomminidom.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/xmldomminidom.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** xmldomminidom.tex 2001/09/02 06:07:36 1.4 --- xmldomminidom.tex 2001/10/26 20:09:49 1.5 *************** *** 181,186 **** \item The type \code{DOMString} maps to Python strings. \refmodule{xml.dom.minidom} supports either byte or Unicode ! strings, but will normally produce Unicode strings. Attributes ! of type \code{DOMString} may also be \code{None}. \item \keyword{const} declarations map to variables in their --- 181,188 ---- \item The type \code{DOMString} maps to Python strings. \refmodule{xml.dom.minidom} supports either byte or Unicode ! strings, but will normally produce Unicode strings. Values ! of type \code{DOMString} may also be \code{None} where allowed ! to have the IDL \code{null} value by the DOM specification from ! the W3C. \item \keyword{const} declarations map to variables in their *************** *** 194,200 **** as \exception{TypeError} and \exception{AttributeError}. ! \item \class{NodeList} objects are implemented as Python's built-in ! list type, so don't support the official API, but are much more ! ``Pythonic.'' \end{itemize} --- 196,205 ---- as \exception{TypeError} and \exception{AttributeError}. ! \item \class{NodeList} objects are implemented using Python's built-in ! list type. Starting with Python 2.2, these objects provide the ! interface defined in the DOM specification, but with earlier ! versions of Python they do not support the official API. They ! are, however, much more ``Pythonic'' than the interface defined ! in the W3C recommendations. \end{itemize} *************** *** 204,224 **** \begin{itemize} ! \item DOMTimeStamp ! \item DocumentType (added in Python 2.1) ! \item DOMImplementation (added in Python 2.1) ! \item CharacterData ! \item CDATASection ! \item Notation ! \item Entity ! \item EntityReference ! \item DocumentFragment \end{itemize} --- 209,229 ---- \begin{itemize} ! \item \class{DOMTimeStamp} ! \item \class{DocumentType} (added in Python 2.1) ! \item \class{DOMImplementation} (added in Python 2.1) ! \item \class{CharacterData} ! \item \class{CDATASection} ! \item \class{Notation} ! \item \class{Entity} ! \item \class{EntityReference} ! \item \class{DocumentFragment} \end{itemize} From tim_one@users.sourceforge.net Fri Oct 26 21:57:41 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 26 Oct 2001 13:57:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.95,1.96 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv3447/python/Lib/test Modified Files: test_descr.py Log Message: dict_constructor(): The last test was passing for the wrong reason (it was intended to verify that sub-sequences of lengths 1 and 3 raise ValueError, but was actually testing string lengths). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.95 retrieving revision 1.96 diff -C2 -d -r1.95 -r1.96 *** test_descr.py 2001/10/26 05:06:50 1.95 --- test_descr.py 2001/10/26 20:57:38 1.96 *************** *** 248,252 **** # Bad sequence lengths. ! for bad in ['tooshort'], ['too', 'long', 'by 1']: try: dictionary(bad) --- 248,252 ---- # Bad sequence lengths. ! for bad in [('tooshort',)], [('too', 'long', 'by 1')]: try: dictionary(bad) From mal@lemburg.com Fri Oct 26 21:58:06 2001 From: mal@lemburg.com (M.-A. Lemburg) Date: Fri, 26 Oct 2001 22:58:06 +0200 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.87,2.88 References: Message-ID: <3BD9CE5E.F43ED33A@lemburg.com> "Fred L. Drake" wrote: > > Update of /cvsroot/python/python/dist/src/Objects > In directory usw-pr-cvs1:/tmp/cvs-serv3454/Objects > > Modified Files: > abstract.c > Log Message: > Added two new functions to conveniently call functions/methods from C. > PyObject_CallFunctionObArgs() and PyObject_CallMethodObArgs() have the > advantage that no format strings need to be parsed. The CallMethod > variant also avoids creating a new string object in order to retrieve > a method from an object as well. Just curious: why didn't you call them ...FunctionObjArgs() ? (with the 'j') -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Consulting & Company: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/ From tim_one@users.sourceforge.net Sat Oct 27 01:17:38 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 26 Oct 2001 17:17:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.69,2.70 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv22471/python/Python Modified Files: getargs.c Log Message: vgetargskeywords(): remove test that can't succeed. Not a bugfix, just removing useless obfuscation. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.69 retrieving revision 2.70 diff -C2 -d -r2.69 -r2.70 *** getargs.c 2001/10/23 21:09:29 2.69 --- getargs.c 2001/10/27 00:17:34 2.70 *************** *** 1029,1035 **** int nkwds, pos, match, converted; PyObject *key, *value; ! /* nested tuples cannot be parsed when using keyword arguments */ ! for (;;) { int c = *format++; --- 1029,1035 ---- int nkwds, pos, match, converted; PyObject *key, *value; ! /* nested tuples cannot be parsed when using keyword arguments */ ! for (;;) { int c = *format++; *************** *** 1069,1088 **** /* do a cursory check of the keywords just to see how many we got */ ! if (keywords) { if (!PyDict_Check(keywords)) { ! if (keywords == NULL) ! PyErr_SetString(PyExc_SystemError, ! "NULL received when keyword dictionary expected"); ! else ! PyErr_Format(PyExc_SystemError, ! "%s received when keyword dictionary expected", ! keywords->ob_type->tp_name); return 0; } kwlen = PyDict_Size(keywords); - } - else { - kwlen = 0; } --- 1069,1082 ---- /* do a cursory check of the keywords just to see how many we got */ ! ! kwlen = 0; if (keywords) { if (!PyDict_Check(keywords)) { ! PyErr_Format(PyExc_SystemError, ! "%s received when keyword dictionary expected", ! keywords->ob_type->tp_name); return 0; } kwlen = PyDict_Size(keywords); } From tim_one@users.sourceforge.net Sat Oct 27 01:46:11 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 26 Oct 2001 17:46:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.70,2.71 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv26539/python/Python Modified Files: getargs.c Log Message: tuple(3,4,5,x=2) dumped core on my box. vgetargskeywords() overindexed the kwlist vector whenever there was a mix of positional and keyword arguments, and the number of positional arguments exceeded the length of the kwlist vector. If there was just one more positional arg than keyword, the kwlist-terminating NULL got passed to PyMapping_HasKeyString, which set an internal error that vgetargskeywords() then squashed (but it's impossible to say whether it knew it was masking an error). If more than one more positional argument, it went on to pass random trash to PyMapping_HasKeyString, which is why the example at the start happened to kill the process. Pure bugfix candidate. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.70 retrieving revision 2.71 diff -C2 -d -r2.70 -r2.71 *** getargs.c 2001/10/27 00:17:34 2.70 --- getargs.c 2001/10/27 00:46:09 2.71 *************** *** 1084,1094 **** its not clear when to use the term "keyword argument vs. keyword parameter in messages */ ! if (keywords) { for (i = 0; i < tplen; i++) { ! if (PyMapping_HasKeyString(keywords, kwlist[i])) { sprintf(msgbuf, "keyword parameter %s redefined", ! kwlist[i]); PyErr_SetString(PyExc_TypeError, msgbuf); return 0; --- 1084,1097 ---- its not clear when to use the term "keyword argument vs. keyword parameter in messages */ ! if (keywords) { for (i = 0; i < tplen; i++) { ! char *thiskw = kwlist[i]; ! if (thiskw == NULL) ! break; ! if (PyMapping_HasKeyString(keywords, thiskw)) { sprintf(msgbuf, "keyword parameter %s redefined", ! thiskw); PyErr_SetString(PyExc_TypeError, msgbuf); return 0; *************** *** 1096,1099 **** --- 1099,1109 ---- } } + /* XXX The loop just above didn't used to break when hitting the + end of kwlist, so could pass NULL on to PyMapping_HasKeyString, + which sets a "NULL argument to internal routine" error then. + However, the comment below doesn't give any clues about which + 'error string' it's talking about, so darned hard to say whether + the PyErr_Clear() still serves a purpose. + */ PyErr_Clear(); /* I'm not which Py functions set the error string */ From fdrake@acm.org Sat Oct 27 03:36:20 2001 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Fri, 26 Oct 2001 22:36:20 -0400 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.87,2.88 In-Reply-To: <3BD9CE5E.F43ED33A@lemburg.com> References: <3BD9CE5E.F43ED33A@lemburg.com> Message-ID: <15322.7588.106800.771227@grendel.zope.com> M.-A. Lemburg writes: > Just curious: why didn't you call them ...FunctionObjArgs() ? (with > the 'j') No particular reason -- it just felt a little nicer. I don't think there's a precedence for either in the C API. If there is and I missed it, these should be adjusted to conform to the precedent. -Fred -- Fred L. Drake, Jr. PythonLabs at Zope Corporation From barry@zope.com Sat Oct 27 04:15:09 2001 From: barry@zope.com (Barry A. Warsaw) Date: Fri, 26 Oct 2001 23:15:09 -0400 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.87,2.88 References: <3BD9CE5E.F43ED33A@lemburg.com> <15322.7588.106800.771227@grendel.zope.com> Message-ID: <15322.9917.871606.312849@anthem.wooz.org> >>>>> "Fred" == Fred L Drake, Jr writes: >> Just curious: why didn't you call them ...FunctionObjArgs() ? >> (with the 'j') Fred> No particular reason -- it just felt a little nicer. I Fred> don't think there's a precedence for either in the C API. Fred> If there is and I missed it, these should be adjusted to Fred> conform to the precedent. `Obj' == +0 `Object' == +1 From tim_one@users.sourceforge.net Sat Oct 27 04:58:42 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 26 Oct 2001 20:58:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.71,2.72 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv759/python/Python Modified Files: getargs.c Log Message: PyArg_ParseTupleAndKeywords: do basic sanity checks on the arguments, and raise an error if they're insane. vgetargskeywords: the same, except that since this is an internal routine, just assert that the arguments are sane. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.71 retrieving revision 2.72 diff -C2 -d -r2.71 -r2.72 *** getargs.c 2001/10/27 00:46:09 2.71 --- getargs.c 2001/10/27 03:58:40 2.72 *************** *** 1006,1010 **** int retval; va_list va; ! va_start(va, kwlist); retval = vgetargskeywords(args, keywords, format, kwlist, &va); --- 1006,1019 ---- int retval; va_list va; ! ! if ((args == NULL || !PyTuple_Check(args)) || ! (keywords != NULL && !PyDict_Check(keywords)) || ! format == NULL || ! kwlist == NULL) ! { ! PyErr_BadInternalCall(); ! return -1; ! } ! va_start(va, kwlist); retval = vgetargskeywords(args, keywords, format, kwlist, &va); *************** *** 1029,1032 **** --- 1038,1047 ---- int nkwds, pos, match, converted; PyObject *key, *value; + + assert(args != NULL && PyTuple_Check(args)); + assert(keywords == NULL || PyDict_Check(keywords)); + assert(format != NULL); + assert(kwlist != NULL); + assert(p_va != NULL); /* nested tuples cannot be parsed when using keyword arguments */ From tim_one@users.sourceforge.net Sat Oct 27 05:26:59 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 26 Oct 2001 21:26:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.72,2.73 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv3534/python/Python Modified Files: getargs.c Log Message: PyArg_ParseTupleAndKeywords: return false on internal error, not -1 (I introduced this bug just a little while ago, when *adding* internal error checks). vgetargskeywords: Rewrote the section that crawls over the format string. + Added block comment so it won't take the next person 15 minutes to reverse-engineer what it's doing. + Lined up the "else" clauses. + Rearranged the ifs in decreasing order of likelihood (for speed). Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.72 retrieving revision 2.73 diff -C2 -d -r2.72 -r2.73 *** getargs.c 2001/10/27 03:58:40 2.72 --- getargs.c 2001/10/27 04:26:57 2.73 *************** *** 998,1001 **** --- 998,1002 ---- Geoff Philbrick */ + /* Return false (0) for error, else true. */ int PyArg_ParseTupleAndKeywords(PyObject *args, *************** *** 1013,1017 **** { PyErr_BadInternalCall(); ! return -1; } --- 1014,1018 ---- { PyErr_BadInternalCall(); ! return 0; } *************** *** 1029,1036 **** char msgbuf[256]; int levels[32]; ! char *fname = NULL; ! char *message = NULL; ! int min = -1; ! int max = 0; char *formatsave = format; int i, len, tplen, kwlen; --- 1030,1035 ---- char msgbuf[256]; int levels[32]; ! char *fname, *message; ! int min, max; char *formatsave = format; int i, len, tplen, kwlen; *************** *** 1044,1078 **** assert(kwlist != NULL); assert(p_va != NULL); - - /* nested tuples cannot be parsed when using keyword arguments */ ! for (;;) { ! int c = *format++; ! if (c == '(') { ! PyErr_SetString(PyExc_SystemError, ! "tuple found in format when using keyword arguments"); ! return 0; ! } ! else if (c == '\0') ! break; ! else if (c == ':') { fname = format; break; ! } else if (c == ';') { message = format; break; ! } else if (c == 'e') ! ; /* Pass */ ! else if (isalpha(c)) ! max++; ! else if (c == '|') ! min = max; } ! ! if (min < 0) min = max; ! format = formatsave; ! if (!PyTuple_Check(args)) { PyErr_SetString(PyExc_SystemError, --- 1043,1082 ---- assert(kwlist != NULL); assert(p_va != NULL); ! /* Search the format: ! message <- error msg, if any (else NULL). ! name <- routine name, if any (else NULL). ! min <- # of required arguments, or -1 if all are required. ! max <- most arguments (required + optional). ! Raise error if a tuple arg spec is found. ! */ ! fname = message = NULL; ! min = -1; ! max = 0; ! while ((i = *format++) != '\0') { ! if (isalpha(i) && i != 'e') ! max++; ! else if (i == '|') ! min = max; ! else if (i == ':') { fname = format; break; ! } ! else if (i == ';') { message = format; break; ! } ! else if (i == '(') { ! PyErr_SetString(PyExc_SystemError, ! "tuple found in format when using keyword arguments"); ! return 0; ! } } ! if (min < 0) { ! /* All arguments are required. */ min = max; ! } format = formatsave; ! if (!PyTuple_Check(args)) { PyErr_SetString(PyExc_SystemError, *************** *** 1080,1086 **** return 0; } ! tplen = PyTuple_GET_SIZE(args); ! /* do a cursory check of the keywords just to see how many we got */ --- 1084,1090 ---- return 0; } ! tplen = PyTuple_GET_SIZE(args); ! /* do a cursory check of the keywords just to see how many we got */ From tim_one@users.sourceforge.net Sat Oct 27 05:33:43 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 26 Oct 2001 21:33:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.73,2.74 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv4609/python/Python Modified Files: getargs.c Log Message: vgetargskeywords: + Removed now-redundant tuple typecheck. + Renamed "tplen" local to "argslen" (it's the length of the "args" argument; I suppose "tp" was for "Tim Peters should rename me someday ). Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.73 retrieving revision 2.74 diff -C2 -d -r2.73 -r2.74 *** getargs.c 2001/10/27 04:26:57 2.73 --- getargs.c 2001/10/27 04:33:41 2.74 *************** *** 1033,1037 **** int min, max; char *formatsave = format; ! int i, len, tplen, kwlen; char *msg, *ks, **p; int nkwds, pos, match, converted; --- 1033,1037 ---- int min, max; char *formatsave = format; ! int i, len, argslen, kwlen; char *msg, *ks, **p; int nkwds, pos, match, converted; *************** *** 1079,1089 **** format = formatsave; ! if (!PyTuple_Check(args)) { ! PyErr_SetString(PyExc_SystemError, ! "new style getargs format but argument is not a tuple"); ! return 0; ! } ! ! tplen = PyTuple_GET_SIZE(args); /* do a cursory check of the keywords just to see how many we got */ --- 1079,1083 ---- format = formatsave; ! argslen = PyTuple_GET_SIZE(args); /* do a cursory check of the keywords just to see how many we got */ *************** *** 1105,1109 **** if (keywords) { ! for (i = 0; i < tplen; i++) { char *thiskw = kwlist[i]; if (thiskw == NULL) --- 1099,1103 ---- if (keywords) { ! for (i = 0; i < argslen; i++) { char *thiskw = kwlist[i]; if (thiskw == NULL) *************** *** 1130,1136 **** arguments */ ! len = tplen; ! if (keywords && tplen < min) { ! for (i = tplen; i < min; i++) { if (PyMapping_HasKeyString(keywords, kwlist[i])) { len++; --- 1124,1130 ---- arguments */ ! len = argslen; ! if (keywords && argslen < min) { ! for (i = argslen; i < min; i++) { if (PyMapping_HasKeyString(keywords, kwlist[i])) { len++; *************** *** 1162,1166 **** } ! for (i = 0; i < tplen; i++) { if (*format == '|') format++; --- 1156,1160 ---- } ! for (i = 0; i < argslen; i++) { if (*format == '|') format++; *************** *** 1175,1179 **** /* handle no keyword parameters in call */ ! if (!keywords) return 1; /* make sure the number of keywords in the keyword list matches the --- 1169,1174 ---- /* handle no keyword parameters in call */ ! if (!keywords) ! return 1; /* make sure the number of keywords in the keyword list matches the *************** *** 1197,1201 **** converted = 0; ! for (i = tplen; i < nkwds; i++) { PyObject *item; if (*format == '|') --- 1192,1196 ---- converted = 0; ! for (i = argslen; i < nkwds; i++) { PyObject *item; if (*format == '|') From tim_one@users.sourceforge.net Sat Oct 27 05:38:13 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 26 Oct 2001 21:38:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.74,2.75 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv5334/python/Python Modified Files: getargs.c Log Message: vgetargskeywords: + Renamed argslen to nargs. + Renamed kwlen to nkeywords. This one was especially confusing because kwlen wasn't the length of the kwlist argument, but of the keywords argument. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.74 retrieving revision 2.75 diff -C2 -d -r2.74 -r2.75 *** getargs.c 2001/10/27 04:33:41 2.74 --- getargs.c 2001/10/27 04:38:11 2.75 *************** *** 1032,1037 **** char *fname, *message; int min, max; ! char *formatsave = format; ! int i, len, argslen, kwlen; char *msg, *ks, **p; int nkwds, pos, match, converted; --- 1032,1037 ---- char *fname, *message; int min, max; ! char *formatsave; ! int i, len, nargs, nkeywords; char *msg, *ks, **p; int nkwds, pos, match, converted; *************** *** 1052,1055 **** --- 1052,1056 ---- */ fname = message = NULL; + formatsave = format; min = -1; max = 0; *************** *** 1079,1087 **** format = formatsave; ! argslen = PyTuple_GET_SIZE(args); /* do a cursory check of the keywords just to see how many we got */ ! kwlen = 0; if (keywords) { if (!PyDict_Check(keywords)) { --- 1080,1088 ---- format = formatsave; ! nargs = PyTuple_GET_SIZE(args); /* do a cursory check of the keywords just to see how many we got */ ! nkeywords = 0; if (keywords) { if (!PyDict_Check(keywords)) { *************** *** 1091,1095 **** return 0; } ! kwlen = PyDict_Size(keywords); } --- 1092,1096 ---- return 0; } ! nkeywords = PyDict_Size(keywords); } *************** *** 1099,1103 **** if (keywords) { ! for (i = 0; i < argslen; i++) { char *thiskw = kwlist[i]; if (thiskw == NULL) --- 1100,1104 ---- if (keywords) { ! for (i = 0; i < nargs; i++) { char *thiskw = kwlist[i]; if (thiskw == NULL) *************** *** 1124,1130 **** arguments */ ! len = argslen; ! if (keywords && argslen < min) { ! for (i = argslen; i < min; i++) { if (PyMapping_HasKeyString(keywords, kwlist[i])) { len++; --- 1125,1131 ---- arguments */ ! len = nargs; ! if (keywords && nargs < min) { ! for (i = nargs; i < min; i++) { if (PyMapping_HasKeyString(keywords, kwlist[i])) { len++; *************** *** 1156,1160 **** } ! for (i = 0; i < argslen; i++) { if (*format == '|') format++; --- 1157,1161 ---- } ! for (i = 0; i < nargs; i++) { if (*format == '|') format++; *************** *** 1192,1196 **** converted = 0; ! for (i = argslen; i < nkwds; i++) { PyObject *item; if (*format == '|') --- 1193,1197 ---- converted = 0; ! for (i = nargs; i < nkwds; i++) { PyObject *item; if (*format == '|') *************** *** 1219,1223 **** pos = 0; ! if (converted < kwlen) { while (PyDict_Next(keywords, &pos, &key, &value)) { match = 0; --- 1220,1224 ---- pos = 0; ! if (converted < nkeywords) { while (PyDict_Next(keywords, &pos, &key, &value)) { match = 0; From tim_one@users.sourceforge.net Sat Oct 27 05:45:36 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 26 Oct 2001 21:45:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.75,2.76 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv6119/python/Python Modified Files: getargs.c Log Message: vgetargskeywords: + Got rid of now-redundant dict typecheck. + Renamed nkwds to nkwlist. Now all the "counting" vrbls have names related to the things they're counting in an obvious way. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.75 retrieving revision 2.76 diff -C2 -d -r2.75 -r2.76 *** getargs.c 2001/10/27 04:38:11 2.75 --- getargs.c 2001/10/27 04:45:34 2.76 *************** *** 1035,1039 **** int i, len, nargs, nkeywords; char *msg, *ks, **p; ! int nkwds, pos, match, converted; PyObject *key, *value; --- 1035,1039 ---- int i, len, nargs, nkeywords; char *msg, *ks, **p; ! int nkwlist, pos, match, converted; PyObject *key, *value; *************** *** 1081,1102 **** nargs = PyTuple_GET_SIZE(args); - /* do a cursory check of the keywords just to see how many we got */ - - nkeywords = 0; - if (keywords) { - if (!PyDict_Check(keywords)) { - PyErr_Format(PyExc_SystemError, - "%s received when keyword dictionary expected", - keywords->ob_type->tp_name); - return 0; - } - nkeywords = PyDict_Size(keywords); - } - /* make sure there are no duplicate values for an argument; its not clear when to use the term "keyword argument vs. keyword parameter in messages */ - if (keywords) { for (i = 0; i < nargs; i++) { --- 1081,1089 ---- nargs = PyTuple_GET_SIZE(args); + nkeywords = keywords == NULL ? 0 : PyDict_Size(keywords); /* make sure there are no duplicate values for an argument; its not clear when to use the term "keyword argument vs. keyword parameter in messages */ if (keywords) { for (i = 0; i < nargs; i++) { *************** *** 1176,1187 **** number of items in the format string */ ! nkwds = 0; p = kwlist; for (;;) { if (!*(p++)) break; ! nkwds++; } ! if (nkwds != max) { PyErr_SetString(PyExc_SystemError, "number of items in format string and keyword list do not match"); --- 1163,1174 ---- number of items in the format string */ ! nkwlist = 0; p = kwlist; for (;;) { if (!*(p++)) break; ! nkwlist++; } ! if (nkwlist != max) { PyErr_SetString(PyExc_SystemError, "number of items in format string and keyword list do not match"); *************** *** 1193,1197 **** converted = 0; ! for (i = nargs; i < nkwds; i++) { PyObject *item; if (*format == '|') --- 1180,1184 ---- converted = 0; ! for (i = nargs; i < nkwlist; i++) { PyObject *item; if (*format == '|') *************** *** 1224,1228 **** match = 0; ks = PyString_AsString(key); ! for (i = 0; i < nkwds; i++) { if (!strcmp(ks, kwlist[i])) { match = 1; --- 1211,1215 ---- match = 0; ks = PyString_AsString(key); ! for (i = 0; i < nkwlist; i++) { if (!strcmp(ks, kwlist[i])) { match = 1; From tim_one@users.sourceforge.net Sat Oct 27 06:07:43 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 26 Oct 2001 22:07:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.76,2.77 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv7868/python/Python Modified Files: getargs.c Log Message: vgetargskeywords: + Generally test nkeywords against 0 instead of keywords against NULL (saves a little work if an empty keywords dict is passed, and is conceptually more on-target regardless). + When a call erroneously specifies a keyword argument both by position and by keyword name: - It was easy to provoke this routine into an internal buffer overrun by using a long argument name. Now uses PyErr_format instead (which computes a safe buffer size). - Improved the error msg. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.76 retrieving revision 2.77 diff -C2 -d -r2.76 -r2.77 *** getargs.c 2001/10/27 04:45:34 2.76 --- getargs.c 2001/10/27 05:07:41 2.77 *************** *** 1086,1090 **** its not clear when to use the term "keyword argument vs. keyword parameter in messages */ ! if (keywords) { for (i = 0; i < nargs; i++) { char *thiskw = kwlist[i]; --- 1086,1090 ---- its not clear when to use the term "keyword argument vs. keyword parameter in messages */ ! if (nkeywords > 0) { for (i = 0; i < nargs; i++) { char *thiskw = kwlist[i]; *************** *** 1092,1099 **** break; if (PyMapping_HasKeyString(keywords, thiskw)) { ! sprintf(msgbuf, ! "keyword parameter %s redefined", thiskw); - PyErr_SetString(PyExc_TypeError, msgbuf); return 0; } --- 1092,1099 ---- break; if (PyMapping_HasKeyString(keywords, thiskw)) { ! PyErr_Format(PyExc_TypeError, ! "keyword parameter '%s' was given " ! "by position and by name", thiskw); return 0; } *************** *** 1156,1173 **** /* handle no keyword parameters in call */ ! ! if (!keywords) return 1; ! /* make sure the number of keywords in the keyword list matches the number of items in the format string */ - nkwlist = 0; p = kwlist; ! for (;;) { ! if (!*(p++)) break; nkwlist++; - } - if (nkwlist != max) { PyErr_SetString(PyExc_SystemError, --- 1156,1168 ---- /* handle no keyword parameters in call */ ! if (nkeywords == 0) return 1; ! /* make sure the number of keywords in the keyword list matches the number of items in the format string */ nkwlist = 0; p = kwlist; ! while (*p++) nkwlist++; if (nkwlist != max) { PyErr_SetString(PyExc_SystemError, *************** *** 1175,1182 **** return 0; } ! /* convert the keyword arguments; this uses the format string where it was left after processing args */ - converted = 0; for (i = nargs; i < nkwlist; i++) { --- 1170,1176 ---- return 0; } ! /* convert the keyword arguments; this uses the format string where it was left after processing args */ converted = 0; for (i = nargs; i < nkwlist; i++) { *************** *** 1203,1209 **** } } ! /* make sure there are no extraneous keyword arguments */ - pos = 0; if (converted < nkeywords) { --- 1197,1202 ---- } } ! /* make sure there are no extraneous keyword arguments */ pos = 0; if (converted < nkeywords) { From tim_one@users.sourceforge.net Sat Oct 27 06:30:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 26 Oct 2001 22:30:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.77,2.78 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv10854/python/Python Modified Files: getargs.c Log Message: vgetargskeywords: Removed one of the mysterious PyErr_Clear() calls. The "need" for this was probably removed by an earlier patch that stopped the loop right before it from passing NULL to a dict lookup routine. I still haven't convinced myself that the next loop is correct, so am leaving the next mysterious PyErr_Clear() call in for now. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.77 retrieving revision 2.78 diff -C2 -d -r2.77 -r2.78 *** getargs.c 2001/10/27 05:07:41 2.77 --- getargs.c 2001/10/27 05:30:17 2.78 *************** *** 1100,1115 **** } } ! /* XXX The loop just above didn't used to break when hitting the ! end of kwlist, so could pass NULL on to PyMapping_HasKeyString, ! which sets a "NULL argument to internal routine" error then. ! However, the comment below doesn't give any clues about which ! 'error string' it's talking about, so darned hard to say whether ! the PyErr_Clear() still serves a purpose. ! */ ! PyErr_Clear(); /* I'm not which Py functions set the error string */ ! /* required arguments missing from args can be supplied by keyword arguments */ - len = nargs; if (keywords && nargs < min) { --- 1100,1106 ---- } } ! /* required arguments missing from args can be supplied by keyword arguments */ len = nargs; if (keywords && nargs < min) { From tim_one@users.sourceforge.net Sat Oct 27 06:50:42 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 26 Oct 2001 22:50:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.78,2.79 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv12868/python/Python Modified Files: getargs.c Log Message: vgetargskeywords: The keywords arg is a dict (if non-NULL), so use the dict API everywhere on it instead of sometimes using the slower mapping API. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.78 retrieving revision 2.79 diff -C2 -d -r2.78 -r2.79 *** getargs.c 2001/10/27 05:30:17 2.78 --- getargs.c 2001/10/27 05:50:39 2.79 *************** *** 1091,1095 **** if (thiskw == NULL) break; ! if (PyMapping_HasKeyString(keywords, thiskw)) { PyErr_Format(PyExc_TypeError, "keyword parameter '%s' was given " --- 1091,1095 ---- if (thiskw == NULL) break; ! if (PyDict_GetItemString(keywords, thiskw)) { PyErr_Format(PyExc_TypeError, "keyword parameter '%s' was given " *************** *** 1106,1112 **** if (keywords && nargs < min) { for (i = nargs; i < min; i++) { ! if (PyMapping_HasKeyString(keywords, kwlist[i])) { len++; - } } } --- 1106,1111 ---- if (keywords && nargs < min) { for (i = nargs; i < min; i++) { ! if (PyDict_GetItemString(keywords, kwlist[i])) len++; } } *************** *** 1169,1175 **** if (*format == '|') format++; ! item = PyMapping_GetItemString(keywords, kwlist[i]); if (item != NULL) { msg = convertitem(item, &format, p_va, levels, msgbuf); if (msg) { seterror(i+1, msg, levels, fname, message); --- 1168,1176 ---- if (*format == '|') format++; ! item = PyDict_GetItemString(keywords, kwlist[i]); if (item != NULL) { + Py_INCREF(item); msg = convertitem(item, &format, p_va, levels, msgbuf); + Py_DECREF(item); if (msg) { seterror(i+1, msg, levels, fname, message); *************** *** 1177,1181 **** } converted++; - Py_DECREF(item); } else { --- 1178,1181 ---- From tim_one@users.sourceforge.net Sat Oct 27 07:14:34 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 26 Oct 2001 23:14:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.79,2.80 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv15138/python/Python Modified Files: getargs.c Log Message: vgetargskeywords: Removed all PyErr_Clear() calls. It's possible that this routine will report an error now when it didn't before, but, if so, it's a legitimate error that should never have been suppressed. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.79 retrieving revision 2.80 diff -C2 -d -r2.79 -r2.80 *** getargs.c 2001/10/27 05:50:39 2.79 --- getargs.c 2001/10/27 06:14:32 2.80 *************** *** 1098,1101 **** --- 1098,1103 ---- return 0; } + else if (PyErr_Occurred()) + return 0; } } *************** *** 1108,1115 **** if (PyDict_GetItemString(keywords, kwlist[i])) len++; } } ! PyErr_Clear(); ! /* make sure we got an acceptable number of arguments; the message is a little confusing with keywords since keyword arguments --- 1110,1118 ---- if (PyDict_GetItemString(keywords, kwlist[i])) len++; + else if (PyErr_Occurred()) + return 0; } } ! /* make sure we got an acceptable number of arguments; the message is a little confusing with keywords since keyword arguments *************** *** 1160,1164 **** return 0; } ! /* convert the keyword arguments; this uses the format string where it was left after processing args */ --- 1163,1167 ---- return 0; } ! /* convert the keyword arguments; this uses the format string where it was left after processing args */ *************** *** 1179,1184 **** converted++; } else { - PyErr_Clear(); msg = skipitem(&format, p_va); if (msg) { --- 1182,1188 ---- converted++; } + else if (PyErr_Occurred()) + return 0; else { msg = skipitem(&format, p_va); if (msg) { From fdrake@users.sourceforge.net Sat Oct 27 07:16:34 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 26 Oct 2001 23:16:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.88,2.89 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv15467/Objects Modified Files: abstract.c Log Message: PyObject_CallFunction(), PyObject_CallMethod(): Make sure we do not touch the va_list until we are sure we have a format string and need to use it; this avoid premature initialization and having to finalize it several different places because of error returns. Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.88 retrieving revision 2.89 diff -C2 -d -r2.88 -r2.89 *** abstract.c 2001/10/26 16:21:32 2.88 --- abstract.c 2001/10/27 06:16:31 2.89 *************** *** 1671,1688 **** va_list va; PyObject *args, *retval; - va_start(va, format); ! if (callable == NULL) { ! va_end(va); return null_error(); - } ! if (format) args = Py_VaBuildValue(format, va); else args = PyTuple_New(0); - va_end(va); - if (args == NULL) return NULL; --- 1671,1686 ---- va_list va; PyObject *args, *retval; ! if (callable == NULL) return null_error(); ! if (format && *format) { ! va_start(va, format); args = Py_VaBuildValue(format, va); + va_end(va); + } else args = PyTuple_New(0); if (args == NULL) return NULL; *************** *** 1710,1738 **** va_list va; PyObject *args, *func = 0, *retval; - va_start(va, format); ! if (o == NULL || name == NULL) { ! va_end(va); return null_error(); - } func = PyObject_GetAttrString(o, name); if (func == NULL) { - va_end(va); PyErr_SetString(PyExc_AttributeError, name); return 0; } ! if (!PyCallable_Check(func)) { ! va_end(va); return type_error("call of non-callable attribute"); - } ! if (format && *format) args = Py_VaBuildValue(format, va); else args = PyTuple_New(0); - - va_end(va); if (!args) --- 1708,1731 ---- va_list va; PyObject *args, *func = 0, *retval; ! if (o == NULL || name == NULL) return null_error(); func = PyObject_GetAttrString(o, name); if (func == NULL) { PyErr_SetString(PyExc_AttributeError, name); return 0; } ! if (!PyCallable_Check(func)) return type_error("call of non-callable attribute"); ! if (format && *format) { ! va_start(va, format); args = Py_VaBuildValue(format, va); + va_end(va); + } else args = PyTuple_New(0); if (!args) From tim_one@users.sourceforge.net Sat Oct 27 07:42:18 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 26 Oct 2001 23:42:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.80,2.81 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv18101/python/Python Modified Files: getargs.c Log Message: vgetargskeywords: Verify kwlist has the required length while parsing the format, instead of waiting until after we can overindex it by mistake. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.80 retrieving revision 2.81 diff -C2 -d -r2.80 -r2.81 *** getargs.c 2001/10/27 06:14:32 2.80 --- getargs.c 2001/10/27 06:42:16 2.81 *************** *** 1033,1039 **** int min, max; char *formatsave; ! int i, len, nargs, nkeywords; char *msg, *ks, **p; ! int nkwlist, pos, match, converted; PyObject *key, *value; --- 1033,1039 ---- int min, max; char *formatsave; ! int i, len, nargs, nkeywords, nkwlist; char *msg, *ks, **p; ! int pos, match, converted; PyObject *key, *value; *************** *** 1049,1061 **** min <- # of required arguments, or -1 if all are required. max <- most arguments (required + optional). Raise error if a tuple arg spec is found. */ fname = message = NULL; formatsave = format; min = -1; max = 0; while ((i = *format++) != '\0') { ! if (isalpha(i) && i != 'e') max++; else if (i == '|') min = max; --- 1049,1070 ---- min <- # of required arguments, or -1 if all are required. max <- most arguments (required + optional). + Check that kwlist has a non-NULL entry for each arg. Raise error if a tuple arg spec is found. */ fname = message = NULL; formatsave = format; + p = kwlist; min = -1; max = 0; while ((i = *format++) != '\0') { ! if (isalpha(i) && i != 'e') { max++; + if (*p == NULL) { + /* kwlist is too short */ + PyErr_BadInternalCall(); + return 0; + } + p++; + } else if (i == '|') min = max; *************** *** 1073,1083 **** return 0; } ! } if (min < 0) { /* All arguments are required. */ min = max; } - format = formatsave; nargs = PyTuple_GET_SIZE(args); nkeywords = keywords == NULL ? 0 : PyDict_Size(keywords); --- 1082,1098 ---- return 0; } ! } ! format = formatsave; ! if (*p != NULL) { ! /* kwlist is too long */ ! PyErr_BadInternalCall(); ! return 0; ! } if (min < 0) { /* All arguments are required. */ min = max; } + nkwlist = max; nargs = PyTuple_GET_SIZE(args); nkeywords = keywords == NULL ? 0 : PyDict_Size(keywords); *************** *** 1104,1110 **** /* required arguments missing from args can be supplied by keyword ! arguments */ len = nargs; ! if (keywords && nargs < min) { for (i = nargs; i < min; i++) { if (PyDict_GetItemString(keywords, kwlist[i])) --- 1119,1127 ---- /* required arguments missing from args can be supplied by keyword ! arguments; set len to the number of posiitional arguments, and, ! if that's less than the minimum required, add in the number of ! required arguments that are supplied by keywords */ len = nargs; ! if (nkeywords > 0 && nargs < min) { for (i = nargs; i < min; i++) { if (PyDict_GetItemString(keywords, kwlist[i])) *************** *** 1119,1123 **** which are supplied, but don't match the required arguments are not included in the "%d given" part of the message */ - if (len < min || max < len) { if (message == NULL) { --- 1136,1139 ---- *************** *** 1151,1166 **** if (nkeywords == 0) return 1; - - /* make sure the number of keywords in the keyword list matches the - number of items in the format string */ - nkwlist = 0; - p = kwlist; - while (*p++) - nkwlist++; - if (nkwlist != max) { - PyErr_SetString(PyExc_SystemError, - "number of items in format string and keyword list do not match"); - return 0; - } /* convert the keyword arguments; this uses the format --- 1167,1170 ---- From tim_one@users.sourceforge.net Sat Oct 27 07:53:03 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 26 Oct 2001 23:53:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.81,2.82 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv19781/python/Python Modified Files: getargs.c Log Message: vgetargskeywords: Prevent another potential sprintf buffer overrun. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.81 retrieving revision 2.82 diff -C2 -d -r2.81 -r2.82 *** getargs.c 2001/10/27 06:42:16 2.81 --- getargs.c 2001/10/27 06:53:00 2.82 *************** *** 1028,1032 **** char **kwlist, va_list *p_va) { ! char msgbuf[256]; int levels[32]; char *fname, *message; --- 1028,1032 ---- char **kwlist, va_list *p_va) { ! char msgbuf[512]; int levels[32]; char *fname, *message; *************** *** 1139,1143 **** if (message == NULL) { sprintf(msgbuf, ! "%s%s takes %s %d argument%s (%d given)", fname==NULL ? "function" : fname, fname==NULL ? "" : "()", --- 1139,1143 ---- if (message == NULL) { sprintf(msgbuf, ! "%.200s%s takes %s %d argument%s (%d given)", fname==NULL ? "function" : fname, fname==NULL ? "" : "()", From tim_one@users.sourceforge.net Sat Oct 27 08:00:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 27 Oct 2001 00:00:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.82,2.83 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv20594/python/Python Modified Files: getargs.c Log Message: vgetargskeywords: Now that it's clear that nkwlist must equal max, and we're ensuring that's true during the format parse, get rid of nkwlist. Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.82 retrieving revision 2.83 diff -C2 -d -r2.82 -r2.83 *** getargs.c 2001/10/27 06:53:00 2.82 --- getargs.c 2001/10/27 07:00:56 2.83 *************** *** 1033,1037 **** int min, max; char *formatsave; ! int i, len, nargs, nkeywords, nkwlist; char *msg, *ks, **p; int pos, match, converted; --- 1033,1037 ---- int min, max; char *formatsave; ! int i, len, nargs, nkeywords; char *msg, *ks, **p; int pos, match, converted; *************** *** 1094,1098 **** } - nkwlist = max; nargs = PyTuple_GET_SIZE(args); nkeywords = keywords == NULL ? 0 : PyDict_Size(keywords); --- 1094,1097 ---- *************** *** 1171,1175 **** string where it was left after processing args */ converted = 0; ! for (i = nargs; i < nkwlist; i++) { PyObject *item; if (*format == '|') --- 1170,1174 ---- string where it was left after processing args */ converted = 0; ! for (i = nargs; i < max; i++) { PyObject *item; if (*format == '|') *************** *** 1203,1207 **** match = 0; ks = PyString_AsString(key); ! for (i = 0; i < nkwlist; i++) { if (!strcmp(ks, kwlist[i])) { match = 1; --- 1202,1206 ---- match = 0; ks = PyString_AsString(key); ! for (i = 0; i < max; i++) { if (!strcmp(ks, kwlist[i])) { match = 1; From tim_one@users.sourceforge.net Sat Oct 27 08:25:11 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 27 Oct 2001 00:25:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python getargs.c,2.83,2.84 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv22673/python/Python Modified Files: getargs.c Log Message: vgetargskeywords() + Squash another potential buffer overrun. + Simplify the keyword-arg loop by decrementing the count of keywords remaining instead of incrementing Yet Another Variable; also break out early if the number of keyword args remaining hits 0. Since I hit the function's closing curly brace with this patch, that's enough of this for now . Index: getargs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v retrieving revision 2.83 retrieving revision 2.84 diff -C2 -d -r2.83 -r2.84 *** getargs.c 2001/10/27 07:00:56 2.83 --- getargs.c 2001/10/27 07:25:06 2.84 *************** *** 1034,1040 **** char *formatsave; int i, len, nargs, nkeywords; ! char *msg, *ks, **p; ! int pos, match, converted; ! PyObject *key, *value; assert(args != NULL && PyTuple_Check(args)); --- 1034,1038 ---- char *formatsave; int i, len, nargs, nkeywords; ! char *msg, **p; assert(args != NULL && PyTuple_Check(args)); *************** *** 1151,1155 **** return 0; } ! for (i = 0; i < nargs; i++) { if (*format == '|') --- 1149,1154 ---- return 0; } ! ! /* convert the positional arguments */ for (i = 0; i < nargs; i++) { if (*format == '|') *************** *** 1163,1167 **** } ! /* handle no keyword parameters in call */ if (nkeywords == 0) return 1; --- 1162,1166 ---- } ! /* handle no keyword parameters in call */ if (nkeywords == 0) return 1; *************** *** 1169,1173 **** /* convert the keyword arguments; this uses the format string where it was left after processing args */ - converted = 0; for (i = nargs; i < max; i++) { PyObject *item; --- 1168,1171 ---- *************** *** 1183,1187 **** return 0; } ! converted++; } else if (PyErr_Occurred()) --- 1181,1187 ---- return 0; } ! --nkeywords; ! if (nkeywords == 0) ! break; } else if (PyErr_Occurred()) *************** *** 1197,1205 **** /* make sure there are no extraneous keyword arguments */ ! pos = 0; ! if (converted < nkeywords) { while (PyDict_Next(keywords, &pos, &key, &value)) { ! match = 0; ! ks = PyString_AsString(key); for (i = 0; i < max; i++) { if (!strcmp(ks, kwlist[i])) { --- 1197,1206 ---- /* make sure there are no extraneous keyword arguments */ ! if (nkeywords > 0) { ! PyObject *key, *value; ! int pos = 0; while (PyDict_Next(keywords, &pos, &key, &value)) { ! int match = 0; ! char *ks = PyString_AsString(key); for (i = 0; i < max; i++) { if (!strcmp(ks, kwlist[i])) { *************** *** 1209,1221 **** } if (!match) { ! sprintf(msgbuf, ! "%s is an invalid keyword argument for this function", ! ks); ! PyErr_SetString(PyExc_TypeError, msgbuf); return 0; } } } ! return 1; } --- 1210,1222 ---- } if (!match) { ! PyErr_Format(PyExc_TypeError, ! "'%s' is an invalid keyword " ! "argument for this function", ! ks); return 0; } } } ! return 1; } From mal@lemburg.com Sat Oct 27 09:38:26 2001 From: mal@lemburg.com (M.-A. Lemburg) Date: Sat, 27 Oct 2001 10:38:26 +0200 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.87,2.88 References: <3BD9CE5E.F43ED33A@lemburg.com> <15322.7588.106800.771227@grendel.zope.com> <15322.9917.871606.312849@anthem.wooz.org> Message-ID: <3BDA7282.E00EECFC@lemburg.com> "Barry A. Warsaw" wrote: > > >>>>> "Fred" == Fred L Drake, Jr writes: > > >> Just curious: why didn't you call them ...FunctionObjArgs() ? > >> (with the 'j') > > Fred> No particular reason -- it just felt a little nicer. I > Fred> don't think there's a precedence for either in the C API. > Fred> If there is and I missed it, these should be adjusted to > Fred> conform to the precedent. There probably is no precedent, but "Ob" looks weird to me :-) > `Obj' == +0 > > `Object' == +1 Anything with a substring of "Obj" will do, IMHO ;-) Maybe we should even go for the full monty and call them: Py..._FunctionPyObjectArgs() ... after all, that's what the function takes as arguments. -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Consulting & Company: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/ From fredrik@pythonware.com Sat Oct 27 10:20:54 2001 From: fredrik@pythonware.com (Fredrik Lundh) Date: Sat, 27 Oct 2001 11:20:54 +0200 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.87,2.88 References: <3BD9CE5E.F43ED33A@lemburg.com> <15322.7588.106800.771227@grendel.zope.com> Message-ID: <01ce01c15ec9$04523b60$ced241d5@hagrid> Fred wrote: > M.-A. Lemburg writes: > > Just curious: why didn't you call them ...FunctionObjArgs() ? (with > > the 'j') > > No particular reason -- it just felt a little nicer. I don't think > there's a precedence for either in the C API. If there is and I > missed it, these should be adjusted to conform to the precedent. from what I can tell, "ob" is used as a prefix for PyObject struct members, but never in function/macro names. don't think "Ob" is ever used (after all, it means Obligatory, not Object [1] ;-) "obj" is used in the func/proc pointers (intobjargproc etc), and "Obj" is used in the mac toolbox. everything else uses "Object" 1) http://foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi?query=ob- From guido@python.org Sat Oct 27 16:58:10 2001 From: guido@python.org (Guido van Rossum) Date: Sat, 27 Oct 2001 11:58:10 -0400 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.87,2.88 In-Reply-To: Your message of "Sat, 27 Oct 2001 11:20:54 +0200." <01ce01c15ec9$04523b60$ced241d5@hagrid> References: <3BD9CE5E.F43ED33A@lemburg.com> <15322.7588.106800.771227@grendel.zope.com> <01ce01c15ec9$04523b60$ced241d5@hagrid> Message-ID: <200110271558.LAA25348@cj20424-a.reston1.va.home.com> Given that these functions are supposed to be enticing conveniences and their names are already pretty long, I propose we should use "ObjArgs". --Guido van Rossum (home page: http://www.python.org/~guido/) From tim_one@users.sourceforge.net Sat Oct 27 19:27:50 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 27 Oct 2001 11:27:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.115,2.116 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv30140/python/Objects Modified Files: dictobject.c Log Message: dictionary() constructor: + Change keyword arg name from "x" to "items". People passing a mapping object can stretch their imaginations . + Simplify the docstring text. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.115 retrieving revision 2.116 diff -C2 -d -r2.115 -r2.116 *** dictobject.c 2001/10/26 05:06:50 2.115 --- dictobject.c 2001/10/27 18:27:48 2.116 *************** *** 1782,1786 **** { PyObject *arg = NULL; ! static char *kwlist[] = {"x", 0}; int result = 0; --- 1782,1786 ---- { PyObject *arg = NULL; ! static char *kwlist[] = {"items", 0}; int result = 0; *************** *** 1808,1817 **** "dictionary(mapping) -> new dict initialized from a mapping object's\n" " (key, value) pairs.\n" ! "dictionary(seq) -> new dict initialized from the 2-element elements of\n" ! " a sequence; for example, from mapping.items(). seq must be an\n" ! " iterable object, producing iterable objects each producing exactly\n" ! " two objects, the first of which is used as a key and the second as\n" ! " its value. If a given key is seen more than once, the dict retains\n" ! " the last value associated with it."; PyTypeObject PyDict_Type = { --- 1808,1815 ---- "dictionary(mapping) -> new dict initialized from a mapping object's\n" " (key, value) pairs.\n" ! "dictionary(seq) -> new dict initialized as if via:\n" ! " d = {}\n" ! " for k, v in seq:\n" ! " d[k] = v"; PyTypeObject PyDict_Type = { From tim_one@users.sourceforge.net Sat Oct 27 19:27:50 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 27 Oct 2001 11:27:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.96,1.97 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv30140/python/Lib/test Modified Files: test_descr.py Log Message: dictionary() constructor: + Change keyword arg name from "x" to "items". People passing a mapping object can stretch their imaginations . + Simplify the docstring text. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.96 retrieving revision 1.97 diff -C2 -d -r1.96 -r1.97 *** test_descr.py 2001/10/26 20:57:38 1.96 --- test_descr.py 2001/10/27 18:27:47 1.97 *************** *** 179,188 **** d = dictionary({}) vereq(d, {}) ! d = dictionary(x={}) vereq(d, {}) d = dictionary({1: 2, 'a': 'b'}) vereq(d, {1: 2, 'a': 'b'}) vereq(d, dictionary(d.items())) ! vereq(d, dictionary(x=d.iteritems())) for badarg in 0, 0L, 0j, "0", [0], (0,): try: --- 179,188 ---- d = dictionary({}) vereq(d, {}) ! d = dictionary(items={}) vereq(d, {}) d = dictionary({1: 2, 'a': 'b'}) vereq(d, {1: 2, 'a': 'b'}) vereq(d, dictionary(d.items())) ! vereq(d, dictionary(items=d.iteritems())) for badarg in 0, 0L, 0j, "0", [0], (0,): try: *************** *** 227,231 **** Mapping.keys = lambda self: self.dict.keys() Mapping.__getitem__ = lambda self, i: self.dict[i] ! d = dictionary(x=Mapping()) vereq(d, Mapping.dict) --- 227,231 ---- Mapping.keys = lambda self: self.dict.keys() Mapping.__getitem__ = lambda self, i: self.dict[i] ! d = dictionary(items=Mapping()) vereq(d, Mapping.dict) *************** *** 1866,1870 **** vereq(tuple(sequence=range(3)), (0, 1, 2)) vereq(list(sequence=(0, 1, 2)), range(3)) ! vereq(dictionary(x={1: 2}), {1: 2}) for constructor in (int, float, long, complex, str, unicode, --- 1866,1870 ---- vereq(tuple(sequence=range(3)), (0, 1, 2)) vereq(list(sequence=(0, 1, 2)), range(3)) ! vereq(dictionary(items={1: 2}), {1: 2}) for constructor in (int, float, long, complex, str, unicode, From tim_one@users.sourceforge.net Sat Oct 27 20:37:50 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 27 Oct 2001 12:37:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.97,2.98 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv12753/python/Include Modified Files: object.h Log Message: SF bug #475327: type() produces incorrect error msg object.h: Added PyType_CheckExact macro. typeobject.c, type_new(): + Use the new macro. + Assert that the arguments have the right types rather than do incomplete runtime checks "sometimes". + If this isn't the 1-argument flavor() of type, and there aren't 3 args total, produce a "types() takes 1 or 3 args" msg before PyArg_ParseTupleAndKeywords produces a "takes exactly 3" msg. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.97 retrieving revision 2.98 diff -C2 -d -r2.97 -r2.98 *** object.h 2001/10/15 22:03:31 2.97 --- object.h 2001/10/27 19:37:47 2.98 *************** *** 313,316 **** --- 313,317 ---- #define PyType_Check(op) PyObject_TypeCheck(op, &PyType_Type) + #define PyType_CheckExact(op) ((op)->ob_type == &PyType_Type) extern DL_IMPORT(int) PyType_Ready(PyTypeObject *); From tim_one@users.sourceforge.net Sat Oct 27 20:37:50 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 27 Oct 2001 12:37:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.113,2.114 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12753/python/Objects Modified Files: typeobject.c Log Message: SF bug #475327: type() produces incorrect error msg object.h: Added PyType_CheckExact macro. typeobject.c, type_new(): + Use the new macro. + Assert that the arguments have the right types rather than do incomplete runtime checks "sometimes". + If this isn't the 1-argument flavor() of type, and there aren't 3 args total, produce a "types() takes 1 or 3 args" msg before PyArg_ParseTupleAndKeywords produces a "takes exactly 3" msg. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.113 retrieving revision 2.114 diff -C2 -d -r2.113 -r2.114 *** typeobject.c 2001/10/26 04:26:11 2.113 --- typeobject.c 2001/10/27 19:37:48 2.114 *************** *** 714,724 **** int i, nbases, nslots, slotoffset, add_dict, add_weak; /* Special case: type(x) should return x->ob_type */ ! if (metatype == &PyType_Type && ! PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 && ! (kwds == NULL || (PyDict_Check(kwds) && PyDict_Size(kwds) == 0))) { ! PyObject *x = PyTuple_GET_ITEM(args, 0); ! Py_INCREF(x->ob_type); ! return (PyObject *) x->ob_type; } --- 714,739 ---- int i, nbases, nslots, slotoffset, add_dict, add_weak; + assert(args != NULL && PyTuple_Check(args)); + assert(kwds == NULL || PyDict_Check(kwds)); + /* Special case: type(x) should return x->ob_type */ ! { ! const int nargs = PyTuple_GET_SIZE(args); ! const int nkwds = kwds == NULL ? 0 : PyDict_Size(kwds); ! ! if (PyType_CheckExact(metatype) && nargs == 1 && nkwds == 0) { ! PyObject *x = PyTuple_GET_ITEM(args, 0); ! Py_INCREF(x->ob_type); ! return (PyObject *) x->ob_type; ! } ! ! /* SF bug 475327 -- if that didn't trigger, we need 3 ! arguments. but PyArg_ParseTupleAndKeywords below may give ! a msg saying type() needs exactly 3. */ ! if (nargs + nkwds != 3) { ! PyErr_SetString(PyExc_TypeError, ! "type() takes 1 or 3 arguments"); ! return NULL; ! } } From gvanrossum@users.sourceforge.net Sat Oct 27 22:16:18 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 27 Oct 2001 14:16:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/RISCOS/Modules riscosmodule.c,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/RISCOS/Modules In directory usw-pr-cvs1:/tmp/cvs-serv3663/RISCOS/Modules Modified Files: riscosmodule.c Log Message: SF patch #475657 (Dietmar Schwertberger) RISCOS/Makefile: include structseq and weakrefobject; changes to keep command line length below 2048 RISCOS/Modules/riscosmodule.c: typos from the stat structseq patch Include/pyport.h: don't re-#define __attribute__(__x) on RISC OS as it is already defined in c library Index: riscosmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/RISCOS/Modules/riscosmodule.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** riscosmodule.c 2001/10/24 20:13:15 1.3 --- riscosmodule.c 2001/10/27 21:16:16 1.4 *************** *** 8,11 **** --- 8,12 ---- #include "Python.h" + #include "structseq.h" #include *************** *** 143,147 **** { "st_ftype", "file type" }, { "st_attrs", "attributes" }, ! { "st_obtype", "object type" } { 0 } }; --- 144,148 ---- { "st_ftype", "file type" }, { "st_attrs", "attributes" }, ! { "st_obtype", "object type" }, { 0 } }; *************** *** 195,199 **** PyInt_FromLong((long) at)); /*attributes*/ PyStructSequence_SET_ITEM(v, 12, ! PyInt_FromLong((long) ot)); /*object type*/ if (PyErr_Occurred()) { --- 196,200 ---- PyInt_FromLong((long) at)); /*attributes*/ PyStructSequence_SET_ITEM(v, 12, ! PyInt_FromLong((long) ob)); /*object type*/ if (PyErr_Occurred()) { From gvanrossum@users.sourceforge.net Sat Oct 27 22:16:18 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 27 Oct 2001 14:16:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/RISCOS Makefile,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/RISCOS In directory usw-pr-cvs1:/tmp/cvs-serv3663/RISCOS Modified Files: Makefile Log Message: SF patch #475657 (Dietmar Schwertberger) RISCOS/Makefile: include structseq and weakrefobject; changes to keep command line length below 2048 RISCOS/Modules/riscosmodule.c: typos from the stat structseq patch Include/pyport.h: don't re-#define __attribute__(__x) on RISC OS as it is already defined in c library Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/RISCOS/Makefile,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Makefile 2001/10/24 20:04:51 1.3 --- Makefile 2001/10/27 21:16:16 1.4 *************** *** 10,19 **** EXPAT = $(LIBSROOT).expat.lib ! OBJSCAN = $(DLKLIB).objscan ! MAKEDLK = $(DLKLIB).makedlk # change from time to time (don't forget to change !Boot also) TARGET=Python22 ! BUILD=23 --- 10,19 ---- EXPAT = $(LIBSROOT).expat.lib ! OBJSCAN = objscan ! MAKEDLK = makedlk # change from time to time (don't forget to change !Boot also) TARGET=Python22 ! BUILD=25 *************** *** 165,169 **** @.^.Objects.o.unicodectype\ @.^.Objects.o.unicodeobject\ ! @.^.Objects.o.descrobject --- 165,171 ---- @.^.Objects.o.unicodectype\ @.^.Objects.o.unicodeobject\ ! @.^.Objects.o.descrobject\ ! @.^.Objects.o.weakrefobject\ ! @.^.Objects.o.structseq *************** *** 419,422 **** --- 421,425 ---- -wipe @.^.Lib.plat-riscos.*/pyd ~C~V remove s.linktab + remove @.^.LibPython clean-support: From gvanrossum@users.sourceforge.net Sat Oct 27 22:16:18 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 27 Oct 2001 14:16:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include pyport.h,2.39,2.40 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv3663/Include Modified Files: pyport.h Log Message: SF patch #475657 (Dietmar Schwertberger) RISCOS/Makefile: include structseq and weakrefobject; changes to keep command line length below 2048 RISCOS/Modules/riscosmodule.c: typos from the stat structseq patch Include/pyport.h: don't re-#define __attribute__(__x) on RISC OS as it is already defined in c library Index: pyport.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pyport.h,v retrieving revision 2.39 retrieving revision 2.40 diff -C2 -d -r2.39 -r2.40 *** pyport.h 2001/10/24 20:27:28 2.39 --- pyport.h 2001/10/27 21:16:16 2.40 *************** *** 454,460 **** * Hide GCC attributes from compilers that don't support them. */ ! #if !defined(__GNUC__) || __GNUC__ < 2 || \ ! (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || \ ! defined(NEXT) #define __attribute__(__x) #endif --- 454,461 ---- * Hide GCC attributes from compilers that don't support them. */ ! #if (!defined(__GNUC__) || __GNUC__ < 2 || \ ! (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || \ ! defined(NEXT) ) && \ ! !defined(RISCOS) #define __attribute__(__x) #endif From gvanrossum@users.sourceforge.net Sat Oct 27 23:20:49 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 27 Oct 2001 15:20:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.188,1.189 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv18477 Modified Files: socketmodule.c Log Message: Made SocketType and socket the same thing: a subclassable type whose constructor acts just like socket() before. All three arguments have a sensible default now; socket() is equivalent to socket(AF_INET, SOCK_STREAM). One minor issue: the socket() function and the SocketType had different doc strings; socket.__doc__ gave the signature, SocketType.__doc__ gave the methods. I've merged these for now, but maybe the list of methods is no longer necessary since it can easily be recovered through socket.__dict__.keys(). The problem with keeping it is that the total doc string is a bit long (34 lines -- it scrolls of a standard tty screen). Another general issue with the socket module is that it's a big mess. There's pages and pages of random platform #ifdefs, and the naming conventions are totally wrong: it uses Py prefixes and CapWords for static functions. That's a cleanup for another day... (Also I think the big starting comment that summarizes the API can go -- it's a repeat of the docstring.) Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.188 retrieving revision 1.189 diff -C2 -d -r1.188 -r1.189 *** socketmodule.c 2001/10/26 03:25:00 1.188 --- socketmodule.c 2001/10/27 22:20:47 1.189 *************** *** 10,15 **** - only AF_INET, AF_INET6 and AF_UNIX address families are supported in a portable manner, though AF_PACKET is supported under Linux. ! - no read/write operations (use send/recv or makefile instead) ! - additional restrictions apply on Windows Module interface: --- 10,15 ---- - only AF_INET, AF_INET6 and AF_UNIX address families are supported in a portable manner, though AF_PACKET is supported under Linux. ! - no read/write operations (use sendall/recv or makefile instead) ! - additional restrictions apply on Windows (compensated for by socket.py) Module interface: *************** *** 78,81 **** --- 78,84 ---- #include "Python.h" + /* XXX This is a terrible mess of of platform-dependent preprocessor hacks. + I hope some day someone can clean this up please... */ + /* Hacks for gethostbyname_r(). On some non-Linux platforms, the configure script doesn't get this right, so we hardcode some platform checks below. *************** *** 268,271 **** --- 271,278 ---- #endif + + /* XXX There's a problem here: *static* functions are not supposed to have + a Py prefix (or use CapitalizedWords). Later... */ + /* Global variable holding the exception type for errors detected by this module (but not argument type or memory errors, etc.). */ *************** *** 461,465 **** typedef struct { PyObject_HEAD ! SOCKET_T sock_fd; /* Socket file descriptor */ int sock_family; /* Address family, e.g., AF_INET */ int sock_type; /* Socket type, e.g., SOCK_STREAM */ --- 468,472 ---- typedef struct { PyObject_HEAD ! SOCKET_T sock_fd; /* Socket file descriptor */ int sock_family; /* Address family, e.g., AF_INET */ int sock_type; /* Socket type, e.g., SOCK_STREAM */ *************** *** 512,515 **** --- 519,543 ---- + /* Initialize a new socket object. */ + + static void + init_sockobject(PySocketSockObject *s, + SOCKET_T fd, int family, int type, int proto) + { + #ifdef RISCOS + int block = 1; + #endif + s->sock_fd = fd; + s->sock_family = family; + s->sock_type = type; + s->sock_proto = proto; + #ifdef RISCOS + if(taskwindow) { + socketioctl(s->sock_fd, 0x80046679, (u_long*)&block); + } + #endif + } + + /* Create a new socket object. This just creates the object and initializes it. *************** *** 520,540 **** PySocketSock_New(SOCKET_T fd, int family, int type, int proto) { - #ifdef RISCOS - int block = 1; - #endif PySocketSockObject *s; ! PySocketSock_Type.ob_type = &PyType_Type; ! s = PyObject_New(PySocketSockObject, &PySocketSock_Type); ! if (s != NULL) { ! s->sock_fd = fd; ! s->sock_family = family; ! s->sock_type = type; ! s->sock_proto = proto; ! #ifdef RISCOS ! if(taskwindow) { ! socketioctl(s->sock_fd, 0x80046679, (u_long*)&block); ! } ! #endif ! } return s; } --- 548,556 ---- PySocketSock_New(SOCKET_T fd, int family, int type, int proto) { PySocketSockObject *s; ! s = (PySocketSockObject *) ! PyType_GenericNew(&PySocketSock_Type, NULL, NULL); ! if (s != NULL) ! init_sockobject(s, fd, family, type, proto); return s; } *************** *** 1721,1734 **** if (s->sock_fd != -1) (void) SOCKETCLOSE(s->sock_fd); ! PyObject_Del(s); ! } ! ! ! /* Return a socket object's named attribute. */ ! ! static PyObject * ! PySocketSock_getattr(PySocketSockObject *s, char *name) ! { ! return Py_FindMethod(PySocketSock_methods, (PyObject *) s, name); } --- 1737,1741 ---- if (s->sock_fd != -1) (void) SOCKETCLOSE(s->sock_fd); ! s->ob_type->tp_free((PyObject *)s); } *************** *** 1755,1775 **** /* Type object for socket objects. */ static PyTypeObject PySocketSock_Type = { PyObject_HEAD_INIT(0) /* Must fill in type value later */ ! 0, ! "socket", ! sizeof(PySocketSockObject), ! 0, ! (destructor)PySocketSock_dealloc, /*tp_dealloc*/ ! 0, /*tp_print*/ ! (getattrfunc)PySocketSock_getattr, /*tp_getattr*/ ! 0, /*tp_setattr*/ ! 0, /*tp_compare*/ ! (reprfunc)PySocketSock_repr, /*tp_repr*/ ! 0, /*tp_as_number*/ ! 0, /*tp_as_sequence*/ ! 0, /*tp_as_mapping*/ }; --- 1762,1895 ---- + /* Create a new, uninitialized socket object. */ + + static PyObject * + PySocketSock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { + PyObject *new; + + new = type->tp_alloc(type, 0); + if (new != NULL) + ((PySocketSockObject *)new)->sock_fd = -1; + return new; + } + + + /* Initialize a new socket object. */ + + /*ARGSUSED*/ + static int + PySocketSock_init(PyObject *self, PyObject *args, PyObject *kwds) + { + PySocketSockObject *s = (PySocketSockObject *)self; + SOCKET_T fd; + int family = AF_INET, type = SOCK_STREAM, proto = 0; + static char *keywords[] = {"family", "type", "proto", 0}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "|iii:socket", keywords, + &family, &type, &proto)) + return -1; + Py_BEGIN_ALLOW_THREADS + fd = socket(family, type, proto); + Py_END_ALLOW_THREADS + #ifdef MS_WINDOWS + if (fd == INVALID_SOCKET) + #else + if (fd < 0) + #endif + { + PySocket_Err(); + return -1; + } + init_sockobject(s, fd, family, type, proto); + /* From now on, ignore SIGPIPE and let the error checking + do the work. */ + #ifdef SIGPIPE + (void) signal(SIGPIPE, SIG_IGN); + #endif + return 0; + } + + /* Type object for socket objects. */ + static char socket_doc[] = + "socket([family[, type[, proto]]]) -> socket object\n\ + \n\ + Open a socket of the given type. The family argument specifies the\n\ + address family; it defaults to AF_INET. The type argument specifies\n\ + whether this is a stream (SOCK_STREAM, this is the default)\n\ + or datagram (SOCK_DGRAM) socket. The protocol argument defaults to 0,\n\ + specifying the default protocol.\n\ + \n\ + A socket represents one endpoint of a network connection.\n\ + \n\ + Methods:\n\ + \n\ + accept() -- accept a connection, returning new socket and client address\n\ + bind() -- bind the socket to a local address\n\ + close() -- close the socket\n\ + connect() -- connect the socket to a remote address\n\ + connect_ex() -- connect, return an error code instead of an exception \n\ + dup() -- return a new socket object identical to the current one (*)\n\ + fileno() -- return underlying file descriptor\n\ + getpeername() -- return remote address (*)\n\ + getsockname() -- return local address\n\ + getsockopt() -- get socket options\n\ + listen() -- start listening for incoming connections\n\ + makefile() -- return a file object corresponding tot the socket (*)\n\ + recv() -- receive data\n\ + recvfrom() -- receive data and sender's address\n\ + send() -- send data, may not send all of it\n\ + sendall() -- send all data\n\ + sendto() -- send data to a given address\n\ + setblocking() -- set or clear the blocking I/O flag\n\ + setsockopt() -- set socket options\n\ + shutdown() -- shut down traffic in one or both directions\n\ + \n\ + (*) not available on all platforms!)"; + static PyTypeObject PySocketSock_Type = { PyObject_HEAD_INIT(0) /* Must fill in type value later */ ! 0, /* ob_size */ ! "socket.socket", /* tp_name */ ! sizeof(PySocketSockObject), /* tp_basicsize */ ! 0, /* tp_itemsize */ ! (destructor)PySocketSock_dealloc, /* tp_dealloc */ ! 0, /* tp_print */ ! 0, /* tp_getattr */ ! 0, /* tp_setattr */ ! 0, /* tp_compare */ ! (reprfunc)PySocketSock_repr, /* tp_repr */ ! 0, /* tp_as_number */ ! 0, /* tp_as_sequence */ ! 0, /* tp_as_mapping */ ! 0, /* tp_hash */ ! 0, /* tp_call */ ! 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ ! 0, /* tp_setattro */ ! 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ ! socket_doc, /* tp_doc */ ! 0, /* tp_traverse */ ! 0, /* tp_clear */ ! 0, /* tp_richcompare */ ! 0, /* tp_weaklistoffset */ ! 0, /* tp_iter */ ! 0, /* tp_iternext */ ! PySocketSock_methods, /* tp_methods */ ! 0, /* tp_members */ ! 0, /* tp_getset */ ! 0, /* tp_base */ ! 0, /* tp_dict */ ! 0, /* tp_descr_get */ ! 0, /* tp_descr_set */ ! 0, /* tp_dictoffset */ ! PySocketSock_init, /* tp_init */ ! PyType_GenericAlloc, /* tp_alloc */ ! PySocketSock_new, /* tp_new */ ! _PyObject_Del, /* tp_free */ }; *************** *** 2150,2198 **** - /* Python interface to socket(family, type, proto). - The third (protocol) argument is optional. - Return a new socket object. */ - - /*ARGSUSED*/ - static PyObject * - PySocket_socket(PyObject *self, PyObject *args) - { - PySocketSockObject *s; - SOCKET_T fd; - int family, type, proto = 0; - if (!PyArg_ParseTuple(args, "ii|i:socket", &family, &type, &proto)) - return NULL; - Py_BEGIN_ALLOW_THREADS - fd = socket(family, type, proto); - Py_END_ALLOW_THREADS - #ifdef MS_WINDOWS - if (fd == INVALID_SOCKET) - #else - if (fd < 0) - #endif - return PySocket_Err(); - s = PySocketSock_New(fd, family, type, proto); - /* If the object can't be created, don't forget to close the - file descriptor again! */ - if (s == NULL) - (void) SOCKETCLOSE(fd); - /* From now on, ignore SIGPIPE and let the error checking - do the work. */ - #ifdef SIGPIPE - (void) signal(SIGPIPE, SIG_IGN); - #endif - return (PyObject *) s; - } - - static char socket_doc[] = - "socket(family, type[, proto]) -> socket object\n\ - \n\ - Open a socket of the given type. The family argument specifies the\n\ - address family; it is normally AF_INET, sometimes AF_UNIX.\n\ - The type argument specifies whether this is a stream (SOCK_STREAM)\n\ - or datagram (SOCK_DGRAM) socket. The protocol argument defaults to 0,\n\ - specifying the default protocol."; - - #ifndef NO_DUP /* Create a socket object from a numeric file description. --- 2270,2273 ---- *************** *** 2793,2797 **** PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ ! "SSL", /*tp_name*/ sizeof(PySSLObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ --- 2868,2872 ---- PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ ! "SSL", /*tp_name*/ sizeof(PySSLObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ *************** *** 2887,2892 **** {"getprotobyname", PySocket_getprotobyname, METH_VARARGS,getprotobyname_doc}, - {"socket", PySocket_socket, - METH_VARARGS, socket_doc}, #ifndef NO_DUP {"fromfd", PySocket_fromfd, --- 2962,2965 ---- *************** *** 3030,3060 **** for documentation."; - static char sockettype_doc[] = - "A socket represents one endpoint of a network connection.\n\ - \n\ - Methods:\n\ - \n\ - accept() -- accept a connection, returning new socket and client address\n\ - bind() -- bind the socket to a local address\n\ - close() -- close the socket\n\ - connect() -- connect the socket to a remote address\n\ - connect_ex() -- connect, return an error code instead of an exception \n\ - dup() -- return a new socket object identical to the current one (*)\n\ - fileno() -- return underlying file descriptor\n\ - getpeername() -- return remote address (*)\n\ - getsockname() -- return local address\n\ - getsockopt() -- get socket options\n\ - listen() -- start listening for incoming connections\n\ - makefile() -- return a file object corresponding tot the socket (*)\n\ - recv() -- receive data\n\ - recvfrom() -- receive data and sender's address\n\ - send() -- send data\n\ - sendto() -- send data to a given address\n\ - setblocking() -- set or clear the blocking I/O flag\n\ - setsockopt() -- set socket options\n\ - shutdown() -- shut down traffic in one or both directions\n\ - \n\ - (*) not available on all platforms!)"; - DL_EXPORT(void) init_socket(void) --- 3103,3106 ---- *************** *** 3077,3080 **** --- 3123,3127 ---- #endif /* MS_WINDOWS */ #endif /* RISCOS */ + PySocketSock_Type.ob_type = &PyType_Type; #ifdef USE_SSL PySSL_Type.ob_type = &PyType_Type; *************** *** 3118,3124 **** SSL_ERROR_SSL); #endif /* USE_SSL */ - PySocketSock_Type.ob_type = &PyType_Type; - PySocketSock_Type.tp_doc = sockettype_doc; if (PyDict_SetItemString(d, "SocketType", (PyObject *)&PySocketSock_Type) != 0) return; --- 3165,3172 ---- SSL_ERROR_SSL); #endif /* USE_SSL */ if (PyDict_SetItemString(d, "SocketType", + (PyObject *)&PySocketSock_Type) != 0) + return; + if (PyDict_SetItemString(d, "socket", (PyObject *)&PySocketSock_Type) != 0) return; From gvanrossum@users.sourceforge.net Sat Oct 27 23:28:56 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 27 Oct 2001 15:28:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.301,1.302 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv20339 Modified Files: NEWS Log Message: News about the socket type and the HP-UX port. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.301 retrieving revision 1.302 diff -C2 -d -r1.301 -r1.302 *** NEWS 2001/10/26 14:56:06 1.301 --- NEWS 2001/10/27 22:28:54 1.302 *************** *** 18,21 **** --- 18,23 ---- that take keyword arguments are __call__, __init__ and __new__. + - The socket function has been converted to a type; see below. + Core and builtins *************** *** 27,31 **** - The socket module defines a new method for socket objects, sendall(). This is like send() but may make multiple calls to ! send() until all data has been sent. - Various bugfixes to the curses module. There is now a test suite --- 29,35 ---- - The socket module defines a new method for socket objects, sendall(). This is like send() but may make multiple calls to ! send() until all data has been sent. Also, the socket function has ! been converted to a subclassable type, like list and tuple (etc.) ! before it; socket and SocketType are now the same thing. - Various bugfixes to the curses module. There is now a test suite *************** *** 54,57 **** --- 58,64 ---- New platforms + + - We've finally confirmed that this release builds on HP-UX 11.00, + *with* threads, and passes the test suite. - Updated RISCOS port by Dietmar Schwertberger. From fdrake@users.sourceforge.net Sun Oct 28 02:35:03 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 27 Oct 2001 19:35:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include abstract.h,2.39,2.40 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv9130/Include Modified Files: abstract.h Log Message: PyObject_CallFunctionObArgs() ---> PyObject_CallFunctionObjArgs() PyObject_CallMethodObArgs() ---> PyObject_CallMethodObjArgs() Index: abstract.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/abstract.h,v retrieving revision 2.39 retrieving revision 2.40 diff -C2 -d -r2.39 -r2.40 *** abstract.h 2001/10/26 16:21:32 2.39 --- abstract.h 2001/10/28 02:35:01 2.40 *************** *** 345,350 **** ! DL_IMPORT(PyObject *) PyObject_CallFunctionObArgs(PyObject *callable, ! ...); /* --- 345,350 ---- ! DL_IMPORT(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable, ! ...); /* *************** *** 358,363 **** ! DL_IMPORT(PyObject *) PyObject_CallMethodObArgs(PyObject *o, ! PyObject *m, ...); /* --- 358,363 ---- ! DL_IMPORT(PyObject *) PyObject_CallMethodObjArgs(PyObject *o, ! PyObject *m, ...); /* From fdrake@users.sourceforge.net Sun Oct 28 02:35:03 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 27 Oct 2001 19:35:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.89,2.90 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9130/Objects Modified Files: abstract.c Log Message: PyObject_CallFunctionObArgs() ---> PyObject_CallFunctionObjArgs() PyObject_CallMethodObArgs() ---> PyObject_CallMethodObjArgs() Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.89 retrieving revision 2.90 diff -C2 -d -r2.89 -r2.90 *** abstract.c 2001/10/27 06:16:31 2.89 --- abstract.c 2001/10/28 02:35:01 2.90 *************** *** 1753,1757 **** static PyObject * ! obargs_mktuple(va_list va) { int i, n = 0; --- 1753,1757 ---- static PyObject * ! objargs_mktuple(va_list va) { int i, n = 0; *************** *** 1779,1783 **** PyObject * ! PyObject_CallMethodObArgs(PyObject *callable, PyObject *name, ...) { PyObject *args, *tmp; --- 1779,1783 ---- PyObject * ! PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...) { PyObject *args, *tmp; *************** *** 1793,1797 **** /* count the args */ va_start(vargs, name); ! args = obargs_mktuple(vargs); va_end(vargs); if (args == NULL) { --- 1793,1797 ---- /* count the args */ va_start(vargs, name); ! args = objargs_mktuple(vargs); va_end(vargs); if (args == NULL) { *************** *** 1807,1811 **** PyObject * ! PyObject_CallFunctionObArgs(PyObject *callable, ...) { PyObject *args, *tmp; --- 1807,1811 ---- PyObject * ! PyObject_CallFunctionObjArgs(PyObject *callable, ...) { PyObject *args, *tmp; *************** *** 1817,1821 **** /* count the args */ va_start(vargs, callable); ! args = obargs_mktuple(vargs); va_end(vargs); if (args == NULL) --- 1817,1821 ---- /* count the args */ va_start(vargs, callable); ! args = objargs_mktuple(vargs); va_end(vargs); if (args == NULL) From fdrake@users.sourceforge.net Sun Oct 28 02:37:12 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 27 Oct 2001 19:37:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api abstract.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv9432 Modified Files: abstract.tex Log Message: PyObject_CallFunctionObArgs() ---> PyObject_CallFunctionObjArgs() PyObject_CallMethodObArgs() ---> PyObject_CallMethodObjArgs() Index: abstract.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/abstract.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** abstract.tex 2001/10/26 16:38:38 1.3 --- abstract.tex 2001/10/28 02:37:10 1.4 *************** *** 209,215 **** ! \begin{cfuncdesc}{PyObject*}{PyObject_CallFunctionObArgs}{PyObject *callable, ! \moreargs, ! \code{NULL}} Call a callable Python object \var{callable}, with a variable number of \ctype{PyObject*} arguments. The arguments are provided --- 209,215 ---- ! \begin{cfuncdesc}{PyObject*}{PyObject_CallFunctionObjArgs}{PyObject *callable, ! \moreargs, ! \code{NULL}} Call a callable Python object \var{callable}, with a variable number of \ctype{PyObject*} arguments. The arguments are provided *************** *** 220,227 **** ! \begin{cfuncdesc}{PyObject*}{PyObject_CallMethodObArgs}{PyObject *o, ! PyObject *name, ! \moreargs, ! \code{NULL}} Calls a method of the object \var{o}, where the name of the method is given as a Python string object in \var{name}. It is called with --- 220,227 ---- ! \begin{cfuncdesc}{PyObject*}{PyObject_CallMethodObjArgs}{PyObject *o, ! PyObject *name, ! \moreargs, ! \code{NULL}} Calls a method of the object \var{o}, where the name of the method is given as a Python string object in \var{name}. It is called with From fdrake@users.sourceforge.net Sun Oct 28 02:39:05 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 27 Oct 2001 19:39:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api refcounts.dat,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv9628 Modified Files: refcounts.dat Log Message: PyObject_CallFunctionObArgs() ---> PyObject_CallFunctionObjArgs() PyObject_CallMethodObArgs() ---> PyObject_CallMethodObjArgs() Index: refcounts.dat =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/refcounts.dat,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** refcounts.dat 2001/10/26 16:29:22 1.34 --- refcounts.dat 2001/10/28 02:39:03 1.35 *************** *** 720,726 **** PyObject_CallFunction::...:: ! PyObject_CallFunctionObArgs:PyObject*::+1: ! PyObject_CallFunctionObArgs:PyObject*:callable:0: ! PyObject_CallFunctionObArgs::...:: PyObject_CallMethod:PyObject*::+1: --- 720,726 ---- PyObject_CallFunction::...:: ! PyObject_CallFunctionObjArgs:PyObject*::+1: ! PyObject_CallFunctionObjArgs:PyObject*:callable:0: ! PyObject_CallFunctionObjArgs::...:: PyObject_CallMethod:PyObject*::+1: *************** *** 730,737 **** PyObject_CallMethod::...:: ! PyObject_CallMethodObArgs:PyObject*::+1: ! PyObject_CallMethodObArgs:PyObject*:o:0: ! PyObject_CallMethodObArgs:char*:name:: ! PyObject_CallMethodObArgs::...:: PyObject_CallObject:PyObject*::+1: --- 730,737 ---- PyObject_CallMethod::...:: ! PyObject_CallMethodObjArgs:PyObject*::+1: ! PyObject_CallMethodObjArgs:PyObject*:o:0: ! PyObject_CallMethodObjArgs:char*:name:: ! PyObject_CallMethodObjArgs::...:: PyObject_CallObject:PyObject*::+1: From fdrake@acm.org Sun Oct 28 02:32:31 2001 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Sat, 27 Oct 2001 22:32:31 -0400 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.87,2.88 In-Reply-To: <200110271558.LAA25348@cj20424-a.reston1.va.home.com> References: <3BD9CE5E.F43ED33A@lemburg.com> <15322.7588.106800.771227@grendel.zope.com> <01ce01c15ec9$04523b60$ced241d5@hagrid> <200110271558.LAA25348@cj20424-a.reston1.va.home.com> Message-ID: <15323.28223.47723.551577@grendel.zope.com> Guido van Rossum writes: > Given that these functions are supposed to be enticing conveniences > and their names are already pretty long, I propose we should use > "ObjArgs". Sigh. Ok, done. -Fred -- Fred L. Drake, Jr. PythonLabs at Zope Corporation From gvanrossum@users.sourceforge.net Sun Oct 28 12:31:35 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 28 Oct 2001 04:31:35 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.189,1.190 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv3552 Modified Files: socketmodule.c Log Message: Oops. In the tp_name field, the name should be "_socket.socket", not "socket.socket" -- on Windows, "socket.socket" is the wrapper class. Also added the module name to the SSL type (which is not a new-style class -- I don't want to mess with it yet). Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.189 retrieving revision 1.190 diff -C2 -d -r1.189 -r1.190 *** socketmodule.c 2001/10/27 22:20:47 1.189 --- socketmodule.c 2001/10/28 12:31:33 1.190 *************** *** 1854,1858 **** PyObject_HEAD_INIT(0) /* Must fill in type value later */ 0, /* ob_size */ ! "socket.socket", /* tp_name */ sizeof(PySocketSockObject), /* tp_basicsize */ 0, /* tp_itemsize */ --- 1854,1858 ---- PyObject_HEAD_INIT(0) /* Must fill in type value later */ 0, /* ob_size */ ! "_socket.socket", /* tp_name */ sizeof(PySocketSockObject), /* tp_basicsize */ 0, /* tp_itemsize */ *************** *** 2868,2872 **** PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ ! "SSL", /*tp_name*/ sizeof(PySSLObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ --- 2868,2872 ---- PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ ! "_socket.SSL", /*tp_name*/ sizeof(PySSLObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ From effbot@users.sourceforge.net Sun Oct 28 20:15:42 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Sun, 28 Oct 2001 12:15:42 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib sre.py,1.43,1.44 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv26414/Lib Modified Files: sre.py Log Message: added finditer sanity check Index: sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre.py,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** sre.py 2001/10/24 22:16:30 1.43 --- sre.py 2001/10/28 20:15:40 1.44 *************** *** 168,174 **** if sys.hexversion >= 0x02020000: def finditer(pattern, string): ! """Return an iterator over all non-overlapping matches in ! the string. For each match, the iterator returns a match ! object. Empty matches are included in the result.""" --- 168,173 ---- if sys.hexversion >= 0x02020000: def finditer(pattern, string): ! """Return an iterator over all non-overlapping matches in the ! string. For each match, the iterator returns a match object. Empty matches are included in the result.""" From effbot@users.sourceforge.net Sun Oct 28 20:15:43 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Sun, 28 Oct 2001 12:15:43 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_sre.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv26414/Lib/test Modified Files: test_sre.py Log Message: added finditer sanity check Index: test_sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sre.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** test_sre.py 2001/10/22 06:01:56 1.32 --- test_sre.py 2001/10/28 20:15:40 1.33 *************** *** 185,188 **** --- 185,199 ---- test(r"""sre.findall(r"(a|(b))", "aba")""", [("a", ""),("b", "b"),("a", "")]) + if sys.hexversion >= 0x02020000: + if verbose: + print "Running tests on sre.finditer" + def fixup(seq): + # convert iterator to list + if not hasattr(seq, "next") or not hasattr(seq, "__iter__"): + print "finditer returned", type(seq) + return map(lambda item: item.group(0), seq) + # sanity + test(r"""fixup(sre.finditer(r":+", "a:b::c:::d"))""", [":", "::", ":::"]) + if verbose: print "Running tests on sre.match" From gvanrossum@users.sourceforge.net Mon Oct 29 07:13:56 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 28 Oct 2001 23:13:56 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib socket.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv28729 Modified Files: socket.py Log Message: Add 'sendall' to list of socket methods. Index: socket.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/socket.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** socket.py 2001/10/24 20:33:34 1.14 --- socket.py 2001/10/29 07:13:53 1.15 *************** *** 126,130 **** 'bind', 'connect', 'connect_ex', 'fileno', 'listen', 'getpeername', 'getsockname', 'getsockopt', 'setsockopt', ! 'recv', 'recvfrom', 'send', 'sendto', 'setblocking', 'shutdown') class _socketobject: --- 126,130 ---- 'bind', 'connect', 'connect_ex', 'fileno', 'listen', 'getpeername', 'getsockname', 'getsockopt', 'setsockopt', ! 'recv', 'recvfrom', 'send', 'sendall', 'sendto', 'setblocking', 'shutdown') class _socketobject: From gvanrossum@users.sourceforge.net Mon Oct 29 07:14:12 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 28 Oct 2001 23:14:12 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_socket.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv28804 Modified Files: test_socket.py Log Message: Test sendall(). Index: test_socket.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_socket.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** test_socket.py 2001/03/23 17:40:16 1.19 --- test_socket.py 2001/10/29 07:14:10 1.20 *************** *** 125,129 **** if verbose: print 'received:', data ! conn.send(data) conn.close() else: --- 125,129 ---- if verbose: print 'received:', data ! conn.sendall(data) conn.close() else: From gvanrossum@users.sourceforge.net Mon Oct 29 07:18:04 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 28 Oct 2001 23:18:04 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_socketserver.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv29645 Modified Files: test_socketserver.py Log Message: Use sendall() in the stream test instead of send(). Index: test_socketserver.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_socketserver.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_socketserver.py 2001/09/18 02:18:57 1.5 --- test_socketserver.py 2001/10/29 07:18:02 1.6 *************** *** 59,63 **** s = socket.socket(proto, socket.SOCK_STREAM) s.connect(addr) ! s.send(teststring) buf = data = receive(s, 100) while data and '\n' not in buf: --- 59,63 ---- s = socket.socket(proto, socket.SOCK_STREAM) s.connect(addr) ! s.sendall(teststring) buf = data = receive(s, 100) while data and '\n' not in buf: From gvanrossum@users.sourceforge.net Mon Oct 29 14:34:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 29 Oct 2001 06:34:00 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.114,2.115 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9012 Modified Files: typeobject.c Log Message: When overriding __str__ or __repr__, set the tp_print slot to NULL. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.114 retrieving revision 2.115 diff -C2 -d -r2.114 -r2.115 *** typeobject.c 2001/10/27 19:37:48 2.114 --- typeobject.c 2001/10/29 14:33:44 2.115 *************** *** 3381,3386 **** --- 3381,3388 ---- TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, "x.__str__() <==> str(x)"), + TPSLOT("__str__", tp_print, NULL, NULL, ""), TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc, "x.__repr__() <==> repr(x)"), + TPSLOT("__repr__", tp_print, NULL, NULL, ""), TPSLOT("__cmp__", tp_compare, _PyObject_SlotCompare, wrap_cmpfunc, "x.__cmp__(y) <==> cmp(x,y)"), From bwarsaw@users.sourceforge.net Mon Oct 29 15:53:06 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Mon, 29 Oct 2001 07:53:06 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.13,1.14 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv8714 Modified Files: pep-0101.txt Log Message: Add a section called Final Release Notes to collect information about why and how a final release is special. Index: pep-0101.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0101.txt,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** pep-0101.txt 2001/10/25 15:42:57 1.13 --- pep-0101.txt 2001/10/29 15:53:04 1.14 *************** *** 530,534 **** use this to build the MacOS versions. He may send you information about the Mac release that should be merged into the informational ! pages on SourceForge or www.python.org. --- 530,555 ---- use this to build the MacOS versions. He may send you information about the Mac release that should be merged into the informational ! pages on SourceForge or www.python.org. When he's done, he'll ! tag the branch something like "rX.YaZ-mac". He'll also be ! responsible for merging any Mac-related changes back into the ! trunk. ! ! ! Final Release Notes ! ! The Final release of any major release, e.g. Python 2.2 final, has ! special requirements, specifically because it will be one of the ! longest lived releases (i.e. betas don't last more than a couple ! of weeks, but final releases can last for years!). ! ! For this reason we want to have a higher coordination between the ! three major releases: Windows, Mac, and source. The Windows and ! source releases benefit from the close proximity of the respective ! release-bots. But the Mac-bot, Jack Jansen, is 6 hours away. So ! we add this extra step to the release process for a final ! release: ! ! ___ Hold up the final release until Jack approves, or until we ! lose patience . From akuchling@users.sourceforge.net Mon Oct 29 16:06:07 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Mon, 29 Oct 2001 08:06:07 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0264.txt,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv12595 Modified Files: pep-0264.txt Log Message: Fix typo Index: pep-0264.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0264.txt,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** pep-0264.txt 2001/10/26 14:36:22 1.7 --- pep-0264.txt 2001/10/29 16:06:05 1.8 *************** *** 126,130 **** http://sourceforge.net/tracker/?func=detail&atid=305470&aid=449043&group_id=5470 ! After light massagin by Tim Peters, they have now been checked in. --- 126,130 ---- http://sourceforge.net/tracker/?func=detail&atid=305470&aid=449043&group_id=5470 ! After light massaging by Tim Peters, they have now been checked in. From jhylton@users.sourceforge.net Mon Oct 29 16:32:24 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Mon, 29 Oct 2001 08:32:24 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib asyncore.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv21008 Modified Files: asyncore.py Log Message: Fix for SF bug 453099 -- select not defensive And SF patch 473223 -- infinite getattr loop Wrap select() and poll() calls with try/except for EINTR. If EINTR is raised, treat as a response where no fd is ready. In dispatcher constructor, make sure self.socket is always initialized. Index: asyncore.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asyncore.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** asyncore.py 2001/10/18 17:33:19 1.24 --- asyncore.py 2001/10/29 16:32:19 1.25 *************** *** 54,58 **** import os from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \ ! ENOTCONN, ESHUTDOWN try: --- 54,58 ---- import os from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \ ! ENOTCONN, ESHUTDOWN, EINTR try: *************** *** 67,71 **** def poll (timeout=0.0, map=None): - global DEBUG if map is None: map = socket_map --- 67,70 ---- *************** *** 77,81 **** if obj.writable(): w.append (fd) ! r,w,e = select.select (r,w,e, timeout) if DEBUG: --- 76,84 ---- if obj.writable(): w.append (fd) ! try: ! r,w,e = select.select (r,w,e, timeout) ! except select.error, err: ! if err[0] != EINTR: ! raise if DEBUG: *************** *** 159,163 **** if flags: pollster.register(fd, flags) ! r = pollster.poll (timeout) for fd, flags in r: try: --- 162,171 ---- if flags: pollster.register(fd, flags) ! try: ! r = pollster.poll (timeout) ! except select.error, err: ! if err[0] != EINTR: ! raise ! r = [] for fd, flags in r: try: *************** *** 206,209 **** --- 214,219 ---- self.connected = 1 self.addr = sock.getpeername() + else: + self.socket = None def __repr__ (self): *************** *** 242,246 **** def set_socket (self, sock, map=None): ! self.__dict__['socket'] = sock self._fileno = sock.fileno() self.add_channel (map) --- 252,257 ---- def set_socket (self, sock, map=None): ! self.socket = sock ! ## self.__dict__['socket'] = sock self._fileno = sock.fileno() self.add_channel (map) From jhylton@users.sourceforge.net Mon Oct 29 16:44:39 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Mon, 29 Oct 2001 08:44:39 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib asyncore.py,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv24491 Modified Files: asyncore.py Log Message: Use connect_ex() instead of connect(). Removes old XXX comment and possible source of long-delays. Index: asyncore.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asyncore.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** asyncore.py 2001/10/29 16:32:19 1.25 --- asyncore.py 2001/10/29 16:44:37 1.26 *************** *** 54,58 **** import os from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \ ! ENOTCONN, ESHUTDOWN, EINTR try: --- 54,58 ---- import os from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \ ! ENOTCONN, ESHUTDOWN, EINTR, EISCONN try: *************** *** 302,316 **** def connect (self, address): self.connected = 0 ! # XXX why not use connect_ex? ! try: ! self.socket.connect (address) ! except socket.error, why: ! if why[0] in (EINPROGRESS, EALREADY, EWOULDBLOCK): ! return ! else: ! raise socket.error, why ! self.addr = address ! self.connected = 1 ! self.handle_connect() def accept (self): --- 302,313 ---- def connect (self, address): self.connected = 0 ! err = self.socket.connect_ex(address) ! if err in (EINPROGRESS, EALREADY, EWOULDBLOCK): ! return ! if err in (0, EISCONN): ! self.addr = address ! self.connected = 1 ! self.handle_connect() ! raise socket.error, err def accept (self): From fdrake@users.sourceforge.net Mon Oct 29 17:40:43 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 29 Oct 2001 09:40:43 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile,1.229,1.230 Makefile.deps,1.77,1.78 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv9315 Modified Files: Makefile Makefile.deps Log Message: Make sure we generate versions of each file in the Python/C API manual with reference-count annotations; this is needed for the typeset forms of the manuals. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile,v retrieving revision 1.229 retrieving revision 1.230 diff -C2 -d -r1.229 -r1.230 *** Makefile 2001/10/25 15:12:31 1.229 --- Makefile 2001/10/29 17:40:40 1.230 *************** *** 147,150 **** --- 147,152 ---- COMMONPERL= perl/manual.perl perl/python.perl perl/l2hinit.perl + ANNOAPI=api/refcounts.dat tools/anno-api.py + include Makefile.deps *************** *** 174,185 **** # Targets for each document: # Python/C API Reference Manual ! paper-$(PAPER)/api.dvi: paper-$(PAPER)/api.tex $(APIFILES) cd paper-$(PAPER) && $(MKDVI) api.tex ! paper-$(PAPER)/api.pdf: paper-$(PAPER)/api.tex $(APIFILES) cd paper-$(PAPER) && $(MKPDF) api.tex ! paper-$(PAPER)/api.tex: api/api.tex api/refcounts.dat tools/anno-api.py $(PYTHON) $(TOOLSDIR)/anno-api.py -o $@ api/api.tex # Distributing Python Modules --- 176,217 ---- # Targets for each document: # Python/C API Reference Manual ! paper-$(PAPER)/api.dvi: $(ANNOAPIFILES) cd paper-$(PAPER) && $(MKDVI) api.tex ! paper-$(PAPER)/api.pdf: $(ANNOAPIFILES) cd paper-$(PAPER) && $(MKPDF) api.tex ! paper-$(PAPER)/api.tex: api/api.tex $(ANNOAPI) $(PYTHON) $(TOOLSDIR)/anno-api.py -o $@ api/api.tex + + paper-$(PAPER)/abstract.tex: api/abstract.tex $(ANNOAPI) + $(PYTHON) $(TOOLSDIR)/anno-api.py -o $@ api/abstract.tex + + paper-$(PAPER)/concrete.tex: api/concrete.tex $(ANNOAPI) + $(PYTHON) $(TOOLSDIR)/anno-api.py -o $@ api/concrete.tex + + paper-$(PAPER)/exceptions.tex: api/exceptions.tex $(ANNOAPI) + $(PYTHON) $(TOOLSDIR)/anno-api.py -o $@ api/exceptions.tex + + paper-$(PAPER)/init.tex: api/init.tex $(ANNOAPI) + $(PYTHON) $(TOOLSDIR)/anno-api.py -o $@ api/init.tex + + paper-$(PAPER)/intro.tex: api/intro.tex $(ANNOAPI) + $(PYTHON) $(TOOLSDIR)/anno-api.py -o $@ api/intro.tex + + paper-$(PAPER)/memory.tex: api/memory.tex $(ANNOAPI) + $(PYTHON) $(TOOLSDIR)/anno-api.py -o $@ api/memory.tex + + paper-$(PAPER)/newtypes.tex: api/newtypes.tex $(ANNOAPI) + $(PYTHON) $(TOOLSDIR)/anno-api.py -o $@ api/newtypes.tex + + paper-$(PAPER)/refcounting.tex: api/refcounting.tex $(ANNOAPI) + $(PYTHON) $(TOOLSDIR)/anno-api.py -o $@ api/refcounting.tex + + paper-$(PAPER)/utilities.tex: api/utilities.tex $(ANNOAPI) + $(PYTHON) $(TOOLSDIR)/anno-api.py -o $@ api/utilities.tex + + paper-$(PAPER)/veryhigh.tex: api/veryhigh.tex $(ANNOAPI) + $(PYTHON) $(TOOLSDIR)/anno-api.py -o $@ api/veryhigh.tex # Distributing Python Modules Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.77 retrieving revision 1.78 diff -C2 -d -r1.77 -r1.78 *** Makefile.deps 2001/10/12 19:02:35 1.77 --- Makefile.deps 2001/10/29 17:40:40 1.78 *************** *** 32,35 **** --- 32,52 ---- texinputs/reportingbugs.tex + # These files are generated from those listed above, and are used to + # generate the typeset versions of the manuals. The list is defined + # here to make it easier to ensure parallelism. + ANNOAPIFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \ + paper-$(PAPER)/api.tex \ + paper-$(PAPER)/abstract.tex \ + paper-$(PAPER)/concrete.tex \ + paper-$(PAPER)/exceptions.tex \ + paper-$(PAPER)/init.tex \ + paper-$(PAPER)/intro.tex \ + paper-$(PAPER)/memory.tex \ + paper-$(PAPER)/newtypes.tex \ + paper-$(PAPER)/refcounting.tex \ + paper-$(PAPER)/utilities.tex \ + paper-$(PAPER)/veryhigh.tex \ + texinputs/reportingbugs.tex + DOCFILES= $(HOWTOSTYLES) \ texinputs/boilerplate.tex \ From fdrake@users.sourceforge.net Mon Oct 29 17:42:19 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 29 Oct 2001 09:42:19 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/paper-a4 .cvsignore,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/paper-a4 In directory usw-pr-cvs1:/tmp/cvs-serv9821/paper-a4 Modified Files: .cvsignore Log Message: Ignore all *.tex files in the typesetting output directories since there are a bunch of them now. Index: .cvsignore =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/paper-a4/.cvsignore,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** .cvsignore 2000/06/30 19:25:41 1.8 --- .cvsignore 2001/10/29 17:42:17 1.9 *************** *** 14,16 **** *.how README ! api.tex --- 14,16 ---- *.how README ! *.tex From fdrake@users.sourceforge.net Mon Oct 29 17:42:19 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 29 Oct 2001 09:42:19 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/paper-letter .cvsignore,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/paper-letter In directory usw-pr-cvs1:/tmp/cvs-serv9821/paper-letter Modified Files: .cvsignore Log Message: Ignore all *.tex files in the typesetting output directories since there are a bunch of them now. Index: .cvsignore =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/paper-letter/.cvsignore,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** .cvsignore 2000/04/03 04:43:05 1.8 --- .cvsignore 2001/10/29 17:42:17 1.9 *************** *** 14,16 **** *.how README ! api.tex --- 14,16 ---- *.how README ! *.tex From fdrake@users.sourceforge.net Mon Oct 29 17:43:16 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 29 Oct 2001 09:43:16 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/api refcounts.dat,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv10152/api Modified Files: refcounts.dat Log Message: More refcount information. Index: refcounts.dat =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/refcounts.dat,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** refcounts.dat 2001/10/28 02:39:03 1.35 --- refcounts.dat 2001/10/29 17:43:14 1.36 *************** *** 536,539 **** --- 536,552 ---- PyMapping_Values:PyObject*:o:0: + PyMarshal_ReadLastObjectFromFile:PyObject*::+1: + PyMarshal_ReadLastObjectFromFile:FILE*:file:: + + PyMarshal_ReadObjectFromFile:PyObject*::+1: + PyMarshal_ReadObjectFromFile:FILE*:file:: + + PyMarshal_ReadObjectFromString:PyObject*::+1: + PyMarshal_ReadObjectFromString:char*:string:: + PyMarshal_ReadObjectFromString:int:len:: + + PyMarshal_WriteObjectToString:PyObject*::+1: + PyMarshal_WriteObjectToString:PyObject*:value:0: + PyMethod_Class:PyObject*::0: PyMethod_Class:PyObject*:im:0: *************** *** 1096,1099 **** --- 1109,1121 ---- PyTuple_Size:PyTupleObject*:p:0: + PyType_GenericAlloc:PyObject*::+1: + PyType_GenericAlloc:PyObject*:type:0: + PyType_GenericAlloc:int:nitems:0: + + PyType_GenericNew:PyObject*::+1: + PyType_GenericNew:PyObject*:type:0: + PyType_GenericNew:PyObject*:args:0: + PyType_GenericNew:PyObject*:kwds:0: + PyUnicode_Check:int::: PyUnicode_Check:PyObject*:o:0: *************** *** 1371,1374 **** --- 1393,1414 ---- PyUnicode_Contains:PyObject*:container:0: PyUnicode_Contains:PyObject*:element:0: + + PyWeakref_GET_OBJECT:PyObject*::0: + PyWeakref_GET_OBJECT:PyObject*:ref:0: + + PyWeakref_GetObject:PyObject*::+1: + PyWeakref_GetObject:PyObject*:ref:0: + + PyWeakref_NewProxy:PyObject*::+1: + PyWeakref_NewProxy:PyObject*:ob:0: + PyWeakref_NewProxy:PyObject*:callback:0: + + PyWeakref_NewRef:PyObject*::+1: + PyWeakref_NewRef:PyObject*:ob:0: + PyWeakref_NewRef:PyObject*:callback:0: + + PyWrapper_New:PyObject*::+1: + PyWrapper_New:PyObject*:d:0: + PyWrapper_New:PyObject*:self:0: Py_AtExit:int::: From bwarsaw@users.sourceforge.net Mon Oct 29 17:45:12 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Mon, 29 Oct 2001 09:45:12 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0273.txt,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv10779 Modified Files: pep-0273.txt Log Message: Jim's patch for a pointer to the implementation. Index: pep-0273.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0273.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pep-0273.txt 2001/10/26 19:51:28 1.2 --- pep-0273.txt 2001/10/29 17:45:10 1.3 *************** *** 148,152 **** Implementation ! A C implementation exists which works, but which can be made better. --- 148,153 ---- Implementation ! A C implementation is available as SourceForge patch 476047. ! http://sourceforge.net/tracker/index.php?func=detail&aid=476047&group_id=5470&atid=305470 From fdrake@users.sourceforge.net Mon Oct 29 18:01:26 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 29 Oct 2001 10:01:26 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libtime.tex,1.46,1.47 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv15585/lib Modified Files: libtime.tex Log Message: Add additional information on exceptions from time.mktime() and related to improper time tuples passed to various functions. Based on comments from Andreas Jung. Index: libtime.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtime.tex,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -d -r1.46 -r1.47 *** libtime.tex 2001/10/20 04:24:09 1.46 --- libtime.tex 2001/10/29 18:01:24 1.47 *************** *** 74,78 **** \item - The time tuple as returned by \function{gmtime()}, \function{localtime()}, and \function{strptime()}, and accepted by --- 74,77 ---- *************** *** 98,101 **** --- 97,104 ---- result in the correct daylight savings state to be filled in. + When a tuple with an incorrect length is passed to a function + expecting a time tuple, or having elements of the wrong type, a + \exception{TypeError} is raised. + \end{itemize} *************** *** 175,179 **** \emph{local} time, not UTC. It returns a floating point number, for compatibility with \function{time()}. If the input value cannot be ! represented as a valid time, \exception{OverflowError} is raised. The earliest date for which it can generate a time is platform-dependent. \end{funcdesc} --- 178,184 ---- \emph{local} time, not UTC. It returns a floating point number, for compatibility with \function{time()}. If the input value cannot be ! represented as a valid time, either \exception{OverflowError} or ! \exception{ValueError} will be raised (which depends on whether the ! invalid value is caught by Python or the underlying C libraries). The earliest date for which it can generate a time is platform-dependent. \end{funcdesc} From bwarsaw@users.sourceforge.net Mon Oct 29 18:47:01 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Mon, 29 Oct 2001 10:47:01 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0274.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv28265 Modified Files: pep-0274.txt Log Message: Updates and fixes based on community comments. Some of the examples has bugs in them. Also, they should use Python 2.2's {}.iteritems() where appropriate. Renamed and reorg'd the Open Issues section, with an entry about the shortcut syntax, and a question about nested for loop. Added a section on Implementation, noting Python 2.2's new dictionary sequence-of-2-element-sequences constructor. Index: pep-0274.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0274.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pep-0274.txt 2001/10/25 20:28:05 1.1 --- pep-0274.txt 2001/10/29 18:46:59 1.2 *************** *** 8,12 **** Created: 25-Oct-2001 Python-Version: 2.3 ! Post-History: --- 8,12 ---- Created: 25-Oct-2001 Python-Version: 2.3 ! Post-History: 29-Oct-2001 *************** *** 60,64 **** {0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'} ! >>> print {k : v for k, v in someDict.items()} == someDict.copy() 1 --- 60,64 ---- {0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'} ! >>> print {k : v for k, v in someDict.iteritems()} == someDict.copy() 1 *************** *** 67,101 **** >>> def invert(d): ! ... return {v : k for k, v in d} ... >>> d = {0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'} >>> print invert(d) ! {'A' : 0, 'B' : 1, 'C' : 2, 'D' : 4} - >>> print {k, v for k in range(4) for v in range(-4, 0, 1)} - {0 : -4, 1 : -3, 2 : -2, 3 : -1} ! Optional Enhancements ! There is one further shortcut we could adopt. Suppose we wanted ! to create a set of items, such as in the "list_of_email_addrs" ! example above. Here, we're simply taking the target of the for ! loop and turning that into the key for the dict comprehension. ! The assertion is that this would be a common idiom, so the ! shortcut below allows for an easy spelling of it, by allow us to ! omit the "key :" part of the left hand clause: ! >>> print {1 for x in list_of_email_addrs} ! {'barry@zope.com' : 1, 'barry@python.org' : 1, 'guido@python.org' : 1} ! Or say we wanted to map email addresses to the MX record handling ! their mail: ! >>> print {mx_for_addr(x) for x in list_of_email_addrs} ! {'barry@zope.com' : 'mail.zope.com', ! 'barry@python.org' : 'mail.python.org, ! 'guido@python.org' : 'mail.python.org, ! } --- 67,133 ---- >>> def invert(d): ! ... return {v : k for k, v in d.iteritems()} ... >>> d = {0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'} >>> print invert(d) ! {'A' : 0, 'B' : 1, 'C' : 2, 'D' : 3} + Open Issues ! - There is one further shortcut we could adopt. Suppose we wanted ! to create a set of items, such as in the "list_of_email_addrs" ! example above. Here, we're simply taking the target of the for ! loop and turning that into the key for the dict comprehension. ! The assertion is that this would be a common idiom, so the ! shortcut below allows for an easy spelling of it, by allow us to ! omit the "key :" part of the left hand clause: ! >>> print {1 for x in list_of_email_addrs} ! {'barry@zope.com' : 1, 'barry@python.org' : 1, 'guido@python.org' : 1} ! Or say we wanted to map email addresses to the MX record handling ! their mail: ! >>> print {mx_for_addr(x) for x in list_of_email_addrs} ! {'barry@zope.com' : 'mail.zope.com', ! 'barry@python.org' : 'mail.python.org, ! 'guido@python.org' : 'mail.python.org, ! } ! Questions: what about nested loops? Where does the key come ! from? The shortcut probably doesn't save much typing, and comes ! at the expense of legibility, so it's of dubious value. ! ! - Should nested for loops be allowed? The following example, ! taken from an earlier revision of this PEP illustrates the ! problem: ! ! >>> print {k, v for k in range(4) for v in range(-4, 0, 1)} ! ! The intent of this example was to produce a mapping from a ! number to its negative, but this code doesn't work because -- as ! in list comprehensions -- the for loops are nested, not in ! parallel! So the value of this expression is actually ! ! {0: -1, 1: -1, 2: -1, 3: -1} ! ! which seems of dubious value. For symmetry with list ! comprehensions, perhaps this should be allowed, but it might be ! better to disallow this syntax. ! ! ! Implementation ! ! The semantics of dictionary comprehensions can actually be modeled ! in stock Python 2.2, by passing a list comprehension to the ! builtin dictionary constructor: ! ! >>> dictionary([(i, chr(65+i)) for i in range(4)]) ! ! This has two dictinct disadvantages from the proposed syntax ! though. First, it's isn't as legible as a dict comprehension. ! Second, it forces the programmer to create an in-core list object ! first, which could be expensive. From fdrake@users.sourceforge.net Mon Oct 29 20:45:59 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 29 Oct 2001 12:45:59 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules _hotshot.c,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv8984/Modules Modified Files: _hotshot.c Log Message: Make the low-level log-reader object export a dictionary mapping keys to lists of values, giving the contents of all the ADD_INFO records seen so far. This is initialized agressively when the log file is opened, so that whoever is looking at the log reader can always see the initial data loaded into the data stream. ADD_INFO events later in the log file continue to be reported to the application layer as before. Add a new method, addinfo(), to the profiler. This can be used to insert additional ADD_INFO records into the profiler log. Fix the tp_flags and tp_name slots on the type objects. Index: _hotshot.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_hotshot.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** _hotshot.c 2001/10/23 22:26:16 1.7 --- _hotshot.c 2001/10/29 20:45:57 1.8 *************** *** 83,86 **** --- 83,87 ---- typedef struct { PyObject_HEAD + PyObject *info; FILE *logfp; int filled; *************** *** 258,261 **** --- 259,263 ---- #define ERR_EOF -1 #define ERR_EXCEPTION -2 + #define ERR_BAD_RECTYPE -3 #define PISIZE (sizeof(int) + 1) *************** *** 327,330 **** --- 329,399 ---- + static int + unpack_add_info(LogReaderObject *self, int skip_opcode) + { + PyObject *key; + PyObject *value = NULL; + int err; + + if (skip_opcode) { + if (self->buffer[self->index] != WHAT_ADD_INFO) + return ERR_BAD_RECTYPE; + self->index++; + } + err = unpack_string(self, &key); + if (!err) { + err = unpack_string(self, &value); + if (err) + Py_DECREF(key); + else { + PyObject *list = PyDict_GetItem(self->info, key); + if (list == NULL) { + list = PyList_New(0); + if (list == NULL) { + err = ERR_EXCEPTION; + goto finally; + } + if (PyDict_SetItem(self->info, key, list)) { + err = ERR_EXCEPTION; + goto finally; + } + } + if (PyList_Append(list, value)) + err = ERR_EXCEPTION; + } + } + finally: + Py_XDECREF(key); + Py_XDECREF(value); + return err; + } + + + static void + logreader_refill(LogReaderObject *self) + { + int needed; + size_t res; + + if (self->index) { + memmove(self->buffer, &self->buffer[self->index], + self->filled - self->index); + self->filled = self->filled - self->index; + self->index = 0; + } + needed = BUFFERSIZE - self->filled; + if (needed > 0) { + res = fread(&self->buffer[self->filled], 1, needed, self->logfp); + self->filled += res; + } + } + + static void + eof_error(void) + { + PyErr_SetString(PyExc_EOFError, + "end of file with incomplete profile record"); + } + static PyObject * logreader_tp_iternext(LogReaderObject *self) *************** *** 347,365 **** } restart: ! if ((self->filled - self->index) < MAXEVENTSIZE) { ! /* add a little to the buffer */ ! int needed; ! size_t res; ! refill: ! if (self->index) { ! memmove(self->buffer, &self->buffer[self->index], ! self->filled - self->index); ! self->filled = self->filled - self->index; ! self->index = 0; ! } ! needed = BUFFERSIZE - self->filled; ! res = fread(&self->buffer[self->filled], 1, needed, self->logfp); ! self->filled += res; ! } /* end of input */ if (self->filled == 0) --- 416,422 ---- } restart: ! if ((self->filled - self->index) < MAXEVENTSIZE) ! logreader_refill(self); ! /* end of input */ if (self->filled == 0) *************** *** 392,403 **** break; case WHAT_ADD_INFO: ! err = unpack_string(self, &s1); ! if (!err) { ! err = unpack_string(self, &s2); ! if (err) { ! Py_DECREF(s1); ! s1 = NULL; ! } ! } break; case WHAT_DEFINE_FILE: --- 449,453 ---- break; case WHAT_ADD_INFO: ! err = unpack_add_info(self, 0); break; case WHAT_DEFINE_FILE: *************** *** 427,430 **** --- 477,481 ---- goto restart; } + break; case WHAT_FRAME_TIMES: if (self->index >= self->filled) *************** *** 435,440 **** goto restart; } default: ! ; } if (err == ERR_EOF && oldindex != 0) { --- 486,492 ---- goto restart; } + break; default: ! err = ERR_BAD_RECTYPE; } if (err == ERR_EOF && oldindex != 0) { *************** *** 444,453 **** */ err = ERR_NONE; ! goto refill; } ! if (err == ERR_EOF) { /* Could not avoid end-of-buffer error. */ ! PyErr_SetString(PyExc_EOFError, ! "end of file with incomplete profile record"); } else if (!err) { --- 496,508 ---- */ err = ERR_NONE; ! logreader_refill(self); } ! if (err == ERR_BAD_RECTYPE) { ! PyErr_SetString(PyExc_ValueError, ! "unknown record type in log file"); ! } ! else if (err == ERR_EOF) { /* Could not avoid end-of-buffer error. */ ! eof_error(); } else if (!err) { *************** *** 974,977 **** --- 1029,1054 ---- /* Profiler object interface methods. */ + static char addinfo__doc__[] = + "addinfo(key, value)\n" + "Insert an ADD_INFO record into the log."; + + static PyObject * + profiler_addinfo(ProfilerObject *self, PyObject *args) + { + PyObject *result = NULL; + char *key, *value; + + if (PyArg_ParseTuple(args, "ss:addinfo", &key, &value)) { + if (self->logfp == NULL) + PyErr_SetString(ProfilerError, "profiler already closed"); + else { + pack_add_info(self, key, value); + result = Py_None; + Py_INCREF(result); + } + } + return result; + } + static char close__doc__[] = "close()\n" *************** *** 1110,1113 **** --- 1187,1191 ---- */ static PyMethodDef profiler_methods[] = { + {"addinfo", (PyCFunction)profiler_addinfo, METH_VARARGS, addinfo__doc__}, {"close", (PyCFunction)profiler_close, METH_VARARGS, close__doc__}, {"runcall", (PyCFunction)profiler_runcall, METH_VARARGS, runcall__doc__}, *************** *** 1169,1173 **** PyObject_HEAD_INIT(NULL) 0, /* ob_size */ ! "HotShot-profiler", /* tp_name */ (int) sizeof(ProfilerObject), /* tp_basicsize */ 0, /* tp_itemsize */ --- 1247,1251 ---- PyObject_HEAD_INIT(NULL) 0, /* ob_size */ ! "_hotshot.ProfilerType", /* tp_name */ (int) sizeof(ProfilerObject), /* tp_basicsize */ 0, /* tp_itemsize */ *************** *** 1187,1191 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! 0, /* tp_flags */ profiler_object__doc__, /* tp_doc */ }; --- 1265,1269 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ profiler_object__doc__, /* tp_doc */ }; *************** *** 1201,1206 **** static PyObject * ! logreader_getattr(ProfilerObject *self, char *name) { return Py_FindMethod(logreader_methods, (PyObject *)self, name); } --- 1279,1288 ---- static PyObject * ! logreader_getattr(LogReaderObject *self, char *name) { + if (strcmp(name, "info") == 0) { + Py_INCREF(self->info); + return self->info; + } return Py_FindMethod(logreader_methods, (PyObject *)self, name); } *************** *** 1227,1231 **** PyObject_HEAD_INIT(NULL) 0, /* ob_size */ ! "HotShot-logreader", /* tp_name */ (int) sizeof(LogReaderObject), /* tp_basicsize */ 0, /* tp_itemsize */ --- 1309,1313 ---- PyObject_HEAD_INIT(NULL) 0, /* ob_size */ ! "_hotshot.LogReaderType", /* tp_name */ (int) sizeof(LogReaderObject), /* tp_basicsize */ 0, /* tp_itemsize */ *************** *** 1245,1249 **** 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! 0, /* tp_flags */ logreader__doc__, /* tp_doc */ #if Py_TPFLAGS_HAVE_ITER --- 1327,1331 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ logreader__doc__, /* tp_doc */ #if Py_TPFLAGS_HAVE_ITER *************** *** 1270,1273 **** --- 1352,1356 ---- self->frametimings = 1; self->linetimings = 0; + self->info = NULL; self->logfp = fopen(filename, "rb"); if (self->logfp == NULL) { *************** *** 1275,1281 **** --- 1358,1394 ---- Py_DECREF(self); self = NULL; + goto finally; + } + self->info = PyDict_New(); + if (self->info == NULL) { + Py_DECREF(self); + goto finally; + } + /* Aggressively attempt to load all preliminary ADD_INFO + * records from the log so the info records are available + * from a fresh logreader object. + */ + logreader_refill(self); + while (self->filled > self->index + && self->buffer[self->index] == WHAT_ADD_INFO) { + int err = unpack_add_info(self, 1); + if (err) { + if (err == ERR_EOF) + eof_error(); + else + PyErr_SetString(PyExc_RuntimeError, + "unexpected error"); + break; + } + /* Refill agressively so we can avoid EOF during + * initialization unless there's a real EOF condition + * (the tp_iternext handler loops attempts to refill + * and try again). + */ + logreader_refill(self); } } } + finally: return (PyObject *) self; } *************** *** 1323,1350 **** return -1; } ! pack_add_info(self, "HotShot-Version", buffer); ! pack_add_info(self, "Requested-Line-Events", (self->lineevents ? "yes" : "no")); ! pack_add_info(self, "Platform", Py_GetPlatform()); ! pack_add_info(self, "Executable", Py_GetProgramFullPath()); buffer = (char *) Py_GetVersion(); if (buffer == NULL) PyErr_Clear(); else ! pack_add_info(self, "Executable-Version", buffer); #ifdef MS_WIN32 sprintf(cwdbuffer, "%I64d", frequency.QuadPart); ! pack_add_info(self, "Reported-Performance-Frequency", cwdbuffer); #else sprintf(cwdbuffer, "%lu", rusage_diff); ! pack_add_info(self, "Observed-Interval-getrusage", cwdbuffer); sprintf(cwdbuffer, "%lu", timeofday_diff); ! pack_add_info(self, "Observed-Interval-gettimeofday", cwdbuffer); #endif - pack_frame_times(self); - pack_line_times(self); ! pack_add_info(self, "Current-Directory", getcwd(cwdbuffer, sizeof cwdbuffer)); --- 1436,1465 ---- return -1; } ! pack_add_info(self, "hotshot-version", buffer); ! pack_add_info(self, "requested-frame-timings", ! (self->frametimings ? "yes" : "no")); ! pack_add_info(self, "requested-line-events", (self->lineevents ? "yes" : "no")); ! pack_add_info(self, "requested-line-timings", ! (self->linetimings ? "yes" : "no")); ! pack_add_info(self, "platform", Py_GetPlatform()); ! pack_add_info(self, "executable", Py_GetProgramFullPath()); buffer = (char *) Py_GetVersion(); if (buffer == NULL) PyErr_Clear(); else ! pack_add_info(self, "executable-version", buffer); #ifdef MS_WIN32 sprintf(cwdbuffer, "%I64d", frequency.QuadPart); ! pack_add_info(self, "reported-performance-frequency", cwdbuffer); #else sprintf(cwdbuffer, "%lu", rusage_diff); ! pack_add_info(self, "observed-interval-getrusage", cwdbuffer); sprintf(cwdbuffer, "%lu", timeofday_diff); ! pack_add_info(self, "observed-interval-gettimeofday", cwdbuffer); #endif ! pack_add_info(self, "current-directory", getcwd(cwdbuffer, sizeof cwdbuffer)); *************** *** 1356,1361 **** if (buffer == NULL) return -1; ! pack_add_info(self, "Sys-Path-Entry", buffer); } return 0; } --- 1471,1479 ---- if (buffer == NULL) return -1; ! pack_add_info(self, "sys-path-entry", buffer); } + pack_frame_times(self); + pack_line_times(self); + return 0; } From fdrake@users.sourceforge.net Mon Oct 29 20:48:11 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 29 Oct 2001 12:48:11 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/hotshot __init__.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/hotshot In directory usw-pr-cvs1:/tmp/cvs-serv10096/Lib/hotshot Modified Files: __init__.py Log Message: Allow user code to call the addinfo() method on the profiler object. Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/hotshot/__init__.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** __init__.py 2001/10/15 22:14:29 1.2 --- __init__.py 2001/10/29 20:48:09 1.3 *************** *** 22,25 **** --- 22,28 ---- self._prof.stop() + def addinfo(self, key, value): + self._prof.addinfo(key, value) + # These methods offer the same interface as the profile.Profile class, # but delegate most of the work to the C implementation underneath. From fdrake@users.sourceforge.net Mon Oct 29 20:54:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 29 Oct 2001 12:54:04 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_hotshot.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv14012/Lib/test Modified Files: test_hotshot.py Log Message: Add a test for the insertion of user-provided ADD_INFO records. Index: test_hotshot.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_hotshot.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_hotshot.py 2001/10/18 19:34:00 1.4 --- test_hotshot.py 2001/10/29 20:54:01 1.5 *************** *** 42,47 **** def get_logreader(self): ! log = UnlinkingLogReader(self.logfn) ! return log def get_events_wotime(self): --- 42,46 ---- def get_logreader(self): ! return UnlinkingLogReader(self.logfn) def get_events_wotime(self): *************** *** 68,71 **** --- 67,81 ---- profiler.close() self.check_events(events) + + def test_addinfo(self): + def f(p): + p.addinfo("test-key", "test-value") + profiler = self.new_profiler() + profiler.runcall(f, profiler) + profiler.close() + log = self.get_logreader() + info = log._info + list(log) + self.failUnless(info["test-key"] == ["test-value"]) def test_line_numbers(self): From fdrake@users.sourceforge.net Mon Oct 29 20:57:25 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 29 Oct 2001 12:57:25 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/hotshot log.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/hotshot In directory usw-pr-cvs1:/tmp/cvs-serv16081/Lib/hotshot Modified Files: log.py Log Message: Update to reflect changes to the low-level logreader: share the info dictionary instead of building a new one, and provide an overridable method to allow subclasses to catch ADD_INFO records that are not part of the initial block of ADD_INFO records created by the profiler itself. Index: log.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/hotshot/log.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** log.py 2001/10/15 22:05:32 1.3 --- log.py 2001/10/29 20:57:23 1.4 *************** *** 35,43 **** self._funcmap = {} - self._info = {} self._reader = _hotshot.logreader(logfn) self._nextitem = self._reader.next self._stack = [] # Iteration support: # This adds an optional (& ignored) parameter to next() so that the --- 35,57 ---- self._funcmap = {} self._reader = _hotshot.logreader(logfn) self._nextitem = self._reader.next + self._info = self._reader.info self._stack = [] + def addinfo(self, key, value): + """This method is called for each additional ADD_INFO record. + + This can be overridden by applications that want to receive + these events. The default implementation does not need to be + called by alternate implementations. + + The initial set of ADD_INFO records do not pass through this + mechanism; this is only needed to receive notification when + new values are added. Subclasses can inspect self._info after + calling LogReader.__init__(). + """ + pass + # Iteration support: # This adds an optional (& ignored) parameter to next() so that the *************** *** 61,73 **** continue if what == WHAT_ADD_INFO: ! key = tdelta.lower() ! try: ! L = self._info[key] ! except KeyError: ! L = [] ! self._info[key] = L ! L.append(lineno) ! if key == "current-directory": ! self.cwd = lineno continue if what == WHAT_ENTER: --- 75,82 ---- continue if what == WHAT_ADD_INFO: ! # value already loaded into self.info; call the ! # overridable addinfo() handler so higher-level code ! # can pick up the new value ! self.addinfo(tdelta, lineno) continue if what == WHAT_ENTER: From fdrake@users.sourceforge.net Mon Oct 29 21:02:30 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 29 Oct 2001 13:02:30 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs python.sty,1.83,1.84 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv18766 Modified Files: python.sty Log Message: Revise the PDF support in the LaTeX style sheet. This still isn't quite right, but the tests for whether we are generating PDF are a bit more readable, and some unnecessary indirection has been removed. Index: python.sty =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/python.sty,v retrieving revision 1.83 retrieving revision 1.84 diff -C2 -d -r1.83 -r1.84 *** python.sty 2001/10/09 18:01:23 1.83 --- python.sty 2001/10/29 21:02:28 1.84 *************** *** 27,32 **** --- 27,34 ---- \py@doing@page@targetsfalse + \newif\ifpdf\pdffalse \ifx\pdfoutput\undefined\else\ifcase\pdfoutput \else + \pdftrue \input{pdfcolor} \let\py@LinkColor=\NavyBlue *************** *** 254,265 **** % Refer to a module's documentation using a hyperlink of the module's % name, at least if we're building PDF: ! \@ifundefined{pdfannotlink}{% ! \newcommand{\refmodule}[2][\py@modulebadkey]{\module{#2}} ! }{% \newcommand{\refmodule}[2][\py@modulebadkey]{% \ifx\py@modulebadkey#1\def\py@modulekey{#2}\else\def\py@modulekey{#1}\fi% \py@linkToName{label-module-\py@modulekey}{\module{#2}}% } ! } % support for the module index --- 256,267 ---- % Refer to a module's documentation using a hyperlink of the module's % name, at least if we're building PDF: ! \ifpdf \newcommand{\refmodule}[2][\py@modulebadkey]{% \ifx\py@modulebadkey#1\def\py@modulekey{#2}\else\def\py@modulekey{#1}\fi% \py@linkToName{label-module-\py@modulekey}{\module{#2}}% } ! \else ! \newcommand{\refmodule}[2][\py@modulebadkey]{\module{#2}} ! \fi % support for the module index *************** *** 435,445 **** } ! \@ifundefined{pdfoutput}{ ! \newcommand{\py@ModSynopsisSummary}[4]{\bfcode{#2} & #4\\} ! }{ \newcommand{\py@ModSynopsisSummary}[4]{% \py@linkToName{label-module-#1}{\bfcode{#2}} & #4\\ } ! } \newenvironment{synopsistable}{ % key, name, type, synopsis --- 437,447 ---- } ! \ifpdf \newcommand{\py@ModSynopsisSummary}[4]{% \py@linkToName{label-module-#1}{\bfcode{#2}} & #4\\ } ! \else ! \newcommand{\py@ModSynopsisSummary}[4]{\bfcode{#2} & #4\\} ! \fi \newenvironment{synopsistable}{ % key, name, type, synopsis *************** *** 785,800 **** % Use this def/redef approach for \url{} since hyperref defined this already, % but only if we actually used hyperref: ! \@ifundefined{pdfannotlink}{ ! \newcommand{\py@url}[1]{\mbox{\small\textsf{#1}}} ! }{ ! \newcommand{\py@url}[1]{{% \pdfannotlink attr{/Border [0 0 0]} user{/S /URI /URI (#1)}% \py@LinkColor% color of the link text ! \mbox{\small\textsf{#1}}% \py@NormalColor% Turn it back off; these are declarative \pdfendlink}% and don't appear bound to the current }% formatting "box". ! } ! \let\url=\py@url \newcommand{\email}[1]{{\small\textsf{#1}}} \newcommand{\newsgroup}[1]{{\small\textsf{#1}}} --- 787,801 ---- % Use this def/redef approach for \url{} since hyperref defined this already, % but only if we actually used hyperref: ! \ifpdf ! \newcommand{\url}[1]{{% \pdfannotlink attr{/Border [0 0 0]} user{/S /URI /URI (#1)}% \py@LinkColor% color of the link text ! \small\sf #1% \py@NormalColor% Turn it back off; these are declarative \pdfendlink}% and don't appear bound to the current }% formatting "box". ! \else ! \newcommand{\url}[1]{\mbox{\small\textsf{#1}}} ! \fi \newcommand{\email}[1]{{\small\textsf{#1}}} \newcommand{\newsgroup}[1]{{\small\textsf{#1}}} *************** *** 844,848 **** \newcommand{\envvar}[1]{% #1% ! \index{#1@{#1}}% \index{environment variables!{#1}}% } --- 845,849 ---- \newcommand{\envvar}[1]{% #1% ! \index{#1}% \index{environment variables!{#1}}% } *************** *** 860,869 **** % Note that \longprogramopt provides the '--'! \newcommand{\longprogramopt}[1]{\strong{-{}-#1}} % \ulink{link text}{URL} ! \newcommand{\ulink}[2]{#1} % cited titles: \citetitle{Title of Work} % online: \citetitle[url-to-resource]{Title of Work} ! \newcommand{\citetitle}[2][URL]{\emph{#2}} --- 861,890 ---- % Note that \longprogramopt provides the '--'! \newcommand{\longprogramopt}[1]{\strong{-{}-#1}} + % \ulink{link text}{URL} ! \ifpdf ! % The \noindent here is a hack -- we're forcing pdfTeX into ! % horizontal mode since \pdfannotlink requires that. ! \newcommand{\ulink}[2]{\noindent{% ! \pdfannotlink attr{/Border [0 0 0]} user{/S /URI /URI (#2)}% ! \py@LinkColor% color of the link text ! #1% ! \py@NormalColor% Turn it back off; these are declarative ! \pdfendlink}% and don't appear bound to the current ! }% formatting "box". ! \else ! \newcommand{\ulink}[2]{#1} ! \fi % cited titles: \citetitle{Title of Work} % online: \citetitle[url-to-resource]{Title of Work} ! \ifpdf ! \newcommand{\citetitle}[2][\py@modulebadkey]{% ! \ifx\py@modulebadkey#1\emph{#2}\else\ulink{\emph{#2}}{#1}\fi% ! } ! \else ! \newcommand{\citetitle}[2][URL]{#1} ! \fi ! *************** *** 1020,1042 **** % sentences and be terminated with the proper punctuation. ! \@ifundefined{pdfannotlink}{% \newcommand{\py@seemodule}[3][\py@modulebadkey]{% \par% \ifx\py@modulebadkey#1\def\py@modulekey{#2}\else\def\py@modulekey{#1}\fi% \begin{fulllineitems} ! \item[Module \module{#2} (section \ref{module-\py@modulekey}):] #3 \end{fulllineitems} } ! }{\newcommand{\py@seemodule}[3][\py@modulebadkey]{% \par% \ifx\py@modulebadkey#1\def\py@modulekey{#2}\else\def\py@modulekey{#1}\fi% \begin{fulllineitems} ! \item[\py@linkToName{label-module-\py@modulekey}{Module \module{#2}} ! (section \ref{module-\py@modulekey}):] #3 \end{fulllineitems} } ! } % \seetitle[url]{title}{why it's interesting} \newcommand{\py@seetitle}[3][\py@modulebadkey]{% --- 1041,1065 ---- % sentences and be terminated with the proper punctuation. ! \ifpdf \newcommand{\py@seemodule}[3][\py@modulebadkey]{% \par% \ifx\py@modulebadkey#1\def\py@modulekey{#2}\else\def\py@modulekey{#1}\fi% \begin{fulllineitems} ! \item[\py@linkToName{label-module-\py@modulekey}{Module \module{#2}} ! (section \ref{module-\py@modulekey}):] #3 \end{fulllineitems} } ! \else ! \newcommand{\py@seemodule}[3][\py@modulebadkey]{% \par% \ifx\py@modulebadkey#1\def\py@modulekey{#2}\else\def\py@modulekey{#1}\fi% \begin{fulllineitems} ! \item[Module \module{#2} (section \ref{module-\py@modulekey}):] #3 \end{fulllineitems} } ! \fi ! % \seetitle[url]{title}{why it's interesting} \newcommand{\py@seetitle}[3][\py@modulebadkey]{% From tim_one@users.sourceforge.net Mon Oct 29 21:46:10 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 29 Oct 2001 13:46:10 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib tempfile.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv10684/python/Lib Modified Files: tempfile.py Log Message: SF bug #476138: tempfile behavior across platforms Ensure that a tempfile can be closed any number of times without error. This wasn't true on Windows. Index: tempfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tempfile.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** tempfile.py 2001/10/24 20:33:34 1.31 --- tempfile.py 2001/10/29 21:46:08 1.32 *************** *** 132,143 **** self.file = file self.path = path def close(self): ! self.file.close() ! os.unlink(self.path) def __del__(self): ! try: self.close() ! except: pass def __getattr__(self, name): --- 132,145 ---- self.file = file self.path = path + self.close_called = 0 def close(self): ! if not self.close_called: ! self.close_called = 1 ! self.file.close() ! os.unlink(self.path) def __del__(self): ! self.close() def __getattr__(self, name): From tim_one@users.sourceforge.net Mon Oct 29 21:46:10 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 29 Oct 2001 13:46:10 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_tempfile.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv10684/python/Lib/test Added Files: test_tempfile.py Log Message: SF bug #476138: tempfile behavior across platforms Ensure that a tempfile can be closed any number of times without error. This wasn't true on Windows. --- NEW FILE: test_tempfile.py --- # SF bug #476138: tempfile behavior across platforms # Ensure that a temp file can be closed any number of times without error. import tempfile f = tempfile.TemporaryFile("w+b") f.write('abc\n') f.close() f.close() f.close() From gvanrossum@users.sourceforge.net Mon Oct 29 22:09:39 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 29 Oct 2001 14:09:39 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.115,2.116 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv22912 Modified Files: typeobject.c Log Message: Add __del__ callbacks. They are too useful to leave out. XXX Remaining problems: - The GC module doesn't know about these; I think it has its reasons to disallow calling __del__, but for now, __del__ on new-style objects is called when the GC module discards an object, for better or for worse. - The code to call a __del__ handler is really ridiculously complicated, due to all the different debug #ifdefs. I've copied this from the similar code in classobject.c, so I'm pretty sure I did it right, but it's not pretty. :-( - No tests yet. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.115 retrieving revision 2.116 diff -C2 -d -r2.115 -r2.116 *** typeobject.c 2001/10/29 14:33:44 2.115 --- typeobject.c 2001/10/29 22:09:37 2.116 *************** *** 231,234 **** --- 231,305 ---- } + staticforward PyObject *lookup_maybe(PyObject *, char *, PyObject **); + + static int + call_finalizer(PyObject *self) + { + static PyObject *del_str = NULL; + PyObject *del, *res; + PyObject *error_type, *error_value, *error_traceback; + + /* Temporarily resurrect the object. */ + #ifdef Py_TRACE_REFS + #ifndef Py_REF_DEBUG + # error "Py_TRACE_REFS defined but Py_REF_DEBUG not." + #endif + /* much too complicated if Py_TRACE_REFS defined */ + _Py_NewReference((PyObject *)self); + #ifdef COUNT_ALLOCS + /* compensate for boost in _Py_NewReference; note that + * _Py_RefTotal was also boosted; we'll knock that down later. + */ + self->ob_type->tp_allocs--; + #endif + #else /* !Py_TRACE_REFS */ + /* Py_INCREF boosts _Py_RefTotal if Py_REF_DEBUG is defined */ + Py_INCREF(self); + #endif /* !Py_TRACE_REFS */ + + /* Save the current exception, if any. */ + PyErr_Fetch(&error_type, &error_value, &error_traceback); + + /* Execute __del__ method, if any. */ + del = lookup_maybe(self, "__del__", &del_str); + if (del != NULL) { + res = PyEval_CallObject(del, NULL); + if (res == NULL) + PyErr_WriteUnraisable(del); + else + Py_DECREF(res); + Py_DECREF(del); + } + + /* Restore the saved exception. */ + PyErr_Restore(error_type, error_value, error_traceback); + + /* Undo the temporary resurrection; can't use DECREF here, it would + * cause a recursive call. + */ + #ifdef Py_REF_DEBUG + /* _Py_RefTotal was boosted either by _Py_NewReference or + * Py_INCREF above. + */ + _Py_RefTotal--; + #endif + if (--self->ob_refcnt > 0) { + #ifdef COUNT_ALLOCS + self->ob_type->tp_frees--; + #endif + _PyObject_GC_TRACK(self); + return -1; /* __del__ added a reference; don't delete now */ + } + #ifdef Py_TRACE_REFS + _Py_ForgetReference((PyObject *)self); + #ifdef COUNT_ALLOCS + /* compensate for increment in _Py_ForgetReference */ + self->ob_type->tp_frees--; + #endif + #endif + + return 0; + } + static void subtype_dealloc(PyObject *self) *************** *** 238,241 **** --- 309,315 ---- /* This exists so we can DECREF self->ob_type */ + + if (call_finalizer(self) < 0) + return; /* Find the nearest base with a different tp_dealloc */ From gvanrossum@users.sourceforge.net Mon Oct 29 22:11:02 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 29 Oct 2001 14:11:02 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.302,1.303 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv23487 Modified Files: NEWS Log Message: Add __del__ callbacks. They are too useful to leave out. XXX Remaining problems: - The GC module doesn't know about these; I think it has its reasons to disallow calling __del__, but for now, __del__ on new-style objects is called when the GC module discards an object, for better or for worse. - The code to call a __del__ handler is really ridiculously complicated, due to all the different debug #ifdefs. I've copied this from the similar code in classobject.c, so I'm pretty sure I did it right, but it's not pretty. :-( - No tests yet. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.302 retrieving revision 1.303 diff -C2 -d -r1.302 -r1.303 *** NEWS 2001/10/27 22:28:54 1.302 --- NEWS 2001/10/29 22:11:00 1.303 *************** *** 5,8 **** --- 5,11 ---- Type/class unification and new-style classes + - New-style classes can now have a __del__ method, which is called + when the instance is deleted (just like for classic classes). + - Assignment to object.__dict__ is now possible, for objects that are instances of new-style classes that have a __dict__ (unless the base From tim_one@users.sourceforge.net Mon Oct 29 22:25:46 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 29 Oct 2001 14:25:46 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.93,1.94 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv28201/python/Doc/lib Modified Files: libfuncs.tex Log Message: Rename "dictionary" (type and constructor) to "dict". Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.93 retrieving revision 1.94 diff -C2 -d -r1.93 -r1.94 *** libfuncs.tex 2001/10/26 15:04:33 1.93 --- libfuncs.tex 2001/10/29 22:25:44 1.94 *************** *** 176,180 **** \end{funcdesc} ! \begin{funcdesc}{dictionary}{\optional{mapping-or-sequence}} Return a new dictionary initialized from the optional argument. If an argument is not specified, return a new empty dictionary. --- 176,180 ---- \end{funcdesc} ! \begin{funcdesc}{dict}{\optional{mapping-or-sequence}} Return a new dictionary initialized from the optional argument. If an argument is not specified, return a new empty dictionary. *************** *** 192,201 **** \begin{itemize} ! \item \code{dictionary(\{1: 2, 2: 3\})} ! \item \code{dictionary(\{1: 2, 2: 3\}.items())} ! \item \code{dictionary(\{1: 2, 2: 3\}.iteritems())} ! \item \code{dictionary(zip((1, 2), (2, 3)))} ! \item \code{dictionary([[2, 3], [1, 2]])} ! \item \code{dictionary([(i-1, i) for i in (2, 3)])} \end{itemize} \end{funcdesc} --- 192,201 ---- \begin{itemize} ! \item \code{dict(\{1: 2, 2: 3\})} ! \item \code{dict(\{1: 2, 2: 3\}.items())} ! \item \code{dict(\{1: 2, 2: 3\}.iteritems())} ! \item \code{dict(zip((1, 2), (2, 3)))} ! \item \code{dict([[2, 3], [1, 2]])} ! \item \code{dict([(i-1, i) for i in (2, 3)])} \end{itemize} \end{funcdesc} From tim_one@users.sourceforge.net Mon Oct 29 22:25:46 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 29 Oct 2001 14:25:46 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.303,1.304 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv28201/python/Misc Modified Files: NEWS Log Message: Rename "dictionary" (type and constructor) to "dict". Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.303 retrieving revision 1.304 diff -C2 -d -r1.303 -r1.304 *** NEWS 2001/10/29 22:11:00 1.303 --- NEWS 2001/10/29 22:25:44 1.304 *************** *** 5,8 **** --- 5,11 ---- Type/class unification and new-style classes + - The new builtin dictionary() constructor, and dictionary type, have + been renamed to dict. This reflects a decade of common usage. + - New-style classes can now have a __del__ method, which is called when the instance is deleted (just like for classic classes). From tim_one@users.sourceforge.net Mon Oct 29 22:25:46 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 29 Oct 2001 14:25:46 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib repr.py,1.13,1.14 types.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv28201/python/Lib Modified Files: repr.py types.py Log Message: Rename "dictionary" (type and constructor) to "dict". Index: repr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/repr.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** repr.py 2001/09/05 02:27:04 1.13 --- repr.py 2001/10/29 22:25:44 1.14 *************** *** 49,53 **** if n > self.maxlist: s = s + ', ...' return '[' + s + ']' ! def repr_dictionary(self, x, level): n = len(x) if n == 0: return '{}' --- 49,53 ---- if n > self.maxlist: s = s + ', ...' return '[' + s + ']' ! def repr_dict(self, x, level): n = len(x) if n == 0: return '{}' Index: types.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/types.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** types.py 2001/09/26 19:54:08 1.23 --- types.py 2001/10/29 22:25:44 1.24 *************** *** 35,39 **** TupleType = tuple ListType = list ! DictType = DictionaryType = dictionary def _f(): pass --- 35,39 ---- TupleType = tuple ListType = list ! DictType = DictionaryType = dict def _f(): pass From tim_one@users.sourceforge.net Mon Oct 29 22:25:46 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 29 Oct 2001 14:25:46 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.97,1.98 test_descrtut.py,1.9,1.10 test_repr.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv28201/python/Lib/test Modified Files: test_descr.py test_descrtut.py test_repr.py Log Message: Rename "dictionary" (type and constructor) to "dict". Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.97 retrieving revision 1.98 diff -C2 -d -r1.97 -r1.98 *** test_descr.py 2001/10/27 18:27:47 1.97 --- test_descr.py 2001/10/29 22:25:44 1.98 *************** *** 164,168 **** vereq(l, l1) l = [] ! for i in dictionary.__iter__(d): l.append(i) vereq(l, l1) d = {1:2, 3:4} --- 164,168 ---- vereq(l, l1) l = [] ! for i in dict.__iter__(d): l.append(i) vereq(l, l1) d = {1:2, 3:4} *************** *** 174,191 **** def dict_constructor(): if verbose: ! print "Testing dictionary constructor ..." ! d = dictionary() vereq(d, {}) ! d = dictionary({}) vereq(d, {}) ! d = dictionary(items={}) vereq(d, {}) ! d = dictionary({1: 2, 'a': 'b'}) vereq(d, {1: 2, 'a': 'b'}) ! vereq(d, dictionary(d.items())) ! vereq(d, dictionary(items=d.iteritems())) for badarg in 0, 0L, 0j, "0", [0], (0,): try: ! dictionary(badarg) except TypeError: pass --- 174,191 ---- def dict_constructor(): if verbose: ! print "Testing dict constructor ..." ! d = dict() vereq(d, {}) ! d = dict({}) vereq(d, {}) ! d = dict(items={}) vereq(d, {}) ! d = dict({1: 2, 'a': 'b'}) vereq(d, {1: 2, 'a': 'b'}) ! vereq(d, dict(d.items())) ! vereq(d, dict(items=d.iteritems())) for badarg in 0, 0L, 0j, "0", [0], (0,): try: ! dict(badarg) except TypeError: pass *************** *** 197,216 **** pass else: ! raise TestFailed("no TypeError from dictionary(%r)" % badarg) else: ! raise TestFailed("no TypeError from dictionary(%r)" % badarg) try: ! dictionary(senseless={}) except TypeError: pass else: ! raise TestFailed("no TypeError from dictionary(senseless={})") try: ! dictionary({}, {}) except TypeError: pass else: ! raise TestFailed("no TypeError from dictionary({}, {})") class Mapping: --- 197,216 ---- pass else: ! raise TestFailed("no TypeError from dict(%r)" % badarg) else: ! raise TestFailed("no TypeError from dict(%r)" % badarg) try: ! dict(senseless={}) except TypeError: pass else: ! raise TestFailed("no TypeError from dict(senseless={})") try: ! dict({}, {}) except TypeError: pass else: ! raise TestFailed("no TypeError from dict({}, {})") class Mapping: *************** *** 219,231 **** try: ! dictionary(Mapping()) except TypeError: pass else: ! raise TestFailed("no TypeError from dictionary(incomplete mapping)") Mapping.keys = lambda self: self.dict.keys() Mapping.__getitem__ = lambda self, i: self.dict[i] ! d = dictionary(items=Mapping()) vereq(d, Mapping.dict) --- 219,231 ---- try: ! dict(Mapping()) except TypeError: pass else: ! raise TestFailed("no TypeError from dict(incomplete mapping)") Mapping.keys = lambda self: self.dict.keys() Mapping.__getitem__ = lambda self, i: self.dict[i] ! d = dict(items=Mapping()) vereq(d, Mapping.dict) *************** *** 238,242 **** return iter([self.first, self.last]) ! d = dictionary([AddressBookEntry('Tim', 'Warsaw'), AddressBookEntry('Barry', 'Peters'), AddressBookEntry('Tim', 'Peters'), --- 238,242 ---- return iter([self.first, self.last]) ! d = dict([AddressBookEntry('Tim', 'Warsaw'), AddressBookEntry('Barry', 'Peters'), AddressBookEntry('Tim', 'Peters'), *************** *** 244,258 **** vereq(d, {'Barry': 'Warsaw', 'Tim': 'Peters'}) ! d = dictionary(zip(range(4), range(1, 5))) ! vereq(d, dictionary([(i, i+1) for i in range(4)])) # Bad sequence lengths. for bad in [('tooshort',)], [('too', 'long', 'by 1')]: try: ! dictionary(bad) except ValueError: pass else: ! raise TestFailed("no ValueError from dictionary(%r)" % bad) def test_dir(): --- 244,258 ---- vereq(d, {'Barry': 'Warsaw', 'Tim': 'Peters'}) ! d = dict(zip(range(4), range(1, 5))) ! vereq(d, dict([(i, i+1) for i in range(4)])) # Bad sequence lengths. for bad in [('tooshort',)], [('too', 'long', 'by 1')]: try: ! dict(bad) except ValueError: pass else: ! raise TestFailed("no ValueError from dict(%r)" % bad) def test_dir(): *************** *** 544,554 **** def pydicts(): if verbose: print "Testing Python subclass of dict..." ! verify(issubclass(dictionary, dictionary)) ! verify(isinstance({}, dictionary)) ! d = dictionary() vereq(d, {}) ! verify(d.__class__ is dictionary) ! verify(isinstance(d, dictionary)) ! class C(dictionary): state = -1 def __init__(self, *a, **kw): --- 544,554 ---- def pydicts(): if verbose: print "Testing Python subclass of dict..." ! verify(issubclass(dict, dict)) ! verify(isinstance({}, dict)) ! d = dict() vereq(d, {}) ! verify(d.__class__ is dict) ! verify(isinstance(d, dict)) ! class C(dict): state = -1 def __init__(self, *a, **kw): *************** *** 562,571 **** def __setitem__(self, key, value): assert isinstance(key, type(0)) ! dictionary.__setitem__(self, key, value) def setstate(self, state): self.state = state def getstate(self): return self.state ! verify(issubclass(C, dictionary)) a1 = C(12) vereq(a1.state, 12) --- 562,571 ---- def __setitem__(self, key, value): assert isinstance(key, type(0)) ! dict.__setitem__(self, key, value) def setstate(self, state): self.state = state def getstate(self): return self.state ! verify(issubclass(C, dict)) a1 = C(12) vereq(a1.state, 12) *************** *** 802,806 **** a.setstate(10) vereq(a.getstate(), 10) ! class D(dictionary, C): def __init__(self): type({}).__init__(self) --- 802,806 ---- a.setstate(10) vereq(a.getstate(), 10) ! class D(dict, C): def __init__(self): type({}).__init__(self) *************** *** 814,818 **** d.setstate(10) vereq(d.getstate(), 10) ! vereq(D.__mro__, (D, dictionary, C, object)) # SF bug #442833 --- 814,818 ---- d.setstate(10) vereq(d.getstate(), 10) ! vereq(D.__mro__, (D, dict, C, object)) # SF bug #442833 *************** *** 1000,1004 **** try: ! class C(list, dictionary): pass except TypeError: --- 1000,1004 ---- try: ! class C(list, dict): pass except TypeError: *************** *** 1866,1873 **** vereq(tuple(sequence=range(3)), (0, 1, 2)) vereq(list(sequence=(0, 1, 2)), range(3)) ! vereq(dictionary(items={1: 2}), {1: 2}) for constructor in (int, float, long, complex, str, unicode, ! tuple, list, dictionary, file): try: constructor(bogus_keyword_arg=1) --- 1866,1873 ---- vereq(tuple(sequence=range(3)), (0, 1, 2)) vereq(list(sequence=(0, 1, 2)), range(3)) ! vereq(dict(items={1: 2}), {1: 2}) for constructor in (int, float, long, complex, str, unicode, ! tuple, list, dict, file): try: constructor(bogus_keyword_arg=1) Index: test_descrtut.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descrtut.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_descrtut.py 2001/10/09 19:39:46 1.9 --- test_descrtut.py 2001/10/29 22:25:44 1.10 *************** *** 12,23 **** import pprint ! class defaultdict(dictionary): def __init__(self, default=None): ! dictionary.__init__(self) self.default = default def __getitem__(self, key): try: ! return dictionary.__getitem__(self, key) except KeyError: return self.default --- 12,23 ---- import pprint ! class defaultdict(dict): def __init__(self, default=None): ! dict.__init__(self) self.default = default def __getitem__(self, key): try: ! return dict.__getitem__(self, key) except KeyError: return self.default *************** *** 26,30 **** if not args: args = (self.default,) ! return dictionary.get(self, key, *args) def merge(self, other): --- 26,30 ---- if not args: args = (self.default,) ! return dict.get(self, key, *args) def merge(self, other): *************** *** 57,61 **** >>> print a[0] # a non-existant item 0.0 ! >>> a.merge({1:100, 2:200}) # use a dictionary method >>> print sortdict(a) # show the result {1: 3.25, 2: 200} --- 57,61 ---- >>> print a[0] # a non-existant item 0.0 ! >>> a.merge({1:100, 2:200}) # use a dict method >>> print sortdict(a) # show the result {1: 3.25, 2: 200} *************** *** 112,125 **** """ ! class defaultdict2(dictionary): __slots__ = ['default'] def __init__(self, default=None): ! dictionary.__init__(self) self.default = default def __getitem__(self, key): try: ! return dictionary.__getitem__(self, key) except KeyError: return self.default --- 112,125 ---- """ ! class defaultdict2(dict): __slots__ = ['default'] def __init__(self, default=None): ! dict.__init__(self) self.default = default def __getitem__(self, key): try: ! return dict.__getitem__(self, key) except KeyError: return self.default *************** *** 128,132 **** if not args: args = (self.default,) ! return dictionary.get(self, key, *args) def merge(self, other): --- 128,132 ---- if not args: args = (self.default,) ! return dict.get(self, key, *args) def merge(self, other): *************** *** 169,173 **** >>> isinstance([], list) 1 ! >>> isinstance([], dictionary) 0 >>> isinstance([], object) --- 169,173 ---- >>> isinstance([], list) 1 ! >>> isinstance([], dict) 0 >>> isinstance([], object) Index: test_repr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_repr.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_repr.py 2001/10/24 20:32:02 1.9 --- test_repr.py 2001/10/29 22:25:44 1.10 *************** *** 146,150 **** eq = self.assertEquals # method descriptors ! eq(repr(dictionary.items), "") # XXX member descriptors # XXX attribute descriptors --- 146,150 ---- eq = self.assertEquals # method descriptors ! eq(repr(dict.items), "") # XXX member descriptors # XXX attribute descriptors From tim_one@users.sourceforge.net Mon Oct 29 22:25:47 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 29 Oct 2001 14:25:47 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.116,2.117 typeobject.c,2.116,2.117 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv28201/python/Objects Modified Files: dictobject.c typeobject.c Log Message: Rename "dictionary" (type and constructor) to "dict". Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.116 retrieving revision 2.117 diff -C2 -d -r2.116 -r2.117 *** dictobject.c 2001/10/27 18:27:48 2.116 --- dictobject.c 2001/10/29 22:25:44 2.117 *************** *** 1785,1789 **** int result = 0; ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:dictionary", kwlist, &arg)) result = -1; --- 1785,1789 ---- int result = 0; ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:dict", kwlist, &arg)) result = -1; *************** *** 1805,1812 **** static char dictionary_doc[] = ! "dictionary() -> new empty dictionary.\n" ! "dictionary(mapping) -> new dict initialized from a mapping object's\n" " (key, value) pairs.\n" ! "dictionary(seq) -> new dict initialized as if via:\n" " d = {}\n" " for k, v in seq:\n" --- 1805,1812 ---- static char dictionary_doc[] = ! "dict() -> new empty dictionary.\n" ! "dict(mapping) -> new dictionary initialized from a mapping object's\n" " (key, value) pairs.\n" ! "dict(seq) -> new dictionary initialized as if via:\n" " d = {}\n" " for k, v in seq:\n" *************** *** 1816,1820 **** PyObject_HEAD_INIT(&PyType_Type) 0, ! "dictionary", sizeof(dictobject), 0, --- 1816,1820 ---- PyObject_HEAD_INIT(&PyType_Type) 0, ! "dict", sizeof(dictobject), 0, Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.116 retrieving revision 2.117 diff -C2 -d -r2.116 -r2.117 *** typeobject.c 2001/10/29 22:09:37 2.116 --- typeobject.c 2001/10/29 22:25:44 2.117 *************** *** 2485,2489 **** /* Check that the use doesn't do something silly and unsafe like ! object.__new__(dictionary). To do this, we check that the most derived base that's not a heap type is this type. */ staticbase = subtype; --- 2485,2489 ---- /* Check that the use doesn't do something silly and unsafe like ! object.__new__(dict). To do this, we check that the most derived base that's not a heap type is this type. */ staticbase = subtype; From tim_one@users.sourceforge.net Mon Oct 29 22:25:47 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 29 Oct 2001 14:25:47 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.242,2.243 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv28201/python/Python Modified Files: bltinmodule.c Log Message: Rename "dictionary" (type and constructor) to "dict". Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.242 retrieving revision 2.243 diff -C2 -d -r2.242 -r2.243 *** bltinmodule.c 2001/10/24 20:42:55 2.242 --- bltinmodule.c 2001/10/29 22:25:45 2.243 *************** *** 1849,1853 **** SETBUILTIN("complex", &PyComplex_Type); #endif ! SETBUILTIN("dictionary", &PyDict_Type); SETBUILTIN("float", &PyFloat_Type); SETBUILTIN("property", &PyProperty_Type); --- 1849,1853 ---- SETBUILTIN("complex", &PyComplex_Type); #endif ! SETBUILTIN("dict", &PyDict_Type); SETBUILTIN("float", &PyFloat_Type); SETBUILTIN("property", &PyProperty_Type); From akuchling@users.sourceforge.net Mon Oct 29 22:36:30 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Mon, 29 Oct 2001 14:36:30 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0264.txt,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv31759 Modified Files: pep-0264.txt Log Message: Fix typo Index: pep-0264.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0264.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** pep-0264.txt 2001/10/29 16:06:05 1.8 --- pep-0264.txt 2001/10/29 22:36:27 1.9 *************** *** 19,23 **** statements' effects last the life of the shell. ! The PEP also takes the oppourtunity to clean up the other unresolved issue mentioned in PEP 236, the inability to stop compile() inheriting the effect of future statements affecting the --- 19,23 ---- statements' effects last the life of the shell. ! The PEP also takes the opportunity to clean up the other unresolved issue mentioned in PEP 236, the inability to stop compile() inheriting the effect of future statements affecting the From akuchling@users.sourceforge.net Mon Oct 29 22:37:19 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Mon, 29 Oct 2001 14:37:19 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0272.txt,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv31985 Modified Files: pep-0272.txt Log Message: Use key_size of None for variable-size keys Index: pep-0272.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0272.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pep-0272.txt 2001/09/20 16:12:26 1.2 --- pep-0272.txt 2001/10/29 22:37:17 1.3 *************** *** 80,84 **** An integer value; the size of the keys required by this ! module. If key_size is zero, then the algorithm accepts arbitrary-length keys. You cannot pass a key of length 0 (that is, the null string '') as such a variable-length key. --- 80,84 ---- An integer value; the size of the keys required by this ! module. If key_size is None, then the algorithm accepts arbitrary-length keys. You cannot pass a key of length 0 (that is, the null string '') as such a variable-length key. From effbot@users.sourceforge.net Mon Oct 29 22:58:57 2001 From: effbot@users.sourceforge.net (Fredrik Lundh) Date: Mon, 29 Oct 2001 14:58:57 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/lib-tk tkDirectoryChooser.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory usw-pr-cvs1:/tmp/cvs-serv6076/lib/lib-tk Added Files: tkDirectoryChooser.py Log Message: directory chooser (requires a recent version of Tk) --- NEW FILE: tkDirectoryChooser.py --- # # tkDirectoryChooser.py # $Id: tkDirectoryChooser.py,v 1.1 2001/10/29 22:58:55 effbot Exp $ # # tk common directory dialogue # # this module provides interfaces to the native directory dialogue # available in Tk 8.3 and newer. # # written by Fredrik Lundh, November 2000. # # # options (all have default values): # # - initialdir: initial directory. preserved by dialog instance. # # - mustexist: if true, user must pick an existing directory # # - parent: which window to place the dialog on top of # # - title: dialog title # from tkCommonDialog import Dialog class Chooser(Dialog): command = "tk_chooseDirectory" def _fixresult(self, widget, result): if result: # keep directory until next time self.options["initialdir"] = result self.directory = result # compatibility return result # # convenience stuff def askdirectory(**options): "Ask for a directory name" return apply(Chooser, (), options).show() # -------------------------------------------------------------------- # test stuff if __name__ == "__main__": print "directory", askdirectory() From tim_one@users.sourceforge.net Tue Oct 30 01:26:51 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 29 Oct 2001 17:26:51 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules socketmodule.c,1.190,1.191 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv6912/python/Modules Modified Files: socketmodule.c Log Message: PySocketSock_connect_ex(): On Windows, return the correct Windows exit code. The patch is from Jeremy, and allows test_asynchat to run again. Bugfix candidate. Index: socketmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.190 retrieving revision 1.191 diff -C2 -d -r1.190 -r1.191 *** socketmodule.c 2001/10/28 12:31:33 1.190 --- socketmodule.c 2001/10/30 01:26:49 1.191 *************** *** 1268,1273 **** res = connect(s->sock_fd, addr, addrlen); Py_END_ALLOW_THREADS ! if (res != 0) res = errno; return PyInt_FromLong((long) res); } --- 1268,1278 ---- res = connect(s->sock_fd, addr, addrlen); Py_END_ALLOW_THREADS ! if (res != 0) { ! #ifdef MS_WINDOWS ! res = WSAGetLastError(); ! #else res = errno; + #endif + } return PyInt_FromLong((long) res); } From gvanrossum@users.sourceforge.net Tue Oct 30 02:33:04 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 29 Oct 2001 18:33:04 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.98,1.99 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv3808 Modified Files: test_descr.py Log Message: Minimal test for __del__ hook. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.98 retrieving revision 1.99 diff -C2 -d -r1.98 -r1.99 *** test_descr.py 2001/10/29 22:25:44 1.98 --- test_descr.py 2001/10/30 02:33:02 1.99 *************** *** 2409,2412 **** --- 2409,2423 ---- vereq(a, [0, 1, 2]) + def delhook(): + if verbose: print "Testing __del__ hook..." + log = [] + class C(object): + def __del__(self): + log.append(1) + c = C() + vereq(log, []) + del c + vereq(log, [1]) + def test_main(): class_docstrings() *************** *** 2460,2463 **** --- 2471,2475 ---- str_of_str_subclass() kwdargs() + delhook() if verbose: print "All OK" From gvanrossum@users.sourceforge.net Tue Oct 30 02:40:54 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 29 Oct 2001 18:40:54 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects sliceobject.c,2.9,2.10 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv7189 Modified Files: sliceobject.c Log Message: Add values to tp_getattro and tp_flags so that dir(Ellipsis) will return the same as dir(None). Index: sliceobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/sliceobject.c,v retrieving revision 2.9 retrieving revision 2.10 diff -C2 -d -r2.9 -r2.10 *** sliceobject.c 2001/09/20 20:46:19 2.9 --- sliceobject.c 2001/10/30 02:40:52 2.10 *************** *** 25,42 **** static PyTypeObject PyEllipsis_Type = { PyObject_HEAD_INIT(&PyType_Type) ! 0, ! "ellipsis", ! 0, ! 0, ! 0, /*tp_dealloc*/ /*never called*/ ! 0, /*tp_print*/ ! 0, /*tp_getattr*/ ! 0, /*tp_setattr*/ ! 0, /*tp_compare*/ ! (reprfunc)ellipsis_repr, /*tp_repr*/ ! 0, /*tp_as_number*/ ! 0, /*tp_as_sequence*/ ! 0, /*tp_as_mapping*/ ! 0, /*tp_hash */ }; --- 25,48 ---- static PyTypeObject PyEllipsis_Type = { PyObject_HEAD_INIT(&PyType_Type) ! 0, /* ob_size */ ! "ellipsis", /* tp_name */ ! 0, /* tp_basicsize */ ! 0, /* tp_itemsize */ ! 0, /*never called*/ /* tp_dealloc */ ! 0, /* tp_print */ ! 0, /* tp_getattr */ ! 0, /* tp_setattr */ ! 0, /* tp_compare */ ! (reprfunc)ellipsis_repr, /* tp_repr */ ! 0, /* tp_as_number */ ! 0, /* tp_as_sequence */ ! 0, /* tp_as_mapping */ ! 0, /* tp_hash */ ! 0, /* tp_call */ ! 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ ! 0, /* tp_setattro */ ! 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ }; From gvanrossum@users.sourceforge.net Tue Oct 30 03:00:55 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 29 Oct 2001 19:00:55 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules binascii.c,2.31,2.32 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv16248 Modified Files: binascii.c Log Message: Change the limit on the input size for b2a_base64 to what will fit in memory, rather than the standard's 57. This fixes SF bug #473009. Index: binascii.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/binascii.c,v retrieving revision 2.31 retrieving revision 2.32 diff -C2 -d -r2.31 -r2.32 *** binascii.c 2001/10/04 14:54:53 2.31 --- binascii.c 2001/10/30 03:00:52 2.32 *************** *** 136,140 **** #define BASE64_PAD '=' ! #define BASE64_MAXBIN 57 /* Max binary chunk size (76 char line) */ static unsigned char table_b2a_base64[] = --- 136,142 ---- #define BASE64_PAD '=' ! ! /* Max binary chunk size; limited only by available memory */ ! #define BASE64_MAXBIN (INT_MAX/2 - sizeof(PyStringObject)) static unsigned char table_b2a_base64[] = From gvanrossum@users.sourceforge.net Tue Oct 30 03:03:05 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 29 Oct 2001 19:03:05 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.132,1.133 NEWS,1.304,1.305 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv17175 Modified Files: ACKS NEWS Log Message: News and attribution for SF bug #473009. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.132 retrieving revision 1.133 diff -C2 -d -r1.132 -r1.133 *** ACKS 2001/10/26 03:38:46 1.132 --- ACKS 2001/10/30 03:03:03 1.133 *************** *** 81,84 **** --- 81,85 ---- Tom Christiansen Vadim Chugunov + David Cinege Mike Clarkson Steve Clift Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.304 retrieving revision 1.305 diff -C2 -d -r1.304 -r1.305 *** NEWS 2001/10/29 22:25:44 1.304 --- NEWS 2001/10/30 03:03:03 1.305 *************** *** 42,45 **** --- 42,48 ---- for the curses module (you have to run it manually). + - binascii.b2a_base64 no longer places an arbitrary restriction of 57 + bytes on its input. + Library From gvanrossum@users.sourceforge.net Tue Oct 30 03:17:32 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 29 Oct 2001 19:17:32 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_commands.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv24869 Modified Files: test_commands.py Log Message: Fix SF bug #456386: test_commands regression failure (Andrew Dalke) test_commands does not work on IRIX It assumes the output of "ls /bin/ls" is a line that starts with a '-'. On IRIX that file is a symbolic link, so the first character is an l. This causes test_getstatus to fail. Index: test_commands.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_commands.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_commands.py 2001/09/20 21:33:42 1.2 --- test_commands.py 2001/10/30 03:17:30 1.3 *************** *** 33,37 **** # This pattern should match 'ls -ld /bin/ls' on any posix # system, however perversely configured. ! pat = r'''-..x..x..x # It is executable. \s+\d+ # It has some number of links. \s+\w+\s+\w+ # It has a user and group, which may --- 33,37 ---- # This pattern should match 'ls -ld /bin/ls' on any posix # system, however perversely configured. ! pat = r'''[l-]..x..x..x # It is executable. (May be a symlink.) \s+\d+ # It has some number of links. \s+\w+\s+\w+ # It has a user and group, which may From tim_one@users.sourceforge.net Tue Oct 30 05:41:09 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 29 Oct 2001 21:41:09 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.99,1.100 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv26229/python/Lib/test Modified Files: test_descr.py Log Message: Just changed some continued-line indentation to read better, due to the earlier s/dictionary/dict/ change. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.99 retrieving revision 1.100 diff -C2 -d -r1.99 -r1.100 *** test_descr.py 2001/10/30 02:33:02 1.99 --- test_descr.py 2001/10/30 05:41:07 1.100 *************** *** 239,245 **** d = dict([AddressBookEntry('Tim', 'Warsaw'), ! AddressBookEntry('Barry', 'Peters'), ! AddressBookEntry('Tim', 'Peters'), ! AddressBookEntry('Barry', 'Warsaw')]) vereq(d, {'Barry': 'Warsaw', 'Tim': 'Peters'}) --- 239,245 ---- d = dict([AddressBookEntry('Tim', 'Warsaw'), ! AddressBookEntry('Barry', 'Peters'), ! AddressBookEntry('Tim', 'Peters'), ! AddressBookEntry('Barry', 'Warsaw')]) vereq(d, {'Barry': 'Warsaw', 'Tim': 'Peters'}) From tim_one@users.sourceforge.net Tue Oct 30 05:45:28 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 29 Oct 2001 21:45:28 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.100,1.101 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv27527/python/Lib/test Modified Files: test_descr.py Log Message: To cover a recent checkin, added a test to ensure dir(None) == dir(Ellipsis). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.100 retrieving revision 1.101 diff -C2 -d -r1.100 -r1.101 *** test_descr.py 2001/10/30 05:41:07 1.100 --- test_descr.py 2001/10/30 05:45:26 1.101 *************** *** 356,359 **** --- 356,363 ---- pass + # Two essentially featureless objects, just inheriting stuff from + # object. + vereq(dir(None), dir(Ellipsis)) + binops = { 'add': '+', From tim_one@users.sourceforge.net Tue Oct 30 05:54:06 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 29 Oct 2001 21:54:06 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libstdtypes.tex,1.73,1.74 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv31690/python/Doc/lib Modified Files: libstdtypes.tex Log Message: Mention the new file() builtin in the section on file objects. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.73 retrieving revision 1.74 diff -C2 -d -r1.73 -r1.74 *** libstdtypes.tex 2001/10/26 18:57:14 1.73 --- libstdtypes.tex 2001/10/30 05:54:04 1.74 *************** *** 1188,1194 **** File objects are implemented using C's \code{stdio} package and can be ! created with the built-in function ! \function{open()}\bifuncindex{open} described in section ! \ref{built-in-funcs}, ``Built-in Functions.'' They are also returned by some other built-in functions and methods, such as \function{os.popen()} and \function{os.fdopen()} and the --- 1188,1197 ---- File objects are implemented using C's \code{stdio} package and can be ! created with the built-in constructor ! \function{file()}\bifuncindex{file} described in section ! \ref{built-in-funcs}, ``Built-in Functions.''\footnote{\function{file()} ! is new in Python 2.2. The older built-in \function{open()} is an ! alias for \function{file()}.} ! They are also returned by some other built-in functions and methods, such as \function{os.popen()} and \function{os.fdopen()} and the From tim_one@users.sourceforge.net Tue Oct 30 05:56:42 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 29 Oct 2001 21:56:42 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib imaplib.py,1.38,1.39 os.py,1.49,1.50 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv672/python/Lib Modified Files: imaplib.py os.py Log Message: Whitespace normalization. Index: imaplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/imaplib.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** imaplib.py 2001/10/22 00:42:26 1.38 --- imaplib.py 2001/10/30 05:56:40 1.39 *************** *** 227,231 **** sent = self.sock.send(data) if sent == bytes: ! break # avoid copy data = data[sent:] bytes = bytes - sent --- 227,231 ---- sent = self.sock.send(data) if sent == bytes: ! break # avoid copy data = data[sent:] bytes = bytes - sent Index: os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/os.py,v retrieving revision 1.49 retrieving revision 1.50 diff -C2 -d -r1.49 -r1.50 *** os.py 2001/10/24 20:29:30 1.49 --- os.py 2001/10/30 05:56:40 1.50 *************** *** 363,367 **** # Fake unsetenv() for Windows ! # not sure about os2 and dos here but # I'm guessing they are the same. --- 363,367 ---- # Fake unsetenv() for Windows ! # not sure about os2 and dos here but # I'm guessing they are the same. *************** *** 422,426 **** unsetenv(key) del self.data[key] ! environ = _Environ(environ) --- 422,426 ---- unsetenv(key) del self.data[key] ! environ = _Environ(environ) From tim_one@users.sourceforge.net Tue Oct 30 05:56:42 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 29 Oct 2001 21:56:42 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test regrtest.py,1.65,1.66 test_mimetypes.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv672/python/Lib/test Modified Files: regrtest.py test_mimetypes.py Log Message: Whitespace normalization. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.65 retrieving revision 1.66 diff -C2 -d -r1.65 -r1.66 *** regrtest.py 2001/10/24 20:32:02 1.65 --- regrtest.py 2001/10/30 05:56:40 1.66 *************** *** 39,43 **** curses - Tests that use curses and will modify the terminal's state and output modes. ! largefile - It is okay to run some test that may create huge files. These tests can take a long time and may consume >2GB of disk space --- 39,43 ---- curses - Tests that use curses and will modify the terminal's state and output modes. ! largefile - It is okay to run some test that may create huge files. These tests can take a long time and may consume >2GB of disk space Index: test_mimetypes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mimetypes.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_mimetypes.py 2001/10/25 21:49:18 1.3 --- test_mimetypes.py 2001/10/30 05:56:40 1.4 *************** *** 40,44 **** def test_non_standard_types(self): ! # First try strict self.assertEqual(self.db.guess_type('foo.xul', strict=1), (None, None)) --- 40,44 ---- def test_non_standard_types(self): ! # First try strict self.assertEqual(self.db.guess_type('foo.xul', strict=1), (None, None)) From fdrake@users.sourceforge.net Tue Oct 30 06:21:34 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 29 Oct 2001 22:21:34 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib lib.tex,1.193,1.194 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv13652/lib Modified Files: lib.tex Log Message: Promote built-in functions to come before built-in types. Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.193 retrieving revision 1.194 diff -C2 -d -r1.193 -r1.194 *** lib.tex 2001/09/28 22:03:40 1.193 --- lib.tex 2001/10/30 06:21:32 1.194 *************** *** 68,74 **** \input{libobjs} % Built-in Types, Exceptions and Functions \input{libstdtypes} \input{libexcs} - \input{libfuncs} \input{libpython} % Python Runtime Services --- 68,74 ---- \input{libobjs} % Built-in Types, Exceptions and Functions + \input{libfuncs} \input{libstdtypes} \input{libexcs} \input{libpython} % Python Runtime Services From fdrake@users.sourceforge.net Tue Oct 30 06:22:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 29 Oct 2001 22:22:04 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libobjs.tex,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv13857/lib Modified Files: libobjs.tex Log Message: Promote built-in functions to come before built-in types. Index: libobjs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libobjs.tex,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** libobjs.tex 2000/09/09 03:31:17 1.9 --- libobjs.tex 2001/10/30 06:22:02 1.10 *************** *** 1,5 **** ! \chapter{Built-in Types, Exceptions and Functions} ! \nodename{Built-in Objects} ! \label{builtin} Names for built-in exceptions and functions are found in a separate --- 1,3 ---- ! \chapter{Built-in Functions, Types, and Exceptions \label{builtin}} Names for built-in exceptions and functions are found in a separate From fdrake@users.sourceforge.net Tue Oct 30 06:23:17 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 29 Oct 2001 22:23:17 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libstdtypes.tex,1.74,1.75 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv14472/lib Modified Files: libstdtypes.tex Log Message: Promote file objects out of the "Other Objects" category, so they become visible in the table of contents. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -d -r1.74 -r1.75 *** libstdtypes.tex 2001/10/30 05:54:04 1.74 --- libstdtypes.tex 2001/10/30 06:23:14 1.75 *************** *** 1016,1192 **** ! \subsection{Other Built-in Types \label{typesother}} ! ! The interpreter supports several other kinds of objects. ! Most of these support only one or two operations. ! ! ! \subsubsection{Modules \label{typesmodules}} ! ! The only special operation on a module is attribute access: ! \code{\var{m}.\var{name}}, where \var{m} is a module and \var{name} ! accesses a name defined in \var{m}'s symbol table. Module attributes ! can be assigned to. (Note that the \keyword{import} statement is not, ! strictly speaking, an operation on a module object; \code{import ! \var{foo}} does not require a module object named \var{foo} to exist, ! rather it requires an (external) \emph{definition} for a module named ! \var{foo} somewhere.) ! ! A special member of every module is \member{__dict__}. ! This is the dictionary containing the module's symbol table. ! Modifying this dictionary will actually change the module's symbol ! table, but direct assignment to the \member{__dict__} attribute is not ! possible (you can write \code{\var{m}.__dict__['a'] = 1}, which ! defines \code{\var{m}.a} to be \code{1}, but you can't write ! \code{\var{m}.__dict__ = \{\}}. ! ! Modules built into the interpreter are written like this: ! \code{}. If loaded from a file, they are ! written as \code{}. ! ! ! \subsubsection{Classes and Class Instances \label{typesobjects}} ! \nodename{Classes and Instances} ! ! See chapters 3 and 7 of the \citetitle[../ref/ref.html]{Python ! Reference Manual} for these. ! ! ! \subsubsection{Functions \label{typesfunctions}} ! ! Function objects are created by function definitions. The only ! operation on a function object is to call it: ! \code{\var{func}(\var{argument-list})}. ! ! There are really two flavors of function objects: built-in functions ! and user-defined functions. Both support the same operation (to call ! the function), but the implementation is different, hence the ! different object types. ! ! The implementation adds two special read-only attributes: ! \code{\var{f}.func_code} is a function's \dfn{code ! object}\obindex{code} (see below) and \code{\var{f}.func_globals} is ! the dictionary used as the function's global namespace (this is the ! same as \code{\var{m}.__dict__} where \var{m} is the module in which ! the function \var{f} was defined). ! ! Function objects also support getting and setting arbitrary ! attributes, which can be used to, e.g. attach metadata to functions. ! Regular attribute dot-notation is used to get and set such ! attributes. \emph{Note that the current implementation only supports ! function attributes on user-defined functions. Function attributes on ! built-in functions may be supported in the future.} ! ! Functions have another special attribute \code{\var{f}.__dict__} ! (a.k.a. \code{\var{f}.func_dict}) which contains the namespace used to ! support function attributes. \code{__dict__} and \code{func_dict} can ! be accessed directly or set to a dictionary object. A function's ! dictionary cannot be deleted. ! ! \subsubsection{Methods \label{typesmethods}} ! \obindex{method} ! ! Methods are functions that are called using the attribute notation. ! There are two flavors: built-in methods (such as \method{append()} on ! lists) and class instance methods. Built-in methods are described ! with the types that support them. ! ! The implementation adds two special read-only attributes to class ! instance methods: \code{\var{m}.im_self} is the object on which the ! method operates, and \code{\var{m}.im_func} is the function ! implementing the method. Calling \code{\var{m}(\var{arg-1}, ! \var{arg-2}, \textrm{\ldots}, \var{arg-n})} is completely equivalent to ! calling \code{\var{m}.im_func(\var{m}.im_self, \var{arg-1}, ! \var{arg-2}, \textrm{\ldots}, \var{arg-n})}. ! ! Class instance methods are either \emph{bound} or \emph{unbound}, ! referring to whether the method was accessed through an instance or a ! class, respectively. When a method is unbound, its \code{im_self} ! attribute will be \code{None} and if called, an explicit \code{self} ! object must be passed as the first argument. In this case, ! \code{self} must be an instance of the unbound method's class (or a ! subclass of that class), otherwise a \code{TypeError} is raised. ! ! Like function objects, methods objects support getting ! arbitrary attributes. However, since method attributes are actually ! stored on the underlying function object (\code{meth.im_func}), ! setting method attributes on either bound or unbound methods is ! disallowed. Attempting to set a method attribute results in a ! \code{TypeError} being raised. In order to set a method attribute, ! you need to explicitly set it on the underlying function object: ! ! \begin{verbatim} ! class C: ! def method(self): ! pass ! ! c = C() ! c.method.im_func.whoami = 'my name is c' ! \end{verbatim} ! ! See the \citetitle[../ref/ref.html]{Python Reference Manual} for more ! information. ! ! ! \subsubsection{Code Objects \label{bltin-code-objects}} ! \obindex{code} ! ! Code objects are used by the implementation to represent ! ``pseudo-compiled'' executable Python code such as a function body. ! They differ from function objects because they don't contain a ! reference to their global execution environment. Code objects are ! returned by the built-in \function{compile()} function and can be ! extracted from function objects through their \member{func_code} ! attribute. ! \bifuncindex{compile} ! \withsubitem{(function object attribute)}{\ttindex{func_code}} ! ! A code object can be executed or evaluated by passing it (instead of a ! source string) to the \keyword{exec} statement or the built-in ! \function{eval()} function. ! \stindex{exec} ! \bifuncindex{eval} ! ! See the \citetitle[../ref/ref.html]{Python Reference Manual} for more ! information. ! ! ! \subsubsection{Type Objects \label{bltin-type-objects}} ! ! Type objects represent the various object types. An object's type is ! accessed by the built-in function \function{type()}. There are no special ! operations on types. The standard module \module{types} defines names ! for all standard built-in types. ! \bifuncindex{type} ! \refstmodindex{types} ! ! Types are written like this: \code{}. ! ! ! \subsubsection{The Null Object \label{bltin-null-object}} ! ! This object is returned by functions that don't explicitly return a ! value. It supports no special operations. There is exactly one null ! object, named \code{None} (a built-in name). ! ! It is written as \code{None}. ! ! ! \subsubsection{The Ellipsis Object \label{bltin-ellipsis-object}} ! ! This object is used by extended slice notation (see the ! \citetitle[../ref/ref.html]{Python Reference Manual}). It supports no ! special operations. There is exactly one ellipsis object, named ! \constant{Ellipsis} (a built-in name). ! ! It is written as \code{Ellipsis}. ! ! ! \subsubsection{File Objects\obindex{file} ! \label{bltin-file-objects}} ! File objects are implemented using C's \code{stdio} package and can be ! created with the built-in constructor \function{file()}\bifuncindex{file} described in section \ref{built-in-funcs}, ``Built-in Functions.''\footnote{\function{file()} --- 1016,1024 ---- ! \subsection{File Objects ! \label{bltin-file-objects}} ! File objects\obindex{file} are implemented using C's \code{stdio} ! package and can be created with the built-in constructor \function{file()}\bifuncindex{file} described in section \ref{built-in-funcs}, ``Built-in Functions.''\footnote{\function{file()} *************** *** 1371,1374 **** --- 1203,1374 ---- \keyword{print} to keep track of its internal state.} \end{memberdesc} + + + \subsection{Other Built-in Types \label{typesother}} + + The interpreter supports several other kinds of objects. + Most of these support only one or two operations. + + + \subsubsection{Modules \label{typesmodules}} + + The only special operation on a module is attribute access: + \code{\var{m}.\var{name}}, where \var{m} is a module and \var{name} + accesses a name defined in \var{m}'s symbol table. Module attributes + can be assigned to. (Note that the \keyword{import} statement is not, + strictly speaking, an operation on a module object; \code{import + \var{foo}} does not require a module object named \var{foo} to exist, + rather it requires an (external) \emph{definition} for a module named + \var{foo} somewhere.) + + A special member of every module is \member{__dict__}. + This is the dictionary containing the module's symbol table. + Modifying this dictionary will actually change the module's symbol + table, but direct assignment to the \member{__dict__} attribute is not + possible (you can write \code{\var{m}.__dict__['a'] = 1}, which + defines \code{\var{m}.a} to be \code{1}, but you can't write + \code{\var{m}.__dict__ = \{\}}. + + Modules built into the interpreter are written like this: + \code{}. If loaded from a file, they are + written as \code{}. + + + \subsubsection{Classes and Class Instances \label{typesobjects}} + \nodename{Classes and Instances} + + See chapters 3 and 7 of the \citetitle[../ref/ref.html]{Python + Reference Manual} for these. + + + \subsubsection{Functions \label{typesfunctions}} + + Function objects are created by function definitions. The only + operation on a function object is to call it: + \code{\var{func}(\var{argument-list})}. + + There are really two flavors of function objects: built-in functions + and user-defined functions. Both support the same operation (to call + the function), but the implementation is different, hence the + different object types. + + The implementation adds two special read-only attributes: + \code{\var{f}.func_code} is a function's \dfn{code + object}\obindex{code} (see below) and \code{\var{f}.func_globals} is + the dictionary used as the function's global namespace (this is the + same as \code{\var{m}.__dict__} where \var{m} is the module in which + the function \var{f} was defined). + + Function objects also support getting and setting arbitrary + attributes, which can be used to, e.g. attach metadata to functions. + Regular attribute dot-notation is used to get and set such + attributes. \emph{Note that the current implementation only supports + function attributes on user-defined functions. Function attributes on + built-in functions may be supported in the future.} + + Functions have another special attribute \code{\var{f}.__dict__} + (a.k.a. \code{\var{f}.func_dict}) which contains the namespace used to + support function attributes. \code{__dict__} and \code{func_dict} can + be accessed directly or set to a dictionary object. A function's + dictionary cannot be deleted. + + \subsubsection{Methods \label{typesmethods}} + \obindex{method} + + Methods are functions that are called using the attribute notation. + There are two flavors: built-in methods (such as \method{append()} on + lists) and class instance methods. Built-in methods are described + with the types that support them. + + The implementation adds two special read-only attributes to class + instance methods: \code{\var{m}.im_self} is the object on which the + method operates, and \code{\var{m}.im_func} is the function + implementing the method. Calling \code{\var{m}(\var{arg-1}, + \var{arg-2}, \textrm{\ldots}, \var{arg-n})} is completely equivalent to + calling \code{\var{m}.im_func(\var{m}.im_self, \var{arg-1}, + \var{arg-2}, \textrm{\ldots}, \var{arg-n})}. + + Class instance methods are either \emph{bound} or \emph{unbound}, + referring to whether the method was accessed through an instance or a + class, respectively. When a method is unbound, its \code{im_self} + attribute will be \code{None} and if called, an explicit \code{self} + object must be passed as the first argument. In this case, + \code{self} must be an instance of the unbound method's class (or a + subclass of that class), otherwise a \code{TypeError} is raised. + + Like function objects, methods objects support getting + arbitrary attributes. However, since method attributes are actually + stored on the underlying function object (\code{meth.im_func}), + setting method attributes on either bound or unbound methods is + disallowed. Attempting to set a method attribute results in a + \code{TypeError} being raised. In order to set a method attribute, + you need to explicitly set it on the underlying function object: + + \begin{verbatim} + class C: + def method(self): + pass + + c = C() + c.method.im_func.whoami = 'my name is c' + \end{verbatim} + + See the \citetitle[../ref/ref.html]{Python Reference Manual} for more + information. + + + \subsubsection{Code Objects \label{bltin-code-objects}} + \obindex{code} + + Code objects are used by the implementation to represent + ``pseudo-compiled'' executable Python code such as a function body. + They differ from function objects because they don't contain a + reference to their global execution environment. Code objects are + returned by the built-in \function{compile()} function and can be + extracted from function objects through their \member{func_code} + attribute. + \bifuncindex{compile} + \withsubitem{(function object attribute)}{\ttindex{func_code}} + + A code object can be executed or evaluated by passing it (instead of a + source string) to the \keyword{exec} statement or the built-in + \function{eval()} function. + \stindex{exec} + \bifuncindex{eval} + + See the \citetitle[../ref/ref.html]{Python Reference Manual} for more + information. + + + \subsubsection{Type Objects \label{bltin-type-objects}} + + Type objects represent the various object types. An object's type is + accessed by the built-in function \function{type()}. There are no special + operations on types. The standard module \module{types} defines names + for all standard built-in types. + \bifuncindex{type} + \refstmodindex{types} + + Types are written like this: \code{}. + + + \subsubsection{The Null Object \label{bltin-null-object}} + + This object is returned by functions that don't explicitly return a + value. It supports no special operations. There is exactly one null + object, named \code{None} (a built-in name). + + It is written as \code{None}. + + + \subsubsection{The Ellipsis Object \label{bltin-ellipsis-object}} + + This object is used by extended slice notation (see the + \citetitle[../ref/ref.html]{Python Reference Manual}). It supports no + special operations. There is exactly one ellipsis object, named + \constant{Ellipsis} (a built-in name). + + It is written as \code{Ellipsis}. From jackjansen@users.sourceforge.net Tue Oct 30 13:08:42 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 30 Oct 2001 05:08:42 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python import.c,2.190,2.191 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv19622/python/Python Modified Files: import.c Log Message: On the macintosh don't take a quick exit in find_module() for frozen submodule imports: the frozen import goes through a different mechanism. Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.190 retrieving revision 2.191 diff -C2 -d -r2.190 -r2.191 *** import.c 2001/10/25 21:38:59 2.190 --- import.c 2001/10/30 13:08:39 2.191 *************** *** 894,897 **** --- 894,904 ---- strcat(buf, name); strcpy(name, buf); + #ifdef macintosh + /* Freezing on the mac works different, and the modules are + ** actually on sys.path. So we don't take the quick exit but + ** continue with the normal flow. + */ + path = NULL; + #else if (find_frozen(name) != NULL) { strcpy(buf, name); *************** *** 901,904 **** --- 908,912 ---- "No frozen submodule named %.200s", name); return NULL; + #endif } if (path == NULL) { From jackjansen@users.sourceforge.net Tue Oct 30 13:11:26 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 30 Oct 2001 05:11:26 -0800 Subject: [Python-checkins] CVS: python/dist/src/Tools/bgen/bgen scantools.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/bgen/bgen In directory usw-pr-cvs1:/tmp/cvs-serv20560/python/Tools/bgen/bgen Modified Files: scantools.py Log Message: Don't override asplit_pat in Scanner_UH3. No reason to do so, and it broke generating Waste. Index: scantools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/scantools.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** scantools.py 2001/07/17 20:44:50 1.23 --- scantools.py 2001/10/30 13:11:24 1.24 *************** *** 581,585 **** self.sym_pat = "^[ \t]*\([a-zA-Z0-9_]+\)[ \t]*=" + \ "[ \t]*\([-0-9'\"][^\t\n,;}]*\),?" - self.asplit_pat = "^\(.*[^a-zA-Z0-9_]\)\([a-zA-Z0-9_]+\)$" class Scanner_OSX(Scanner): --- 581,584 ---- From jhylton@users.sourceforge.net Tue Oct 30 14:16:20 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Tue, 30 Oct 2001 06:16:20 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib asyncore.py,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv5134 Modified Files: asyncore.py Log Message: /F observes that we need an else: in connect() Index: asyncore.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asyncore.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** asyncore.py 2001/10/29 16:44:37 1.26 --- asyncore.py 2001/10/30 14:16:17 1.27 *************** *** 309,313 **** self.connected = 1 self.handle_connect() ! raise socket.error, err def accept (self): --- 309,314 ---- self.connected = 1 self.handle_connect() ! else: ! raise socket.error, err def accept (self): From fdrake@users.sourceforge.net Tue Oct 30 16:09:53 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 30 Oct 2001 08:09:53 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools mkhowto,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools In directory usw-pr-cvs1:/tmp/cvs-serv7491 Modified Files: mkhowto Log Message: Add a new option, --dvips-safe, which sets the $DVIPS_SAFE option in LaTeX2HTML. This is not safe to do in general (for the reasons LaTeX2HTML protects against dvips to begin with), but is safe if we do not actually need to run dvips. Note that we also assume it is safe if the user specifically requests PostScript generation. See the comments for further explanation. Index: mkhowto =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/mkhowto,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** mkhowto 2001/08/10 20:17:09 1.29 --- mkhowto 2001/10/30 16:09:51 1.30 *************** *** 110,113 **** --- 110,135 ---- up_title = None # + # 'dvips_safe' is a weird option. It is used mostly to make + # LaTeX2HTML not try to be too smart about protecting the user + # from a bad version of dvips -- some versions would core dump if + # the path to the source DVI contained a dot, and it's appearantly + # difficult to determine if the version available has that bug. + # This option gets set when PostScript output is requested + # (because we're going to run dvips regardless, and we'll either + # know it succeeds before LaTeX2HTML is run, or we'll have + # detected the failure and bailed), or the user asserts that it's + # safe from the command line. + # + # So, why does LaTeX2HTML think it appropriate to protect the user + # from a dvips that's only potentially going to core dump? Only + # because they want to avoid doing a lot of work just to have to + # bail later with no useful intermediates. Unfortunately, they + # bail *before* they know whether dvips will be needed at all. + # I've gone around the bush a few times with the LaTeX2HTML + # developers over whether this is appropriate behavior, and they + # don't seem interested in changing their position. + # + dvips_safe = 0 + # DEFAULT_FORMATS = ("html",) ALL_FORMATS = ("dvi", "html", "pdf", "ps", "text") *************** *** 132,140 **** "about=", "numeric", "style=", "paper=", "up-link=", "up-title=", "dir=", ! "global-module-index="] + list(self.ALL_FORMATS)) for opt, arg in opts: if opt == "--all": self.formats = list(self.ALL_FORMATS) elif opt in ("-H", "--help"): usage(self) --- 154,163 ---- "about=", "numeric", "style=", "paper=", "up-link=", "up-title=", "dir=", ! "global-module-index=", "dvips-safe"] + list(self.ALL_FORMATS)) for opt, arg in opts: if opt == "--all": self.formats = list(self.ALL_FORMATS) + self.dvips_safe = "ps" in self.formats elif opt in ("-H", "--help"): usage(self) *************** *** 186,189 **** --- 209,214 ---- elif opt == "--paper": self.paper = arg + elif opt == "--dvips-safe": + self.dvips_safe = 1 # # Format specifiers: *************** *** 203,206 **** --- 228,234 ---- """Add a format to the formats list if not present.""" if not format in self.formats: + if format == "ps": + # assume this is safe since we're going to run it anyway + self.dvips_safe = 1 self.formats.append(format) *************** *** 452,455 **** --- 480,484 ---- l2hoption(fp, "EXTERNAL_UP_TITLE", options.up_title) l2hoption(fp, "GLOBAL_MODULE_INDEX", options.global_module_index) + l2hoption(fp, "DVIPS_SAFE", options.dvips_safe) fp.write("1;\n") fp.close() From fdrake@users.sourceforge.net Tue Oct 30 16:28:49 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 30 Oct 2001 08:28:49 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile,1.230,1.231 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv15846 Modified Files: Makefile Log Message: Always use --dvips-safe when generating HTML for the standard documentation since we do not have anything that causes dvips to be run except when PostScript is specifically requested, which is a separate target. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile,v retrieving revision 1.230 retrieving revision 1.231 diff -C2 -d -r1.230 -r1.231 *** Makefile 2001/10/29 17:40:40 1.230 --- Makefile 2001/10/30 16:28:46 1.231 *************** *** 76,82 **** --address $(PYTHONDOCS) --up-link ../index.html \ --up-title "Python Documentation Index" \ ! --global-module-index "../modindex.html" MKISILOHTML=$(PYTHON) tools/mkhowto --html --about html/stdabout.dat \ ! --l2h-init perl/isilo.perl --numeric --split 1 MKISILO= iSilo386 -U -y -rCR -d0 MKPDF= $(PYTHON) ../tools/mkhowto --paper=$(PAPER) --pdf --- 76,83 ---- --address $(PYTHONDOCS) --up-link ../index.html \ --up-title "Python Documentation Index" \ ! --global-module-index "../modindex.html" --dvips-safe MKISILOHTML=$(PYTHON) tools/mkhowto --html --about html/stdabout.dat \ ! --l2h-init perl/isilo.perl --numeric --split 1 \ ! --dvips-safe MKISILO= iSilo386 -U -y -rCR -d0 MKPDF= $(PYTHON) ../tools/mkhowto --paper=$(PAPER) --pdf From tim_one@users.sourceforge.net Tue Oct 30 21:09:57 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 30 Oct 2001 13:09:57 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.133,1.134 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv2389/python/Misc Modified Files: ACKS Log Message: SF bug #474077 2.2b1: Error compiling extns with BCC Removed "#undef HAVE_HYPOT" line from Borland config, as suggested. Whether this will break some other Borland usage is a good question I can't answer. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.133 retrieving revision 1.134 diff -C2 -d -r1.133 -r1.134 *** ACKS 2001/10/30 03:03:03 1.133 --- ACKS 2001/10/30 21:09:55 1.134 *************** *** 24,27 **** --- 24,28 ---- Stig Bakken Greg Ball + Luigi Ballabio Cesar Eduardo Barros Des Barry From tim_one@users.sourceforge.net Tue Oct 30 21:09:57 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 30 Oct 2001 13:09:57 -0800 Subject: [Python-checkins] CVS: python/dist/src/PC pyconfig.h,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory usw-pr-cvs1:/tmp/cvs-serv2389/python/PC Modified Files: pyconfig.h Log Message: SF bug #474077 2.2b1: Error compiling extns with BCC Removed "#undef HAVE_HYPOT" line from Borland config, as suggested. Whether this will break some other Borland usage is a good question I can't answer. Index: pyconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/pyconfig.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pyconfig.h 2001/09/06 00:32:15 1.4 --- pyconfig.h 2001/10/30 21:09:55 1.5 *************** *** 181,185 **** #define LONG_LONG __int64 - #undef HAVE_HYPOT #undef HAVE_SYS_UTIME_H #define HAVE_UTIME_H --- 181,184 ---- From akuchling@users.sourceforge.net Tue Oct 30 21:12:16 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Tue, 30 Oct 2001 13:12:16 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0237.txt,1.12,1.13 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv3850 Modified Files: pep-0237.txt Log Message: Typo fixes Index: pep-0237.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0237.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** pep-0237.txt 2001/08/23 04:34:41 1.12 --- pep-0237.txt 2001/10/30 21:12:14 1.13 *************** *** 101,106 **** bits, if returning a short int would lose bits. ! - Currently, hex and oct literals for for short ints may specify ! negative values; for example 0xffffffff == -1 on a 32-bint machine. This will be changed to equal 0xffffffffL (2**32-1). --- 101,106 ---- bits, if returning a short int would lose bits. ! - Currently, hex and oct literals for short ints may specify ! negative values; for example 0xffffffff == -1 on a 32-bit machine. This will be changed to equal 0xffffffffL (2**32-1). *************** *** 193,197 **** incompatibilities which will break some old code, this phase may require a future statement and/or warnings, and a ! prolongued transition phase. Phase A will be implemented in Python 2.2. --- 193,197 ---- incompatibilities which will break some old code, this phase may require a future statement and/or warnings, and a ! prolonged transition phase. Phase A will be implemented in Python 2.2. *************** *** 200,204 **** stages of phase B: ! B1. The remaining semantic differenes are addressed. Operations that give different results than before will issue a warning that is on by default. A warning for the use of long literals --- 200,204 ---- stages of phase B: ! B1. The remaining semantic differences are addressed. Operations that give different results than before will issue a warning that is on by default. A warning for the use of long literals *************** *** 315,319 **** A complete implementation of phase A is present in the current CVS ! tree and will be release with Python 2.2a3. (It didn't make it into 2.2a2.) Still missing are documentation and a test suite. --- 315,319 ---- A complete implementation of phase A is present in the current CVS ! tree and will be released with Python 2.2a3. (It didn't make it into 2.2a2.) Still missing are documentation and a test suite. From jackjansen@users.sourceforge.net Tue Oct 30 22:41:41 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 30 Oct 2001 14:41:41 -0800 Subject: [Python-checkins] CVS: python/dist/src/Mac/Distributions src.exclude,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions In directory usw-pr-cvs1:/tmp/cvs-serv29159/Python/Mac/Distributions Modified Files: src.exclude Log Message: Files used for MacPython 2.2b1 distribution. Index: src.exclude =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/src.exclude,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** src.exclude 2001/09/08 21:36:37 1.6 --- src.exclude 2001/10/30 22:41:39 1.7 *************** *** 20,21 **** --- 20,22 ---- PyIDE-src [(]*[)] + *.pyo From jackjansen@users.sourceforge.net Tue Oct 30 22:41:45 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 30 Oct 2001 14:41:45 -0800 Subject: [Python-checkins] CVS: python/dist/src/Mac/Distributions src.include,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions In directory usw-pr-cvs1:/tmp/cvs-serv29180/Python/Mac/Distributions Modified Files: src.include Log Message: Files used for MacPython 2.2b1 distribution. Index: src.include =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/src.include,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** src.include 2001/09/08 21:36:42 1.6 --- src.include 2001/10/30 22:41:43 1.7 *************** *** 62,65 **** --- 62,67 ---- (':Mac:MPW', '') (':Mac:Modules', '') + (':Mac:OSX', '') + (':Mac:OSXResources', '') (':Mac:Python', '') (':Mac:ReadMe', '') *************** *** 89,92 **** --- 91,95 ---- (':PC', None) (':PCbuild', None) + (':PLAN.txt', '') (':Parser', '') (':PlugIns', None) *************** *** 95,98 **** --- 98,102 ---- (':Python68K', None) (':PythonApplet', None) + (':PythonCarbonStandalone', None) (':PythonCore', None) (':PythonCoreCarbon', None) *************** *** 104,107 **** --- 108,112 ---- (':PythonStandCarbon', None) (':PythonStandSmall', None) + (':PythonStandSmallCarbon', None) (':PythonStandSmallShGUSI', None) (':PythonStandSmallThreading', None) *************** *** 137,143 **** (':setup.py', None) (':site-packages', None) ! (':PLAN.txt', '') ! (':PythonStandSmallCarbon', None) ! (':PythonCarbonStandalone', None) ! (':Mac:OSXResources', '') ! (':Mac:OSX', '') --- 142,144 ---- (':setup.py', None) (':site-packages', None) ! (':Mac:Distributions:(vise)', None) From jackjansen@users.sourceforge.net Tue Oct 30 22:42:48 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 30 Oct 2001 14:42:48 -0800 Subject: [Python-checkins] CVS: python/dist/src/Mac/Distributions/(vise) Python 2.2.vct,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions/(vise) In directory usw-pr-cvs1:/tmp/cvs-serv29202/Python/Mac/Distributions/(vise) Modified Files: Python 2.2.vct Log Message: Files used for MacPython 2.2b1 distribution. Index: Python 2.2.vct =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/(vise)/Python 2.2.vct,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 Binary files /tmp/cvseTC98J and /tmp/cvs2lnMKo differ From jackjansen@users.sourceforge.net Tue Oct 30 22:48:39 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 30 Oct 2001 14:48:39 -0800 Subject: [Python-checkins] CVS: python/dist/src/Mac/Python macmain.c,1.70,1.71 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Python In directory usw-pr-cvs1:/tmp/cvs-serv31168/Python/Mac/Python Modified Files: macmain.c Log Message: Mod by Donovan Preston to allow MacPython to live in a Python.app bundle and understand the __main__.py convention used there for applets. This gives us applets that work on both OS9 and OSX! (Although "applet" may not be the correct word for something that is going to be multimegabyte:-). But: the code is currently disabled, as it requires CodeWarrior 7 and I'm still using 6. Index: macmain.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Python/macmain.c,v retrieving revision 1.70 retrieving revision 1.71 diff -C2 -d -r1.70 -r1.71 *** macmain.c 2001/09/11 13:08:10 1.70 --- macmain.c 2001/10/30 22:48:36 1.71 *************** *** 39,42 **** --- 39,49 ---- #include #include + #if TARGET_API_MAC_CARBON + #include + #include + #include + #include + #include + #endif /* TARGET_API_MAC_CARBON */ #ifdef USE_APPEARANCE #include *************** *** 488,492 **** #endif /* USE_MAC_APPLET_SUPPORT */ ! #if TARGET_API_MAC_OSX static int --- 495,499 ---- #endif /* USE_MAC_APPLET_SUPPORT */ ! #if TARGET_API_MAC_OSX /* Really: TARGET_API_MAC_CARBON */ static int *************** *** 496,538 **** CFStringRef filenameString, filepathString, rsrcString; CFIndex size, i; ! CFArrayRef arrayRef; ! Boolean success = 0; ! ! /* Create a CFString with the resource name in it */ ! rsrcString = CFStringCreateWithCString(0, resourceName, kCFStringEncodingMacRoman); /* Get a reference to our main bundle */ mainBundle = CFBundleGetMainBundle(); ! /* Look for py files in the main bundle by type */ ! arrayRef = CFBundleCopyResourceURLsOfType( mainBundle, ! CFSTR("py"), ! NULL ); ! /* See if there are any filename matches */ ! size = CFArrayGetCount(arrayRef); ! for (i = 0; i < size; i++) { ! URL = CFArrayGetValueAtIndex(arrayRef, i); ! filenameString = CFURLCopyLastPathComponent(URL); ! if (CFStringCompare(filenameString, rsrcString, 0) == kCFCompareEqualTo) { ! /* We found a match, get the file's full path */ ! absoluteURL = CFURLCopyAbsoluteURL(URL); ! filepathString = CFURLCopyFileSystemPath(absoluteURL, kCFURLPOSIXPathStyle); ! CFRelease(absoluteURL); ! /* Copy the full path into the caller's character buffer */ ! success = CFStringGetCString(filepathString, resourceURLCStr, length, ! kCFStringEncodingMacRoman); ! CFRelease(filepathString); ! } ! CFRelease(filenameString); ! } ! CFRelease(rsrcString); ! CFRelease(arrayRef); return success; } int main(int argc, char **argv) --- 503,557 ---- CFStringRef filenameString, filepathString, rsrcString; CFIndex size, i; ! CFArrayRef arrayRef = NULL; ! int success = 0; ! ! #if TARGET_API_MAC_OSX ! CFURLPathStyle thePathStyle = kCFURLPOSIXPathStyle; ! #else ! CFURLPathStyle thePathStyle = kCFURLHFSPathStyle; ! #endif /* Get a reference to our main bundle */ mainBundle = CFBundleGetMainBundle(); ! /* If we are running inside a bundle, look through it. Otherwise, do nothing. */ ! if (mainBundle) { ! /* Create a CFString with the resource name in it */ ! rsrcString = CFStringCreateWithCString(0, resourceName, kCFStringEncodingMacRoman); ! /* Look for py files in the main bundle by type */ ! arrayRef = CFBundleCopyResourceURLsOfType( mainBundle, ! CFSTR("py"), ! NULL ); ! /* See if there are any filename matches */ ! size = CFArrayGetCount(arrayRef); ! for (i = 0; i < size; i++) { ! URL = CFArrayGetValueAtIndex(arrayRef, i); ! filenameString = CFURLCopyLastPathComponent(URL); ! if (CFStringCompare(filenameString, rsrcString, 0) == kCFCompareEqualTo) { ! /* We found a match, get the file's full path */ ! absoluteURL = CFURLCopyAbsoluteURL(URL); ! filepathString = CFURLCopyFileSystemPath(absoluteURL, thePathStyle); ! CFRelease(absoluteURL); ! /* Copy the full path into the caller's character buffer */ ! success = CFStringGetCString(filepathString, resourceURLCStr, length, ! kCFStringEncodingMacRoman); + CFRelease(filepathString); + } + CFRelease(filenameString); + } + CFRelease(arrayRef); + CFRelease(rsrcString); + } return success; } + #endif /* TARGET_API_MAC_CARBON */ + + #if TARGET_API_MAC_OSX + int main(int argc, char **argv) *************** *** 581,585 **** --- 600,613 ---- char **argv; + static char scriptpath[1024]; + char *script = NULL; + init_common(&argc, &argv, 0); + + #if TARGET_API_MAC_OSX /* Really: TARGET_API_MAC_CARBON */ + /* If we are running inside of a bundle, and a __main__.py is available, use it */ + if (locateResourcePy("__main__.py", scriptpath, 1024)) + script = scriptpath; + #endif if ( argc > 1 ) { *************** *** 604,608 **** } } ! Py_Main(argc, argv, NULL); } #endif /* TARGET_API_MAC_OSX */ --- 632,636 ---- } } ! Py_Main(argc, argv, script); } #endif /* TARGET_API_MAC_OSX */ From tim_one@users.sourceforge.net Tue Oct 30 23:20:48 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 30 Oct 2001 15:20:48 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects structseq.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv7600/python/Objects Modified Files: structseq.c Log Message: Fix bad bug in structseq slicing (NULL pointers in result). Reported by Jack Jansen on python-dev. Add simple test case. Move vereq() from test_descr to test_support (it's handy!). Index: structseq.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/structseq.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** structseq.c 2001/10/18 20:47:51 1.1 --- structseq.c 2001/10/30 23:20:46 1.2 *************** *** 76,80 **** PyObject *v = obj->ob_item[i]; Py_INCREF(v); ! PyTuple_SET_ITEM(np, i, v); } return (PyObject *) np; --- 76,80 ---- PyObject *v = obj->ob_item[i]; Py_INCREF(v); ! PyTuple_SET_ITEM(np, i-low, v); } return (PyObject *) np; From tim_one@users.sourceforge.net Tue Oct 30 23:20:48 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 30 Oct 2001 15:20:48 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_structseq.py,NONE,1.1 test_descr.py,1.101,1.102 test_support.py,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv7600/python/Lib/test Modified Files: test_descr.py test_support.py Added Files: test_structseq.py Log Message: Fix bad bug in structseq slicing (NULL pointers in result). Reported by Jack Jansen on python-dev. Add simple test case. Move vereq() from test_descr to test_support (it's handy!). --- NEW FILE: test_structseq.py --- from test_support import vereq import time t = time.gmtime() astuple = tuple(t) vereq(len(t), len(astuple)) vereq(t, astuple) # Check that slicing works the same way; at one point, slicing t[i:j] with # 0 < i < j could produce NULLs in the result. for i in range(-len(t), len(t)): for j in range(-len(t), len(t)): vereq(t[i:j], astuple[i:j]) XXX more needed Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.101 retrieving revision 1.102 diff -C2 -d -r1.101 -r1.102 *** test_descr.py 2001/10/30 05:45:26 1.101 --- test_descr.py 2001/10/30 23:20:46 1.102 *************** *** 1,10 **** # Test enhancements related to descriptors and new-style classes ! from test_support import verify, verbose, TestFailed, TESTFN from copy import deepcopy - - def vereq(a, b): - if not (a == b): - raise TestFailed, "%r == %r" % (a, b) def veris(a, b): --- 1,6 ---- # Test enhancements related to descriptors and new-style classes ! from test_support import verify, vereq, verbose, TestFailed, TESTFN from copy import deepcopy def veris(a, b): Index: test_support.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_support.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** test_support.py 2001/10/04 19:46:07 1.39 --- test_support.py 2001/10/30 23:20:46 1.40 *************** *** 118,121 **** --- 118,125 ---- raise TestFailed(reason) + def vereq(a, b): + if not (a == b): + raise TestFailed, "%r == %r" % (a, b) + def sortdict(dict): "Like repr(dict), but in sorted order." From akuchling@users.sourceforge.net Wed Oct 31 02:26:27 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Tue, 30 Oct 2001 18:26:27 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0247.txt,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv12561 Modified Files: pep-0247.txt Log Message: Finalize interface for keyed hashes, and add a paragraph to the rationale section describing the reasoning behind using (key, [string]) as the signature. This PEP is ready to be marked Final. Index: pep-0247.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0247.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** pep-0247.txt 2001/10/22 02:10:29 1.8 --- pep-0247.txt 2001/10/31 02:26:25 1.9 *************** *** 24,36 **** Hash function modules define one function: ! new([string]) ! new([key] , [string]) Create a new hashing object and return it. The first form is ! for hashes that are unkeyed; most hashes such as MD5 or SHA ! are unkeyed. For keyed hashes such as HMAC, 'key' is a string ! containing the starting key. The 'string' parameter, if ! supplied, will be immediately hashed into the object's ! starting state, as if obj.update(string) was called. After creating a hashing object, arbitrary strings can be fed --- 24,37 ---- Hash function modules define one function: ! new([string]) (unkeyed hashes) ! new([key] , [string]) (keyed hashes) Create a new hashing object and return it. The first form is ! for hashes that are unkeyed, such as MD5 or SHA. For keyed ! hashes such as HMAC, 'key' is a required parameter containing ! a string giving the key to use. In both cases, the optional ! 'string' parameter, if supplied, will be immediately hashed ! into the object's starting state, as if obj.update(string) was ! called. After creating a hashing object, arbitrary strings can be fed *************** *** 132,135 **** --- 133,146 ---- used by the md5 and sha modules included with Python, so it seems simplest to leave the name update() alone. + + The order of the constructor's arguments for keyed hashes was a + sticky issue. It wasn't clear whether the key should come first + or second. It's a required parameter, and the usual convention is + to place required parameters first, but that also means that the + 'string' parameter moves from the first position to the second. + It would be possible to get confused and pass a single argument to + a keyed hash, thinking that you're passing an initial string to an + unkeyed hash, but it doesn't seem worth making the interface + for keyed hashes more obscure to avoid this potential error. From tim_one@users.sourceforge.net Wed Oct 31 03:46:16 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 30 Oct 2001 19:46:16 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_structseq.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv24960/python/Lib/test Modified Files: test_structseq.py Log Message: Huh. In an effort to be less thorough , seems I checked in a new test that wouldn't even compile, Index: test_structseq.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_structseq.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_structseq.py 2001/10/30 23:20:46 1.1 --- test_structseq.py 2001/10/31 03:46:14 1.2 *************** *** 14,16 **** vereq(t[i:j], astuple[i:j]) ! XXX more needed --- 14,16 ---- vereq(t[i:j], astuple[i:j]) ! # XXX more needed From tim_one@users.sourceforge.net Wed Oct 31 03:50:47 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 30 Oct 2001 19:50:47 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.134,1.135 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv25639/python/Misc Modified Files: ACKS Log Message: SF patch #474500: Make OS/2 locks work like posix locks, from Michael Muller. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.134 retrieving revision 1.135 diff -C2 -d -r1.134 -r1.135 *** ACKS 2001/10/30 21:09:55 1.134 --- ACKS 2001/10/31 03:50:45 1.135 *************** *** 298,301 **** --- 298,302 ---- Sape Mullender Sjoerd Mullender + Michael Muller Takahiro Nakayama Travers Naran From tim_one@users.sourceforge.net Wed Oct 31 03:50:47 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 30 Oct 2001 19:50:47 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python thread_os2.h,2.11,2.12 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv25639/python/Python Modified Files: thread_os2.h Log Message: SF patch #474500: Make OS/2 locks work like posix locks, from Michael Muller. Index: thread_os2.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/thread_os2.h,v retrieving revision 2.11 retrieving revision 2.12 diff -C2 -d -r2.11 -r2.12 *** thread_os2.h 2001/10/16 21:13:49 2.11 --- thread_os2.h 2001/10/31 03:50:45 2.12 *************** *** 102,114 **** /* ! * Lock support. It has too be implemented as semaphores. ! * I [Dag] tried to implement it with mutex but I could find a way to ! * tell whether a thread already own the lock or not. */ PyThread_type_lock PyThread_allocate_lock(void) { - HMTX aLock; APIRET rc; dprintf(("PyThread_allocate_lock called\n")); --- 102,120 ---- /* ! * Lock support. This is implemented with an event semaphore and critical ! * sections to make it behave more like a posix mutex than its OS/2 ! # counterparts. */ + + typedef struct os2_lock_t { + int is_set; + HEV changed; + } *type_os2_lock; + PyThread_type_lock PyThread_allocate_lock(void) { APIRET rc; + type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t)); dprintf(("PyThread_allocate_lock called\n")); *************** *** 116,127 **** PyThread_init_thread(); ! DosCreateMutexSem(NULL, /* Sem name */ ! &aLock, /* the semaphore */ ! 0, /* shared ? */ ! 0); /* initial state */ ! dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock)); ! return (PyThread_type_lock) aLock; } --- 122,134 ---- PyThread_init_thread(); ! lock->is_set = 0; ! DosCreateEventSem(NULL, &lock->changed, 0, 0); ! dprintf(("%ld: PyThread_allocate_lock() -> %p\n", ! PyThread_get_thread_ident(), ! lock->changed)); ! ! return (PyThread_type_lock) lock; } *************** *** 129,135 **** PyThread_free_lock(PyThread_type_lock aLock) { dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); ! DosCloseMutexSem((HMTX)aLock); } --- 136,144 ---- PyThread_free_lock(PyThread_type_lock aLock) { + type_os2_lock lock = (type_os2_lock)aLock; dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); ! DosCloseEventSem(lock->changed); ! free(aLock); } *************** *** 137,181 **** * Return 1 on success if the lock was acquired * ! * and 0 if the lock was not acquired. This means a 0 is returned ! * if the lock has already been acquired by this thread! */ int PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag) { ! int success = 1; ! ULONG rc, count; PID pid = 0; TID tid = 0; dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(), aLock, waitflag)); ! DosQueryMutexSem((HMTX)aLock,&pid,&tid,&count); ! if( tid == PyThread_get_thread_ident() ) { /* if we own this lock */ ! success = 0; ! } else { ! rc = DosRequestMutexSem((HMTX) aLock, ! (waitflag == 1 ? SEM_INDEFINITE_WAIT : 0)); ! if( rc != 0) { ! success = 0; /* We failed */ } - } ! dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", ! PyThread_get_thread_ident(),aLock, waitflag, success)); ! return success; } ! void ! PyThread_release_lock(PyThread_type_lock aLock) { dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); ! if ( DosReleaseMutexSem( (HMTX) aLock ) != 0 ) { dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", PyThread_get_thread_ident(), aLock, GetLastError())); } } --- 146,212 ---- * Return 1 on success if the lock was acquired * ! * and 0 if the lock was not acquired. */ int PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag) { ! int done = 0; ! ULONG count; PID pid = 0; TID tid = 0; + type_os2_lock lock = (type_os2_lock)aLock; dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(), aLock, waitflag)); ! while (!done) { ! /* if the lock is currently set, we have to wait for the state to change */ ! if (lock->is_set) { ! if (!waitflag) ! return 0; ! DosWaitEventSem(lock->changed, SEM_INDEFINITE_WAIT); ! } ! /* ! * enter a critical section and try to get the semaphore. If ! * it is still locked, we will try again. ! */ ! if (DosEnterCritSec()) ! return 0; ! ! if (!lock->is_set) { ! lock->is_set = 1; ! DosResetEventSem(lock->changed, &count); ! done = 1; } ! DosExitCritSec(); ! } ! return 1; } ! void PyThread_release_lock(PyThread_type_lock aLock) { + type_os2_lock lock = (type_os2_lock)aLock; dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); ! if (!lock->is_set) { ! dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", ! PyThread_get_thread_ident(), aLock, GetLastError())); ! return; ! } ! ! ! if (DosEnterCritSec()) { dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", PyThread_get_thread_ident(), aLock, GetLastError())); + return; } + + lock->is_set = 0; + DosPostEventSem(lock->changed); + + DosExitCritSec(); } From tim_one@users.sourceforge.net Wed Oct 31 04:20:28 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 30 Oct 2001 20:20:28 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.135,1.136 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv30866/python/Misc Modified Files: ACKS Log Message: SF patch #474485: pydoc generates some bad html, from Rich Salz. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.135 retrieving revision 1.136 diff -C2 -d -r1.135 -r1.136 *** ACKS 2001/10/31 03:50:45 1.135 --- ACKS 2001/10/31 04:20:26 1.136 *************** *** 409,412 **** --- 409,413 ---- RajGopal Srinivasan Jim St. Pierre + Rich Salz Quentin Stafford-Fraser Frank Stajano From tim_one@users.sourceforge.net Wed Oct 31 04:20:28 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 30 Oct 2001 20:20:28 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.55,1.56 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv30866/python/Lib Modified Files: pydoc.py Log Message: SF patch #474485: pydoc generates some bad html, from Rich Salz. Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** pydoc.py 2001/10/18 19:56:16 1.55 --- pydoc.py 2001/10/31 04:20:26 1.56 *************** *** 332,336 **** """Format an HTML page.""" return ''' ! Python: %s