From rhettinger@users.sourceforge.net Sat Mar 1 01:44:34 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 28 Feb 2003 17:44:34 -0800 Subject: [Python-checkins] python/dist/src/Objects abstract.c,2.118,2.119 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv32068 Modified Files: abstract.c Log Message: Removed duplicate test from inner loop. The PyIter_Check is already performed by PyObject_GetIter. Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.118 retrieving revision 2.119 diff -C2 -d -r2.118 -r2.119 *** abstract.c 18 Feb 2003 16:33:49 -0000 2.118 --- abstract.c 1 Mar 2003 01:44:32 -0000 2.119 *************** *** 2183,2192 **** { PyObject *result; ! if (!PyIter_Check(iter)) { ! PyErr_Format(PyExc_TypeError, ! "'%.100s' object is not an iterator", ! iter->ob_type->tp_name); ! return NULL; ! } result = (*iter->ob_type->tp_iternext)(iter); if (result == NULL && --- 2183,2187 ---- { PyObject *result; ! assert(PyIter_Check(iter)); result = (*iter->ob_type->tp_iternext)(iter); if (result == NULL && From rhettinger@users.sourceforge.net Sat Mar 1 01:48:26 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Fri, 28 Feb 2003 17:48:26 -0800 Subject: [Python-checkins] python/dist/src/Modules itertoolsmodule.c,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv883 Modified Files: itertoolsmodule.c Log Message: Several of the tools can make direct calls the inner iterators. Index: itertoolsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/itertoolsmodule.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** itertoolsmodule.c 23 Feb 2003 04:40:07 -0000 1.6 --- itertoolsmodule.c 1 Mar 2003 01:48:24 -0000 1.7 *************** *** 236,243 **** { PyObject *item, *good; long ok; for (;;) { ! item = PyIter_Next(lz->it); if (item == NULL) return NULL; --- 236,245 ---- { PyObject *item, *good; + PyObject *it = lz->it; long ok; for (;;) { ! assert(PyIter_Check(it)); ! item = (*it->ob_type->tp_iternext)(it); if (item == NULL) return NULL; *************** *** 390,393 **** --- 392,396 ---- { PyObject *item, *good; + PyObject *it = lz->it; long ok; *************** *** 395,399 **** return NULL; ! item = PyIter_Next(lz->it); if (item == NULL) return NULL; --- 398,403 ---- return NULL; ! assert(PyIter_Check(it)); ! item = (*it->ob_type->tp_iternext)(it); if (item == NULL) return NULL; *************** *** 561,568 **** { PyObject *item; long oldnext; while (lz->cnt < lz->next) { ! item = PyIter_Next(lz->it); if (item == NULL) return NULL; --- 565,574 ---- { PyObject *item; + PyObject *it = lz->it; long oldnext; while (lz->cnt < lz->next) { ! assert(PyIter_Check(it)); ! item = (*it->ob_type->tp_iternext)(it); if (item == NULL) return NULL; *************** *** 572,576 **** if (lz->cnt >= lz->stop) return NULL; ! item = PyIter_Next(lz->it); if (item == NULL) return NULL; --- 578,583 ---- if (lz->cnt >= lz->stop) return NULL; ! assert(PyIter_Check(it)); ! item = (*it->ob_type->tp_iternext)(it); if (item == NULL) return NULL; *************** *** 716,721 **** PyObject *args; PyObject *result; ! args = PyIter_Next(lz->it); if (args == NULL) return NULL; --- 723,730 ---- PyObject *args; PyObject *result; + PyObject *it = lz->it; ! assert(PyIter_Check(it)); ! args = (*it->ob_type->tp_iternext)(it); if (args == NULL) return NULL; *************** *** 1195,1202 **** { PyObject *item; long ok; for (;;) { ! item = PyIter_Next(lz->it); if (item == NULL) return NULL; --- 1204,1213 ---- { PyObject *item; + PyObject *it = lz->it; long ok; for (;;) { ! assert(PyIter_Check(it)); ! item = (*it->ob_type->tp_iternext)(it); if (item == NULL) return NULL; *************** *** 1349,1356 **** { PyObject *item; long ok; for (;;) { ! item = PyIter_Next(lz->it); if (item == NULL) return NULL; --- 1360,1369 ---- { PyObject *item; + PyObject *it = lz->it; long ok; for (;;) { ! assert(PyIter_Check(it)); ! item = (*it->ob_type->tp_iternext)(it); if (item == NULL) return NULL; *************** *** 1627,1631 **** for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); ! item = PyIter_Next(it); if (item == NULL) return NULL; --- 1640,1645 ---- for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); ! assert(PyIter_Check(it)); ! item = (*it->ob_type->tp_iternext)(it); if (item == NULL) return NULL; *************** *** 1640,1644 **** for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); ! item = PyIter_Next(it); if (item == NULL) { Py_DECREF(result); --- 1654,1659 ---- for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); ! assert(PyIter_Check(it)); ! item = (*it->ob_type->tp_iternext)(it); if (item == NULL) { Py_DECREF(result); From gvanrossum@users.sourceforge.net Sat Mar 1 02:14:54 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 28 Feb 2003 18:14:54 -0800 Subject: [Python-checkins] python/dist/src/Lib cmd.py,1.26.16.3,1.26.16.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv9709/Lib Modified Files: Tag: release22-maint cmd.py Log Message: - Backported SF patch #676342: after using pdb, the readline command completion was botched. Index: cmd.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/cmd.py,v retrieving revision 1.26.16.3 retrieving revision 1.26.16.4 diff -C2 -d -r1.26.16.3 -r1.26.16.4 *** cmd.py 13 Jan 2003 21:21:00 -0000 1.26.16.3 --- cmd.py 1 Mar 2003 02:14:52 -0000 1.26.16.4 *************** *** 87,97 **** """ self.cmdqueue = [] ! if completekey: ! try: ! import readline ! readline.set_completer(self.complete) ! readline.parse_and_bind(completekey+": complete") ! except ImportError: ! pass def cmdloop(self, intro=None): --- 87,91 ---- """ self.cmdqueue = [] ! self.completekey = completekey def cmdloop(self, intro=None): *************** *** 144,148 **** def preloop(self): """Hook method executed once when the cmdloop() method is called.""" ! pass def postloop(self): --- 138,149 ---- def preloop(self): """Hook method executed once when the cmdloop() method is called.""" ! if self.completekey: ! try: ! import readline ! self.old_completer = readline.get_completer() ! readline.set_completer(self.complete) ! readline.parse_and_bind(self.completekey+": complete") ! except ImportError: ! pass def postloop(self): *************** *** 151,155 **** """ ! pass def parseline(self, line): --- 152,161 ---- """ ! if self.completekey: ! try: ! import readline ! readline.set_completer(self.old_completer) ! except ImportError: ! pass def parseline(self, line): From gvanrossum@users.sourceforge.net Sat Mar 1 02:14:55 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 28 Feb 2003 18:14:55 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.337.2.4.2.63,1.337.2.4.2.64 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv9709/Misc Modified Files: Tag: release22-maint NEWS Log Message: - Backported SF patch #676342: after using pdb, the readline command completion was botched. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.337.2.4.2.63 retrieving revision 1.337.2.4.2.64 diff -C2 -d -r1.337.2.4.2.63 -r1.337.2.4.2.64 *** NEWS 23 Feb 2003 23:45:16 -0000 1.337.2.4.2.63 --- NEWS 1 Mar 2003 02:14:52 -0000 1.337.2.4.2.64 *************** *** 3,6 **** --- 3,9 ---- ============================ + - Backported SF patch #676342: after using pdb, the readline command + completion was botched. + - Fix problem building on OSF1 because the compiler only accepted preprocessor directives that start in column 1. (SF bug #691793.) From gvanrossum@users.sourceforge.net Sat Mar 1 02:14:55 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 28 Feb 2003 18:14:55 -0800 Subject: [Python-checkins] python/dist/src/Modules readline.c,2.41.6.4,2.41.6.5 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv9709/Modules Modified Files: Tag: release22-maint readline.c Log Message: - Backported SF patch #676342: after using pdb, the readline command completion was botched. Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.41.6.4 retrieving revision 2.41.6.5 diff -C2 -d -r2.41.6.4 -r2.41.6.5 *** readline.c 7 Jan 2003 20:37:58 -0000 2.41.6.4 --- readline.c 1 Mar 2003 02:14:53 -0000 2.41.6.5 *************** *** 333,336 **** --- 333,353 ---- "; + static PyObject * + get_completer(PyObject *self, PyObject *args) + { + if (completer == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + Py_INCREF(completer); + return completer; + } + + static char doc_get_completer[] = "\ + get_completer() -> function\n\ + \n\ + Returns current completer function.\ + "; + /* Exported function to read the current line buffer */ *************** *** 386,389 **** --- 403,407 ---- METH_VARARGS, get_history_length_doc}, {"set_completer", set_completer, METH_VARARGS, doc_set_completer}, + {"get_completer", get_completer, METH_VARARGS, doc_get_completer}, {"get_begidx", get_begidx, METH_OLDARGS, doc_get_begidx}, {"get_endidx", get_endidx, METH_OLDARGS, doc_get_endidx}, From gvanrossum@users.sourceforge.net Sat Mar 1 03:20:42 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 28 Feb 2003 19:20:42 -0800 Subject: [Python-checkins] python/dist/src/Doc/tut tut.tex,1.176,1.177 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory sc8-pr-cvs1:/tmp/cvs-serv29053/Doc/tut Modified Files: tut.tex Log Message: - New function sys.exc_clear() clears the current exception. This is rarely needed, but can sometimes be useful to release objects referenced by the traceback held in sys.exc_info()[2]. (SF patch #693195.) Thanks to Kevin Jacobs! Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.176 retrieving revision 1.177 diff -C2 -d -r1.176 -r1.177 *** tut.tex 28 Oct 2002 19:28:22 -0000 1.176 --- tut.tex 1 Mar 2003 03:20:39 -0000 1.177 *************** *** 2452,2463 **** >>> dir(sys) ['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', ! '__stdin__', '__stdout__', '_getframe', 'argv', 'builtin_module_names', ! 'byteorder', 'copyright', 'displayhook', 'exc_info', 'exc_type', ! 'excepthook', 'exec_prefix', 'executable', 'exit', 'getdefaultencoding', ! 'getdlopenflags', 'getrecursionlimit', 'getrefcount', 'hexversion', ! 'maxint', 'maxunicode', 'modules', 'path', 'platform', 'prefix', 'ps1', ! 'ps2', 'setcheckinterval', 'setdlopenflags', 'setprofile', ! 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'version', ! 'version_info', 'warnoptions'] \end{verbatim} --- 2452,2464 ---- >>> dir(sys) ['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', ! '__stdin__', '__stdout__', '_getframe', 'api_version', 'argv', ! 'builtin_module_names', 'byteorder', 'callstats', 'copyright', ! 'displayhook', 'exc_clear', 'exc_info', 'exc_type', 'excepthook', ! 'exec_prefix', 'executable', 'exit', 'getdefaultencoding', 'getdlopenflags', ! 'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode', ! 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', ! 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags', ! 'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', ! 'version', 'version_info', 'warnoptions'] \end{verbatim} From gvanrossum@users.sourceforge.net Sat Mar 1 03:20:43 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 28 Feb 2003 19:20:43 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_sys.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv29053/Lib/test Modified Files: test_sys.py Log Message: - New function sys.exc_clear() clears the current exception. This is rarely needed, but can sometimes be useful to release objects referenced by the traceback held in sys.exc_info()[2]. (SF patch #693195.) Thanks to Kevin Jacobs! Index: test_sys.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sys.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_sys.py 19 Feb 2003 02:35:06 -0000 1.4 --- test_sys.py 1 Mar 2003 03:20:40 -0000 1.5 *************** *** 64,67 **** --- 64,111 ---- # Python/pythonrun.c::PyErr_PrintEx() is tricky. + def test_exc_clear(self): + self.assertRaises(TypeError, sys.exc_clear, 42) + + # Verify that exc_info is present and matches exc, then clear it, and + # check that it worked. + def clear_check(exc): + typ, value, traceback = sys.exc_info() + self.assert_(typ is not None) + self.assert_(value is exc) + self.assert_(traceback is not None) + + sys.exc_clear() + + typ, value, traceback = sys.exc_info() + self.assert_(typ is None) + self.assert_(value is None) + self.assert_(traceback is None) + + def clear(): + try: + raise ValueError, 42 + except ValueError, exc: + clear_check(exc) + + # Raise an exception and check that it can be cleared + clear() + + # Verify that a frame currently handling an exception is + # unaffected by calling exc_clear in a nested frame. + try: + raise ValueError, 13 + except ValueError, exc: + typ1, value1, traceback1 = sys.exc_info() + clear() + typ2, value2, traceback2 = sys.exc_info() + + self.assert_(typ1 is typ2) + self.assert_(value1 is exc) + self.assert_(value1 is value2) + self.assert_(traceback1 is traceback2) + + # Check that an exception can be cleared outside of an except block + clear_check(exc) + def test_exit(self): self.assertRaises(TypeError, sys.exit, 42, 42) From gvanrossum@users.sourceforge.net Sat Mar 1 03:20:43 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 28 Feb 2003 19:20:43 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.683,1.684 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv29053/Misc Modified Files: NEWS Log Message: - New function sys.exc_clear() clears the current exception. This is rarely needed, but can sometimes be useful to release objects referenced by the traceback held in sys.exc_info()[2]. (SF patch #693195.) Thanks to Kevin Jacobs! Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.683 retrieving revision 1.684 diff -C2 -d -r1.683 -r1.684 *** NEWS 28 Feb 2003 22:09:33 -0000 1.683 --- NEWS 1 Mar 2003 03:20:40 -0000 1.684 *************** *** 13,16 **** --- 13,22 ---- ----------------- + + - New function sys.exc_clear() clears the current exception. This is + rarely needed, but can sometimes be useful to release objects + referenced by the traceback held in sys.exc_info()[2]. (SF patch + #693195.) + - On 64-bit systems, a dictionary could contain duplicate long/int keys if the key value was larger than 2**32. See SF bug #689659. From gvanrossum@users.sourceforge.net Sat Mar 1 03:20:44 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 28 Feb 2003 19:20:44 -0800 Subject: [Python-checkins] python/dist/src/Python sysmodule.c,2.114,2.115 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv29053/Python Modified Files: sysmodule.c Log Message: - New function sys.exc_clear() clears the current exception. This is rarely needed, but can sometimes be useful to release objects referenced by the traceback held in sys.exc_info()[2]. (SF patch #693195.) Thanks to Kevin Jacobs! Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.114 retrieving revision 2.115 diff -C2 -d -r2.114 -r2.115 *** sysmodule.c 19 Feb 2003 15:24:39 -0000 2.114 --- sysmodule.c 1 Mar 2003 03:20:41 -0000 2.115 *************** *** 133,137 **** static PyObject * ! sys_exc_info(PyObject *self) { PyThreadState *tstate; --- 133,137 ---- static PyObject * ! sys_exc_info(PyObject *self, PyObject *noargs) { PyThreadState *tstate; *************** *** 148,153 **** "exc_info() -> (type, value, traceback)\n\ \n\ ! Return information about the exception that is currently being handled.\n\ ! This should be called from inside an except clause only." ); --- 148,184 ---- "exc_info() -> (type, value, traceback)\n\ \n\ ! Return information about the most recent exception caught by an except\n\ ! clause in the current stack frame or in an older stack frame." ! ); ! ! static PyObject * ! sys_exc_clear(PyObject *self, PyObject *noargs) ! { ! PyThreadState *tstate = PyThreadState_Get(); ! PyObject *tmp_type, *tmp_value, *tmp_tb; ! tmp_type = tstate->exc_type; ! tmp_value = tstate->exc_value; ! tmp_tb = tstate->exc_traceback; ! tstate->exc_type = NULL; ! tstate->exc_value = NULL; ! tstate->exc_traceback = NULL; ! Py_XDECREF(tmp_type); ! Py_XDECREF(tmp_value); ! Py_XDECREF(tmp_tb); ! /* For b/w compatibility */ ! PySys_SetObject("exc_type", Py_None); ! PySys_SetObject("exc_value", Py_None); ! PySys_SetObject("exc_traceback", Py_None); ! Py_INCREF(Py_None); ! return Py_None; ! } ! ! PyDoc_STRVAR(exc_clear_doc, ! "exc_clear() -> None\n\ ! \n\ ! Clear global information on the current exception. Subsequent calls to\n\ ! exc_info() will return (None,None,None) until another exception is raised\n\ ! in the current thread or the execution stack returns to a frame where\n\ ! another exception is being handled." ); *************** *** 601,605 **** callstats_doc}, {"displayhook", sys_displayhook, METH_O, displayhook_doc}, ! {"exc_info", (PyCFunction)sys_exc_info, METH_NOARGS, exc_info_doc}, {"excepthook", sys_excepthook, METH_VARARGS, excepthook_doc}, {"exit", sys_exit, METH_VARARGS, exit_doc}, --- 632,637 ---- callstats_doc}, {"displayhook", sys_displayhook, METH_O, displayhook_doc}, ! {"exc_info", sys_exc_info, METH_NOARGS, exc_info_doc}, ! {"exc_clear", sys_exc_clear, METH_NOARGS, exc_clear_doc}, {"excepthook", sys_excepthook, METH_VARARGS, excepthook_doc}, {"exit", sys_exit, METH_VARARGS, exit_doc}, *************** *** 787,790 **** --- 819,823 ---- excepthook() -- print an exception and its traceback to sys.stderr\n\ exc_info() -- return thread-safe information about the current exception\n\ + exc_clear() -- clear the exception state for the current thread\n\ exit() -- exit the interpreter by raising SystemExit\n\ getdlopenflags() -- returns flags to be used for dlopen() calls\n\ From gvanrossum@users.sourceforge.net Sat Mar 1 03:21:11 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 28 Feb 2003 19:21:11 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libsys.tex,1.61,1.62 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv29053/Doc/lib Modified Files: libsys.tex Log Message: - New function sys.exc_clear() clears the current exception. This is rarely needed, but can sometimes be useful to release objects referenced by the traceback held in sys.exc_info()[2]. (SF patch #693195.) Thanks to Kevin Jacobs! Index: libsys.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsys.tex,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -d -r1.61 -r1.62 *** libsys.tex 8 Oct 2002 02:44:29 -0000 1.61 --- libsys.tex 1 Mar 2003 03:20:38 -0000 1.62 *************** *** 100,103 **** --- 100,108 ---- originally occurred. \obindex{traceback} + If \function{exc_clear()} is called, this function will return three + \code{None} values until either another exception is raised in the + current thread or the execution stack returns to a frame where + another exception is being handled. + \warning{Assigning the \var{traceback} return value to a local variable in a function that is handling an exception will *************** *** 114,117 **** --- 119,137 ---- collection is enabled and they become unreachable, but it remains more efficient to avoid creating cycles.} + \end{funcdesc} + + \begin{funcdesc}{exc_clear}{} + This function clears all information relating to the current or last + exception that occured in the current thread. After calling this + function, \function{exc_info()} will return three \code{None} values until + another exception is raised in the current thread or the execution stack + returns to a frame where another exception is being handled. + + This function is only needed in only a few obscure situations. These + include logging and error handling systems that report information on the + last or current exception. This function can also be used to try to free + resources and trigger object finalization, though no guarantee is made as + to what objects will be freed, if any. + \versionadded{2.3} \end{funcdesc} From gvanrossum@users.sourceforge.net Sat Mar 1 03:25:44 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 28 Feb 2003 19:25:44 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_sys.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv30550 Modified Files: test_sys.py Log Message: Reindent the new code properly. Index: test_sys.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sys.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_sys.py 1 Mar 2003 03:20:40 -0000 1.5 --- test_sys.py 1 Mar 2003 03:25:41 -0000 1.6 *************** *** 70,90 **** # check that it worked. def clear_check(exc): ! typ, value, traceback = sys.exc_info() ! self.assert_(typ is not None) ! self.assert_(value is exc) ! self.assert_(traceback is not None) ! sys.exc_clear() ! typ, value, traceback = sys.exc_info() ! self.assert_(typ is None) ! self.assert_(value is None) ! self.assert_(traceback is None) def clear(): ! try: ! raise ValueError, 42 ! except ValueError, exc: ! clear_check(exc) # Raise an exception and check that it can be cleared --- 70,90 ---- # check that it worked. def clear_check(exc): ! typ, value, traceback = sys.exc_info() ! self.assert_(typ is not None) ! self.assert_(value is exc) ! self.assert_(traceback is not None) ! sys.exc_clear() ! typ, value, traceback = sys.exc_info() ! self.assert_(typ is None) ! self.assert_(value is None) ! self.assert_(traceback is None) def clear(): ! try: ! raise ValueError, 42 ! except ValueError, exc: ! clear_check(exc) # Raise an exception and check that it can be cleared *************** *** 94,107 **** # unaffected by calling exc_clear in a nested frame. try: ! raise ValueError, 13 except ValueError, exc: ! typ1, value1, traceback1 = sys.exc_info() ! clear() ! typ2, value2, traceback2 = sys.exc_info() ! self.assert_(typ1 is typ2) ! self.assert_(value1 is exc) ! self.assert_(value1 is value2) ! self.assert_(traceback1 is traceback2) # Check that an exception can be cleared outside of an except block --- 94,107 ---- # unaffected by calling exc_clear in a nested frame. try: ! raise ValueError, 13 except ValueError, exc: ! typ1, value1, traceback1 = sys.exc_info() ! clear() ! typ2, value2, traceback2 = sys.exc_info() ! self.assert_(typ1 is typ2) ! self.assert_(value1 is exc) ! self.assert_(value1 is value2) ! self.assert_(traceback1 is traceback2) # Check that an exception can be cleared outside of an except block From gvanrossum@users.sourceforge.net Sat Mar 1 03:36:35 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 28 Feb 2003 19:36:35 -0800 Subject: [Python-checkins] python/dist/src/Python ceval.c,2.352,2.353 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv607 Modified Files: ceval.c Log Message: Added implementation notes for [re]set_exc_info(). Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.352 retrieving revision 2.353 diff -C2 -d -r2.352 -r2.353 *** ceval.c 27 Feb 2003 14:50:34 -0000 2.352 --- ceval.c 1 Mar 2003 03:36:33 -0000 2.353 *************** *** 2617,2620 **** --- 2617,2681 ---- + /* Implementation notes for set_exc_info() and reset_exc_info(): + + - Below, 'exc_ZZZ' stands for 'exc_type', 'exc_value' and + 'exc_traceback'. These always travel together. + + - tstate->curexc_ZZZ is the "hot" exception that is set by + PyErr_SetString(), cleared by PyErr_Clear(), and so on. + + - Once an exception is caught by an except clause, it is transferred + from tstate->curexc_ZZZ to tstate->exc_ZZZ, from which sys.exc_info() + can pick it up. This is the primary task of set_exc_info(). + + - Now let me explain the complicated dance with frame->f_exc_ZZZ. + + Long ago, when none of this existed, there were just a few globals: + one set corresponding to the "hot" exception, and one set + corresponding to sys.exc_ZZZ. (Actually, the latter weren't C + globals; they were simply stored as sys.exc_ZZZ. For backwards + compatibility, they still are!) The problem was that in code like + this: + + try: + "something that may fail" + except "some exception": + "do something else first" + "print the exception from sys.exc_ZZZ." + + if "do something else first" invoked something that raised and caught + an exception, sys.exc_ZZZ were overwritten. That was a frequent + cause of subtle bugs. I fixed this by changing the semantics as + follows: + + - Within one frame, sys.exc_ZZZ will hold the last exception caught + *in that frame*. + + - But initially, and as long as no exception is caught in a given + frame, sys.exc_ZZZ will hold the last exception caught in the + previous frame (or the frame before that, etc.). + + The first bullet fixed the bug in the above example. The second + bullet was for backwards compatibility: it was (and is) common to + have a function that is called when an exception is caught, and to + have that function access the caught exception via sys.exc_ZZZ. + (Example: traceback.print_exc()). + + At the same time I fixed the problem that sys.exc_ZZZ weren't + thread-safe, by introducing sys.exc_info() which gets it from tstate; + but that's really a separate improvement. + + The reset_exc_info() function in ceval.c restores the tstate->exc_ZZZ + variables to what they were before the current frame was called. The + set_exc_info() function saves them on the frame so that + reset_exc_info() can restore them. The invariant is that + frame->f_exc_ZZZ is NULL iff the current frame never caught an + exception (where "catching" an exception applies only to successful + except clauses); and if the current frame ever caught an exception, + frame->f_exc_ZZZ is the exception that was stored in tstate->exc_ZZZ + at the start of the current frame. + + */ + static void set_exc_info(PyThreadState *tstate, From nnorwitz@users.sourceforge.net Sat Mar 1 15:19:44 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sat, 01 Mar 2003 07:19:44 -0800 Subject: [Python-checkins] python/dist/src/Modules readline.c,2.61,2.62 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv29285/Modules Modified Files: readline.c Log Message: get_completer() takes no args Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.61 retrieving revision 2.62 diff -C2 -d -r2.61 -r2.62 *** readline.c 21 Feb 2003 00:30:18 -0000 2.61 --- readline.c 1 Mar 2003 15:19:41 -0000 2.62 *************** *** 350,354 **** static PyObject * ! get_completer(PyObject *self, PyObject *args) { if (completer == NULL) { --- 350,354 ---- static PyObject * ! get_completer(PyObject *self, PyObject *noargs) { if (completer == NULL) { From nnorwitz@users.sourceforge.net Sat Mar 1 15:19:51 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sat, 01 Mar 2003 07:19:51 -0800 Subject: [Python-checkins] python/dist/src/Modules readline.c,2.41.6.5,2.41.6.6 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv29375/Modules Modified Files: Tag: release22-maint readline.c Log Message: get_completer() takes no args Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.41.6.5 retrieving revision 2.41.6.6 diff -C2 -d -r2.41.6.5 -r2.41.6.6 *** readline.c 1 Mar 2003 02:14:53 -0000 2.41.6.5 --- readline.c 1 Mar 2003 15:19:49 -0000 2.41.6.6 *************** *** 334,338 **** static PyObject * ! get_completer(PyObject *self, PyObject *args) { if (completer == NULL) { --- 334,338 ---- static PyObject * ! get_completer(PyObject *self, PyObject *noargs) { if (completer == NULL) { *************** *** 403,407 **** METH_VARARGS, get_history_length_doc}, {"set_completer", set_completer, METH_VARARGS, doc_set_completer}, ! {"get_completer", get_completer, METH_VARARGS, doc_get_completer}, {"get_begidx", get_begidx, METH_OLDARGS, doc_get_begidx}, {"get_endidx", get_endidx, METH_OLDARGS, doc_get_endidx}, --- 403,407 ---- METH_VARARGS, get_history_length_doc}, {"set_completer", set_completer, METH_VARARGS, doc_set_completer}, ! {"get_completer", get_completer, METH_NOARGS, doc_get_completer}, {"get_begidx", get_begidx, METH_OLDARGS, doc_get_begidx}, {"get_endidx", get_endidx, METH_OLDARGS, doc_get_endidx}, From nnorwitz@users.sourceforge.net Sat Mar 1 15:22:44 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sat, 01 Mar 2003 07:22:44 -0800 Subject: [Python-checkins] python/dist/src/Lib pydoc.py,1.78,1.79 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv31219/Lib Modified Files: pydoc.py Log Message: Fix SF patch #695581, "returnself" -> "return self" Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.78 retrieving revision 1.79 diff -C2 -d -r1.78 -r1.79 *** pydoc.py 27 Feb 2003 20:14:39 -0000 1.78 --- pydoc.py 1 Mar 2003 15:22:41 -0000 1.79 *************** *** 269,273 **** if inspect.ismodule(object): return self.docmodule(*args) if inspect.isclass(object): return self.docclass(*args) ! if inspect.isroutine(object): returnself.docroutine(*args) return self.docother(*args) --- 269,273 ---- if inspect.ismodule(object): return self.docmodule(*args) if inspect.isclass(object): return self.docclass(*args) ! if inspect.isroutine(object): return self.docroutine(*args) return self.docother(*args) From nnorwitz@users.sourceforge.net Sat Mar 1 22:58:02 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Sat, 01 Mar 2003 14:58:02 -0800 Subject: [Python-checkins] python/dist/src/Lib dumbdbm.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv31916/Lib Modified Files: dumbdbm.py Log Message: Fix comment, mode really is used Index: dumbdbm.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dumbdbm.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** dumbdbm.py 1 Jun 2002 14:25:41 -0000 1.19 --- dumbdbm.py 1 Mar 2003 22:58:00 -0000 1.20 *************** *** 167,170 **** """ ! # flag, mode arguments are currently ignored return _Database(file, mode) --- 167,170 ---- """ ! # flag argument is currently ignored return _Database(file, mode) From tim_one@users.sourceforge.net Sat Mar 1 23:33:36 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Mar 2003 15:33:36 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_sets.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv11029/Lib/test Modified Files: test_sets.py Log Message: The doctest was printing Sets, but that's unreliable because set elements get displayed in undefined dict order. Use a Set subclass instead (which arranges to sort the elements for display). Index: test_sets.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sets.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** test_sets.py 15 Jan 2003 16:15:38 -0000 1.19 --- test_sets.py 1 Mar 2003 23:33:34 -0000 1.20 *************** *** 642,646 **** Example from the Library Reference: Doc/lib/libsets.tex ! >>> from sets import Set >>> engineers = Set(['John', 'Jane', 'Jack', 'Janice']) >>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice']) --- 642,649 ---- Example from the Library Reference: Doc/lib/libsets.tex ! >>> from sets import Set as Base # override _repr to get sorted output ! >>> class Set(Base): ! ... def _repr(self): ! ... return Base._repr(self, sorted=True) >>> engineers = Set(['John', 'Jane', 'Jack', 'Janice']) >>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice']) *************** *** 651,655 **** >>> engineers.add('Marvin') >>> print engineers ! Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack']) >>> employees.issuperset(engineers) # superset test False --- 654,658 ---- >>> engineers.add('Marvin') >>> print engineers ! Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin']) >>> employees.issuperset(engineers) # superset test False *************** *** 661,668 **** ... print group ... ! Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack']) ! Set(['Janice', 'Jack', 'Sam']) ! Set(['Jane', 'Zack', 'Jack']) ! Set(['Zack', 'Sam', 'Marvin', 'Jack', 'Jane', 'Janice', 'John']) """ --- 664,671 ---- ... print group ... ! Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin']) ! Set(['Jack', 'Janice', 'Sam']) ! Set(['Jack', 'Jane', 'Zack']) ! Set(['Jack', 'Jane', 'Janice', 'John', 'Marvin', 'Sam', 'Zack']) """ From tim_one@users.sourceforge.net Sun Mar 2 00:19:51 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Mar 2003 16:19:51 -0800 Subject: [Python-checkins] python/dist/src/Lib sets.py,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv24329/Lib Modified Files: sets.py Log Message: SF bug 693121: Set == non-Set is a TypeError. Allow mixed-type __eq__ and __ne__ for Set objects. This is messier than I'd like because Set *also* implements __cmp__. I know of one glitch now: cmp(s, t) returns 0 now when s and t are both Sets and s == t, despite that Set.__cmp__ unconditionally raises TypeError (and by intent). The rub is that __eq__ gets tried first, and the x.__eq__(y) True result convinces Python that cmp(x, y) is 0 without even calling Set.__cmp__. Index: sets.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sets.py,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** sets.py 14 Feb 2003 03:42:11 -0000 1.42 --- sets.py 2 Mar 2003 00:19:49 -0000 1.43 *************** *** 103,120 **** return self._data.iterkeys() ! # Three-way comparison is not supported def __cmp__(self, other): raise TypeError, "can't compare sets using cmp()" ! # Equality comparisons using the underlying dicts def __eq__(self, other): ! self._binary_sanity_check(other) ! return self._data == other._data def __ne__(self, other): ! self._binary_sanity_check(other) ! return self._data != other._data # Copying operations --- 103,140 ---- return self._data.iterkeys() ! # Three-way comparison is not supported. However, because __eq__ is ! # tried before __cmp__, if Set x == Set y, x.__eq__(y) returns True and ! # then cmp(x, y) returns 0 (Python doesn't actually call __cmp__ in this ! # case). def __cmp__(self, other): raise TypeError, "can't compare sets using cmp()" ! # Equality comparisons using the underlying dicts. Mixed-type comparisons ! # are allowed here, where Set == z for non-Set z always returns False, ! # and Set != z always True. This allows expressions like "x in y" to ! # give the expected result when y is a sequence of mixed types, not ! # raising a pointless TypeError just because y contains a Set, or x is ! # a Set and y contain's a non-set ("in" invokes only __eq__). ! # Subtle: it would be nicer if __eq__ and __ne__ could return ! # NotImplemented instead of True or False. Then the other comparand ! # would get a chance to determine the result, and if the other comparand ! # also returned NotImplemented then it would fall back to object address ! # comparison (which would always return False for __eq__ and always ! # True for __ne__). However, that doesn't work, because this type ! # *also* implements __cmp__: if, e.g., __eq__ returns NotImplemented, ! # Python tries __cmp__ next, and the __cmp__ here then raises TypeError. def __eq__(self, other): ! if isinstance(other, BaseSet): ! return self._data == other._data ! else: ! return False def __ne__(self, other): ! if isinstance(other, BaseSet): ! return self._data != other._data ! else: ! return True # Copying operations From tim_one@users.sourceforge.net Sun Mar 2 00:19:51 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Mar 2003 16:19:51 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_sets.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv24329/Lib/test Modified Files: test_sets.py Log Message: SF bug 693121: Set == non-Set is a TypeError. Allow mixed-type __eq__ and __ne__ for Set objects. This is messier than I'd like because Set *also* implements __cmp__. I know of one glitch now: cmp(s, t) returns 0 now when s and t are both Sets and s == t, despite that Set.__cmp__ unconditionally raises TypeError (and by intent). The rub is that __eq__ gets tried first, and the x.__eq__(y) True result convinces Python that cmp(x, y) is 0 without even calling Set.__cmp__. Index: test_sets.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sets.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** test_sets.py 1 Mar 2003 23:33:34 -0000 1.20 --- test_sets.py 2 Mar 2003 00:19:49 -0000 1.21 *************** *** 233,237 **** def test_cmp(self): a, b = Set('a'), Set('b') ! self.assertRaises(TypeError, cmp, (a,b)) #============================================================================== --- 233,246 ---- def test_cmp(self): a, b = Set('a'), Set('b') ! self.assertRaises(TypeError, cmp, a, b) ! ! # You can view this as a buglet: cmp(a, a) does not raise TypeError, ! # because __eq__ is tried before __cmp__, and a.__eq__(a) returns, ! # which Python thinks is good enough to synthesize a cmp() result ! # without calling __cmp__. ! self.assertEqual(cmp(a, a), 0) ! ! self.assertRaises(TypeError, cmp, a, 12) ! self.assertRaises(TypeError, cmp, "abc", a) #============================================================================== *************** *** 477,491 **** class TestOnlySetsInBinaryOps(unittest.TestCase): ! def test_cmp(self): ! try: ! self.other == self.set ! self.fail("expected TypeError") ! except TypeError: ! pass ! try: ! self.set != self.other ! self.fail("expected TypeError") ! except TypeError: ! pass def test_union_update(self): --- 486,502 ---- class TestOnlySetsInBinaryOps(unittest.TestCase): ! def test_eq_ne(self): ! # Unlike the others, this is testing that == and != *are* allowed. ! self.assertEqual(self.other == self.set, False) ! self.assertEqual(self.set == self.other, False) ! self.assertEqual(self.other != self.set, True) ! self.assertEqual(self.set != self.other, True) ! ! def test_ge_gt_lt_le(self): ! # Unlike the others, this is testing that == and != *are* allowed. ! self.assertRaises(TypeError, lambda: self.set < self.other) ! self.assertRaises(TypeError, lambda: self.set <= self.other) ! self.assertRaises(TypeError, lambda: self.set > self.other) ! self.assertRaises(TypeError, lambda: self.set >= self.other) def test_union_update(self): From tim_one@users.sourceforge.net Sun Mar 2 00:19:52 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Mar 2003 16:19:52 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.684,1.685 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv24329/Misc Modified Files: NEWS Log Message: SF bug 693121: Set == non-Set is a TypeError. Allow mixed-type __eq__ and __ne__ for Set objects. This is messier than I'd like because Set *also* implements __cmp__. I know of one glitch now: cmp(s, t) returns 0 now when s and t are both Sets and s == t, despite that Set.__cmp__ unconditionally raises TypeError (and by intent). The rub is that __eq__ gets tried first, and the x.__eq__(y) True result convinces Python that cmp(x, y) is 0 without even calling Set.__cmp__. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.684 retrieving revision 1.685 diff -C2 -d -r1.684 -r1.685 *** NEWS 1 Mar 2003 03:20:40 -0000 1.684 --- NEWS 2 Mar 2003 00:19:49 -0000 1.685 *************** *** 32,35 **** --- 32,42 ---- ------- + - sets.Set objects now support mixed-type __eq__ and __ne__, instead + of raising TypeError. If x is a Set object and y is a non-Set object, + x == y is False, and x != y is True. This is akin to the change made + for mixed-type comparisons of datetime objects in 2.3a2; more info + about the rationale is in the NEWS entry for that. See also SF bug + report . + - os.listdir() now returns Unicode strings on platforms that set Py_FileSystemDefaultEncoding, for file names that are not representable *************** *** 84,88 **** - A new method MacOS.WMAvailable() returns true if it is safe to access the window manager, false otherwise. ! - EasyDialogs dialogs are now movable-modal. --- 91,95 ---- - A new method MacOS.WMAvailable() returns true if it is safe to access the window manager, false otherwise. ! - EasyDialogs dialogs are now movable-modal. *************** *** 344,349 **** pathsep, curdir, pardir and defpath are now defined in the platform dependent path modules (e.g. ntpath.py) rather than os.py, so these ! variables are now available via os.path. They continue to be ! available from the os module. (see ). --- 351,356 ---- pathsep, curdir, pardir and defpath are now defined in the platform dependent path modules (e.g. ntpath.py) rather than os.py, so these ! variables are now available via os.path. They continue to be ! available from the os module. (see ). *************** *** 500,509 **** - Type Carbon.File.FSCatalogInfo and supporting methods have been implemented. This also makes macfs.FSSpec.SetDates() work again. ! - There is a new module pimp, the package install manager for Python, and accompanying applet PackageManager. These allow you to easily download and install pretested extension packages either in source or binary form. Only in MacPython-OSX. ! - Applets are now built with bundlebuilder in MacPython-OSX, which should make them more robust and also provides a path towards BuildApplication. The --- 507,516 ---- - Type Carbon.File.FSCatalogInfo and supporting methods have been implemented. This also makes macfs.FSSpec.SetDates() work again. ! - There is a new module pimp, the package install manager for Python, and accompanying applet PackageManager. These allow you to easily download and install pretested extension packages either in source or binary form. Only in MacPython-OSX. ! - Applets are now built with bundlebuilder in MacPython-OSX, which should make them more robust and also provides a path towards BuildApplication. The From tim_one@users.sourceforge.net Sun Mar 2 00:31:26 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Mar 2003 16:31:26 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_sets.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv28203/Lib/test Modified Files: test_sets.py Log Message: Typo repairs in new code. Index: test_sets.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sets.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** test_sets.py 2 Mar 2003 00:19:49 -0000 1.21 --- test_sets.py 2 Mar 2003 00:31:23 -0000 1.22 *************** *** 236,240 **** # You can view this as a buglet: cmp(a, a) does not raise TypeError, ! # because __eq__ is tried before __cmp__, and a.__eq__(a) returns, # which Python thinks is good enough to synthesize a cmp() result # without calling __cmp__. --- 236,240 ---- # You can view this as a buglet: cmp(a, a) does not raise TypeError, ! # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True, # which Python thinks is good enough to synthesize a cmp() result # without calling __cmp__. *************** *** 493,502 **** self.assertEqual(self.set != self.other, True) ! def test_ge_gt_lt_le(self): ! # Unlike the others, this is testing that == and != *are* allowed. self.assertRaises(TypeError, lambda: self.set < self.other) self.assertRaises(TypeError, lambda: self.set <= self.other) self.assertRaises(TypeError, lambda: self.set > self.other) self.assertRaises(TypeError, lambda: self.set >= self.other) def test_union_update(self): --- 493,506 ---- self.assertEqual(self.set != self.other, True) ! def test_ge_gt_le_lt(self): self.assertRaises(TypeError, lambda: self.set < self.other) self.assertRaises(TypeError, lambda: self.set <= self.other) self.assertRaises(TypeError, lambda: self.set > self.other) self.assertRaises(TypeError, lambda: self.set >= self.other) + + self.assertRaises(TypeError, lambda: self.other < self.set) + self.assertRaises(TypeError, lambda: self.other <= self.set) + self.assertRaises(TypeError, lambda: self.other > self.set) + self.assertRaises(TypeError, lambda: self.other >= self.set) def test_union_update(self): From tim_one@users.sourceforge.net Sun Mar 2 00:36:12 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Mar 2003 16:36:12 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_sets.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv29004/Lib/test Modified Files: test_sets.py Log Message: TestOnlySetsInBinaryOps: Simplified the non-inplace tests by using assertRaises. Fixed a repeated subtle bug in the inplace tests by removing the possibilty that a self.fail() call could raise a TypeError that the test catches by mistake. Index: test_sets.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sets.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** test_sets.py 2 Mar 2003 00:31:23 -0000 1.22 --- test_sets.py 2 Mar 2003 00:36:10 -0000 1.23 *************** *** 507,582 **** try: self.set |= self.other - self.fail("expected TypeError") except TypeError: pass def test_union(self): ! try: ! self.other | self.set ! self.fail("expected TypeError") ! except TypeError: ! pass ! try: ! self.set | self.other ! self.fail("expected TypeError") ! except TypeError: ! pass def test_intersection_update(self): try: self.set &= self.other - self.fail("expected TypeError") except TypeError: pass def test_intersection(self): ! try: ! self.other & self.set ! self.fail("expected TypeError") ! except TypeError: ! pass ! try: ! self.set & self.other ! self.fail("expected TypeError") ! except TypeError: ! pass def test_sym_difference_update(self): try: self.set ^= self.other - self.fail("expected TypeError") except TypeError: pass def test_sym_difference(self): ! try: ! self.other ^ self.set ! self.fail("expected TypeError") ! except TypeError: ! pass ! try: ! self.set ^ self.other ! self.fail("expected TypeError") ! except TypeError: ! pass def test_difference_update(self): try: self.set -= self.other - self.fail("expected TypeError") except TypeError: pass def test_difference(self): ! try: ! self.other - self.set ! self.fail("expected TypeError") ! except TypeError: ! pass ! try: ! self.set - self.other ! self.fail("expected TypeError") ! except TypeError: ! pass #------------------------------------------------------------------------------ --- 507,554 ---- try: self.set |= self.other except TypeError: pass + else: + self.fail("expected TypeError") def test_union(self): ! self.assertRaises(TypeError, lambda: self.set | self.other) ! self.assertRaises(TypeError, lambda: self.other | self.set) def test_intersection_update(self): try: self.set &= self.other except TypeError: pass + else: + self.fail("expected TypeError") def test_intersection(self): ! self.assertRaises(TypeError, lambda: self.set & self.other) ! self.assertRaises(TypeError, lambda: self.other & self.set) def test_sym_difference_update(self): try: self.set ^= self.other except TypeError: pass + else: + self.fail("expected TypeError") def test_sym_difference(self): ! self.assertRaises(TypeError, lambda: self.set ^ self.other) ! self.assertRaises(TypeError, lambda: self.other ^ self.set) def test_difference_update(self): try: self.set -= self.other except TypeError: pass + else: + self.fail("expected TypeError") def test_difference(self): ! self.assertRaises(TypeError, lambda: self.set - self.other) ! self.assertRaises(TypeError, lambda: self.other - self.set) #------------------------------------------------------------------------------ From akuchling@users.sourceforge.net Sun Mar 2 02:13:55 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Sat, 01 Mar 2003 18:13:55 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.125,1.126 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv23268 Modified Files: whatsnew23.tex Log Message: Expand itertools paragraph Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.125 retrieving revision 1.126 diff -C2 -d -r1.125 -r1.126 *** whatsnew23.tex 26 Feb 2003 19:00:52 -0000 1.125 --- whatsnew23.tex 2 Mar 2003 02:13:52 -0000 1.126 *************** *** 1355,1361 **** (Contributed by Piers Lauder and Tino Lange.) ! \item The \ulink{\module{itertools}}{../lib/module-itertools.html} ! module provides several functions to support efficient looping using ! iterators. \item Two new functions in the \module{math} module, --- 1355,1367 ---- (Contributed by Piers Lauder and Tino Lange.) ! \item The \module{itertools} contains a number of useful functions for ! use with iterators, inspired by various functions provided by the ML ! and Haskell languages. For example, ! \code{itertools.ifilter(predicate, iterator)} returns all elements in ! the iterator for which the function \function{predicate()} returns ! \constant{True}, and \code{itertools.times(\var{N}, obj)} returns ! \code{obj} \var{N} times. There are a number of other functions in ! the module; see the \ulink{package's reference ! documentation}{../lib/module-itertools.html} for details. \item Two new functions in the \module{math} module, From akuchling@users.sourceforge.net Sun Mar 2 02:32:01 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Sat, 01 Mar 2003 18:32:01 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.126,1.127 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv27509 Modified Files: whatsnew23.tex Log Message: Add updates for alpha2 Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.126 retrieving revision 1.127 diff -C2 -d -r1.126 -r1.127 *** whatsnew23.tex 2 Mar 2003 02:13:52 -0000 1.126 --- whatsnew23.tex 2 Mar 2003 02:31:58 -0000 1.127 *************** *** 330,333 **** --- 330,335 ---- checking \member{os.path.supports_unicode_filenames}, a Boolean value. + Under MacOS, \function{os.listdir()} may now return Unicode filenames. + \begin{seealso} *************** *** 1360,1364 **** \code{itertools.ifilter(predicate, iterator)} returns all elements in the iterator for which the function \function{predicate()} returns ! \constant{True}, and \code{itertools.times(\var{N}, obj)} returns \code{obj} \var{N} times. There are a number of other functions in the module; see the \ulink{package's reference --- 1362,1366 ---- \code{itertools.ifilter(predicate, iterator)} returns all elements in the iterator for which the function \function{predicate()} returns ! \constant{True}, and \code{itertools.repeat(obj, \var{N})} returns \code{obj} \var{N} times. There are a number of other functions in the module; see the \ulink{package's reference *************** *** 1496,1501 **** Sockets Layer (SSL) support. ! \item The value of the C \constant{PYTHON_API_VERSION} macro is now exposed ! at the Python level as \code{sys.api_version}. \item The new \module{tarfile} module --- 1498,1505 ---- Sockets Layer (SSL) support. ! \item The value of the C \constant{PYTHON_API_VERSION} macro is now ! exposed at the Python level as \code{sys.api_version}. The current ! exception can be cleared by calling the new \function{sys.exc_clear()} ! function. \item The new \module{tarfile} module From bwarsaw@users.sourceforge.net Sun Mar 2 03:35:35 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sat, 01 Mar 2003 19:35:35 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.29,1.29.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv9256 Modified Files: Tag: folding-reimpl-branch test_email.py Log Message: A bunch of new tests, mostly from Tokio Kikuchi's SF patch 687338. Working on the new ASCII wrapping code and Tokio's improvements. Committing on a branch until the tests all pass. :/ Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.29 retrieving revision 1.29.4.1 diff -C2 -d -r1.29 -r1.29.4.1 *** test_email.py 2 Jan 2003 22:48:36 -0000 1.29 --- test_email.py 2 Mar 2003 03:35:33 -0000 1.29.4.1 *************** *** 567,571 **** cz_head = "Finan\xe8ni metropole se hroutily pod tlakem jejich d\xf9vtipu.. " utf8_head = u"\u6b63\u78ba\u306b\u8a00\u3046\u3068\u7ffb\u8a33\u306f\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u4e00\u90e8\u306f\u30c9\u30a4\u30c4\u8a9e\u3067\u3059\u304c\u3001\u3042\u3068\u306f\u3067\u305f\u3089\u3081\u3067\u3059\u3002\u5b9f\u969b\u306b\u306f\u300cWenn ist das Nunstuck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput.\u300d\u3068\u8a00\u3063\u3066\u3044\u307e\u3059\u3002".encode("utf-8") ! h = Header(g_head, g) h.append(cz_head, cz) h.append(utf8_head, utf8) --- 567,571 ---- cz_head = "Finan\xe8ni metropole se hroutily pod tlakem jejich d\xf9vtipu.. " utf8_head = u"\u6b63\u78ba\u306b\u8a00\u3046\u3068\u7ffb\u8a33\u306f\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u4e00\u90e8\u306f\u30c9\u30a4\u30c4\u8a9e\u3067\u3059\u304c\u3001\u3042\u3068\u306f\u3067\u305f\u3089\u3081\u3067\u3059\u3002\u5b9f\u969b\u306b\u306f\u300cWenn ist das Nunstuck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput.\u300d\u3068\u8a00\u3063\u3066\u3044\u307e\u3059\u3002".encode("utf-8") ! h = Header(g_head, g, header_name='Subject') h.append(cz_head, cz) h.append(utf8_head, utf8) *************** *** 575,612 **** g = Generator(sfp) g.flatten(msg) ! eq(sfp.getvalue(), '''\ ! Subject: =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_eine?= ! =?iso-8859-1?q?m_Foerderband_komfortabel_den_Korridor_ent?= ! =?iso-8859-1?q?lang=2C_an_s=FCdl=FCndischen_Wandgem=E4lden_vorbei?= ! =?iso-8859-1?q?=2C_gegen_die_rotierenden_Klingen_bef=F6rdert=2E_?= ! =?iso-8859-2?q?Finan=E8ni_metropole_se_hroutil?= ! =?iso-8859-2?q?y_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= ! =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv?= ! =?utf-8?b?44GV44KM44Gm44GE44G+44Gb44KT44CC5LiA?= ! =?utf-8?b?6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM?= ! =?utf-8?b?44CB44GC44Go44Gv44Gn44Gf44KJ44KB44Gn?= ! =?utf-8?b?44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBpc3QgZGE=?= ! =?utf-8?q?s_Nunstuck_git_und?= ! =?utf-8?q?_Slotermeyer=3F_Ja!_Beiherhund_das_Ode?= ! =?utf-8?q?r_die_Flipperwaldt?= ! =?utf-8?b?IGdlcnNwdXQu44CN44Go6KiA44Gj44Gm44GE44G+44GZ44CC?= ! ''') ! eq(h.encode(), '''\ ! =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_eine?= ! =?iso-8859-1?q?m_Foerderband_komfortabel_den_Korridor_ent?= ! =?iso-8859-1?q?lang=2C_an_s=FCdl=FCndischen_Wandgem=E4lden_vorbei?= ! =?iso-8859-1?q?=2C_gegen_die_rotierenden_Klingen_bef=F6rdert=2E_?= ! =?iso-8859-2?q?Finan=E8ni_metropole_se_hroutil?= ! =?iso-8859-2?q?y_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= ! =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv?= ! =?utf-8?b?44GV44KM44Gm44GE44G+44Gb44KT44CC5LiA?= ! =?utf-8?b?6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM?= ! =?utf-8?b?44CB44GC44Go44Gv44Gn44Gf44KJ44KB44Gn?= ! =?utf-8?b?44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBpc3QgZGE=?= ! =?utf-8?q?s_Nunstuck_git_und?= ! =?utf-8?q?_Slotermeyer=3F_Ja!_Beiherhund_das_Ode?= ! =?utf-8?q?r_die_Flipperwaldt?= ! =?utf-8?b?IGdlcnNwdXQu44CN44Go6KiA44Gj44Gm44GE44G+44GZ44CC?=''') def test_long_header_encode(self): --- 575,604 ---- g = Generator(sfp) g.flatten(msg) ! eq(sfp.getvalue(), """\ ! Subject: =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?= ! =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCnd?= ! =?iso-8859-1?q?ischen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kli?= ! =?iso-8859-1?q?ngen_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_metropol?= ! =?iso-8859-2?q?e_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= ! =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE44G+44Gb?= ! =?utf-8?b?44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB44GC44Go?= ! =?utf-8?b?44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBp?= ! =?utf-8?q?st_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das_Oder?= ! =?utf-8?b?IGRpZSBGbGlwcGVyd2FsZHQgZ2Vyc3B1dC7jgI3jgajoqIDjgaPjgabjgYQ=?= ! =?utf-8?b?44G+44GZ44CC?= ! """) ! eq(h.encode(), """\ ! =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?= ! =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCnd?= ! =?iso-8859-1?q?ischen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kli?= ! =?iso-8859-1?q?ngen_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_metropol?= ! =?iso-8859-2?q?e_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= ! =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE44G+44Gb?= ! =?utf-8?b?44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB44GC44Go?= ! =?utf-8?b?44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBp?= ! =?utf-8?q?st_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das_Oder?= ! =?utf-8?b?IGRpZSBGbGlwcGVyd2FsZHQgZ2Vyc3B1dC7jgI3jgajoqIDjgaPjgabjgYQ=?= ! =?utf-8?b?44G+44GZ44CC?=""") def test_long_header_encode(self): *************** *** 713,722 **** eq = self.ndiffAssertEqual msg = Message() ! h = Header('Britische Regierung gibt', 'iso-8859-1') h.append('gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte') msg['Subject'] = h eq(msg.as_string(), """\ ! Subject: =?iso-8859-1?q?Britische_Regierung_gibt?= ! =?iso-8859-1?q?gr=FCnes_Licht_f=FCr_Offshore-Windkraftprojekte?= """) --- 705,715 ---- eq = self.ndiffAssertEqual msg = Message() ! h = Header('Britische Regierung gibt', 'iso-8859-1', ! header_name='Subject') h.append('gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte') msg['Subject'] = h eq(msg.as_string(), """\ ! Subject: =?iso-8859-1?q?Britische_Regierung_gibt?= =?iso-8859-1?q?gr=FCnes?= ! =?iso-8859-1?q?_Licht_f=FCr_Offshore-Windkraftprojekte?= """) *************** *** 731,734 **** --- 724,769 ---- """) + def test_long_to_header(self): + eq = self.ndiffAssertEqual + to = '"Someone Test #A" ,,"Someone Test #B" , "Someone Test #C" , "Someone Test #D" ' + msg = Message() + msg['To'] = to + eq(msg.as_string(0), '''\ + To: "Someone Test #A" , , + \t"Someone Test #B" , + \t"Someone Test #C" , + \t"Someone Test #D" + + ''') + + def test_long_line_after_append(self): + eq = self.ndiffAssertEqual + s = 'This is an example of string which has almost the limit of header length.' + h = Header(s) + h.append('Add another line.') + eq(h.encode(), """\ + This is an example of string which has almost the limit of header length. + Add another line.""") + + def test_shorter_line_with_append(self): + eq = self.ndiffAssertEqual + s = 'This is a shorter line.' + h = Header(s) + h.append('Add another sentence. (Surprise?)') + eq(h.encode(), + 'This is a shorter line. Add another sentence. (Surprise?)') + + def test_long_field_name(self): + eq = self.ndiffAssertEqual + fn = 'X-Very-Very-Very-Long-Header-Name' + gs = "Die Mieter treten hier ein werden mit einem Foerderband komfortabel den Korridor entlang, an s\xfcdl\xfcndischen Wandgem\xe4lden vorbei, gegen die rotierenden Klingen bef\xf6rdert. " + h = Header(gs, 'iso-8859-1', header_name=fn) + # BAW: this seems broken because the first line is too long + eq(h.encode(), """\ + X-Very-Very-Very-Long-Header-Name: =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_eine?= + =?iso-8859-1?q?m_Foerderband_komfortabel_den_Korridor_ent?= + =?iso-8859-1?q?lang=2C_an_s=FCdl=FCndischen_Wandgem=E4lden_vorbei?= + =?iso-8859-1?q?=2C_gegen_die_rotierenden_Klingen_bef=F6rdert=2E_?=""") + *************** *** 2182,2186 **** eq(h.encode(), 'Hello World!') h.append(' Goodbye World!') ! eq(h.encode(), 'Hello World! Goodbye World!') def test_simple_surprise(self): --- 2217,2221 ---- eq(h.encode(), 'Hello World!') h.append(' Goodbye World!') ! eq(h.encode(), 'Hello World! Goodbye World!') def test_simple_surprise(self): *************** *** 2189,2193 **** eq(h.encode(), 'Hello World!') h.append('Goodbye World!') ! eq(h.encode(), 'Hello World!Goodbye World!') def test_header_needs_no_decoding(self): --- 2224,2228 ---- eq(h.encode(), 'Hello World!') h.append('Goodbye World!') ! eq(h.encode(), 'Hello World! Goodbye World!') def test_header_needs_no_decoding(self): *************** *** 2198,2202 **** h = Header("I am the very model of a modern Major-General; I've information vegetable, animal, and mineral; I know the kings of England, and I quote the fights historical from Marathon to Waterloo, in order categorical; I'm very well acquainted, too, with matters mathematical; I understand equations, both the simple and quadratical; about binomial theorem I'm teeming with a lot o' news, with many cheerful facts about the square of the hypotenuse.", maxlinelen=76) ! for l in h.encode().split('\n '): self.failUnless(len(l) <= 76) --- 2233,2237 ---- h = Header("I am the very model of a modern Major-General; I've information vegetable, animal, and mineral; I know the kings of England, and I quote the fights historical from Marathon to Waterloo, in order categorical; I'm very well acquainted, too, with matters mathematical; I understand equations, both the simple and quadratical; about binomial theorem I'm teeming with a lot o' news, with many cheerful facts about the square of the hypotenuse.", maxlinelen=76) ! for l in h.encode(splitchars=' ').split('\n '): self.failUnless(len(l) <= 76) *************** *** 2213,2231 **** h.append(utf8_head, utf8) enc = h.encode() ! eq(enc, """=?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_eine?= ! =?iso-8859-1?q?m_Foerderband_komfortabel_den_Korridor_ent?= ! =?iso-8859-1?q?lang=2C_an_s=FCdl=FCndischen_Wandgem=E4lden_vorbei?= ! =?iso-8859-1?q?=2C_gegen_die_rotierenden_Klingen_bef=F6rdert=2E_?= ! =?iso-8859-2?q?Finan=E8ni_metropole_se_hroutil?= ! =?iso-8859-2?q?y_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= ! =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv?= ! =?utf-8?b?44GV44KM44Gm44GE44G+44Gb44KT44CC5LiA?= ! =?utf-8?b?6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM?= ! =?utf-8?b?44CB44GC44Go44Gv44Gn44Gf44KJ44KB44Gn?= ! =?utf-8?b?44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBpc3QgZGE=?= ! =?utf-8?q?s_Nunstuck_git_und?= ! =?utf-8?q?_Slotermeyer=3F_Ja!_Beiherhund_das_Ode?= ! =?utf-8?q?r_die_Flipperwaldt?= ! =?utf-8?b?IGdlcnNwdXQu44CN44Go6KiA44Gj44Gm44GE44G+44GZ44CC?=""") eq(decode_header(enc), [(g_head, "iso-8859-1"), (cz_head, "iso-8859-2"), --- 2248,2263 ---- h.append(utf8_head, utf8) enc = h.encode() ! eq(enc, """\ ! =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerderband_ko?= ! =?iso-8859-1?q?mfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndischen_Wa?= ! =?iso-8859-1?q?ndgem=E4lden_vorbei=2C_gegen_die_rotierenden_Klingen_bef?= ! =?iso-8859-1?q?=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_metropole_se_hro?= ! =?iso-8859-2?q?utily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= =?utf-8?b?5q2j?= ! =?utf-8?b?56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE44G+44Gb44KT?= ! =?utf-8?b?44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB44GC44Go44Gv?= ! =?utf-8?b?44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBpc3Qg?= ! =?utf-8?q?das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das_Oder_di?= ! =?utf-8?b?ZSBGbGlwcGVyd2FsZHQgZ2Vyc3B1dC7jgI3jgajoqIDjgaPjgabjgYTjgb4=?= ! =?utf-8?b?44GZ44CC?=""") eq(decode_header(enc), [(g_head, "iso-8859-1"), (cz_head, "iso-8859-2"), *************** *** 2318,2321 **** --- 2350,2363 ---- h.append(x, errors='replace') eq(str(h), x) + + def test_encoded_adjacent_nonencoded(self): + eq = self.assertEqual + h = Header() + h.append('hello', 'iso-8859-1') + h.append('world') + s = h.encode() + eq(s, '=?iso-8859-1?q?hello?= world') + h = make_header(decode_header(s)) + eq(h.encode(), s) From bwarsaw@users.sourceforge.net Sun Mar 2 03:35:55 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sat, 01 Mar 2003 19:35:55 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email_codecs.py,1.3,1.3.8.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv9296 Modified Files: Tag: folding-reimpl-branch test_email_codecs.py Log Message: A bunch of new tests, mostly from Tokio Kikuchi's SF patch 687338. Working on the new ASCII wrapping code and Tokio's improvements. Committing on a branch until the tests all pass. :/ Index: test_email_codecs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email_codecs.py,v retrieving revision 1.3 retrieving revision 1.3.8.1 diff -C2 -d -r1.3 -r1.3.8.1 *** test_email_codecs.py 23 Jul 2002 19:03:42 -0000 1.3 --- test_email_codecs.py 2 Mar 2003 03:35:53 -0000 1.3.8.1 *************** *** 36,56 **** # test a very long header enc = h.encode() ! # BAW: The following used to pass. Sadly, the test afterwards is what ! # happens now. I've no idea which is right. Please, any Japanese and ! # RFC 2047 experts, please verify! ! ## eq(enc, '''\ ! ##=?iso-2022-jp?b?dGVzdC1qYSAbJEIkWEVqOUYkNSRsJD8lYRsoQg==?= ! ## =?iso-2022-jp?b?GyRCITwlayRPO0oycTxUJE4+NRsoQg==?= ! ## =?iso-2022-jp?b?GyRCRyckckJUJEMkRiQkJF4kORsoQg==?=''') ! eq(enc, """\ ! =?iso-2022-jp?b?dGVzdC1qYSAbJEIkWEVqOUYkNSRsJD8lYRsoQg==?= ! =?iso-2022-jp?b?GyRCITwlayRPO0oycTxUJE4+NUcnJHJCVCRDJEYkJCReJDkbKEI=?=""") ! # BAW: same deal here. :( ! ## self.assertEqual( ! ## decode_header(enc), ! ## [("test-ja \x1b$B$XEj9F$5$l$?%a\x1b(B\x1b$B!<%k$O;J2q5\x1b(B\x1b$BG'$rBT$C$F$$$^$9\x1b(B", 'iso-2022-jp')]) ! self.assertEqual( ! decode_header(enc), ! [("test-ja \x1b$B$XEj9F$5$l$?%a\x1b(B\x1b$B!<%k$O;J2q5G'$rBT$C$F$$$^$9\x1b(B", 'iso-2022-jp')]) --- 36,45 ---- # test a very long header enc = h.encode() ! # TK: splitting point may differ by codec design and/or Header encoding ! eq(enc , """\ ! =?iso-2022-jp?b?dGVzdC1qYSAbJEIkWEVqOUYkNSRsJD8lYSE8JWskTztKGyhC?= ! =?iso-2022-jp?b?GyRCMnE8VCROPjVHJyRyQlQkQyRGJCQkXiQ5GyhC?=""") ! # TK: full decode comparison ! eq(h.__unicode__().encode('euc-jp'), long) From bwarsaw@users.sourceforge.net Sun Mar 2 03:37:21 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sat, 01 Mar 2003 19:37:21 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Header.py,1.17,1.17.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv9598 Modified Files: Tag: folding-reimpl-branch Header.py Log Message: Re-implemented ASCII split algorithm. Committing on a branch until the tests all pass. :/ Index: Header.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Header.py,v retrieving revision 1.17 retrieving revision 1.17.6.1 diff -C2 -d -r1.17 -r1.17.6.1 *** Header.py 30 Dec 2002 19:13:00 -0000 1.17 --- Header.py 2 Mar 2003 03:37:19 -0000 1.17.6.1 *************** *** 26,29 **** --- 26,30 ---- CRLF = '\r\n' NL = '\n' + SPACE = ' ' SPACE8 = ' ' * 8 EMPTYSTRING = '' *************** *** 48,51 **** --- 49,59 ---- ''', re.VERBOSE | re.IGNORECASE) + pcre = re.compile('([,;])') + + # Field name regexp, including trailing colon, but not separating whitespace, + # according to RFC 2822. Character range is from tilde to exclamation mark. + # For use with .match() + fcre = re.compile(r'[\041-\176]+:$') + *************** *** 127,131 **** class Header: ! def __init__(self, s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict'): """Create a MIME-compliant header that can contain many character sets. --- 135,140 ---- class Header: ! def __init__(self, s=None, charset=None, ! maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict'): """Create a MIME-compliant header that can contain many character sets. *************** *** 254,258 **** self._chunks.append((s, charset)) ! def _split(self, s, charset, firstline=False): # Split up a header safely for use with encode_chunks. splittable = charset.to_splittable(s) --- 263,267 ---- self._chunks.append((s, charset)) ! def _split(self, s, charset, firstline, splitchars): # Split up a header safely for use with encode_chunks. splittable = charset.to_splittable(s) *************** *** 281,287 **** # although it's possible that other charsets may also benefit from the # higher-level syntactic breaks. - # elif charset == 'us-ascii': ! return self._ascii_split(s, charset, firstline) # BAW: should we use encoded? elif elen == len(s): --- 290,295 ---- # although it's possible that other charsets may also benefit from the # higher-level syntactic breaks. elif charset == 'us-ascii': ! return self._split_ascii(s, charset, firstline, splitchars) # BAW: should we use encoded? elif elen == len(s): *************** *** 297,377 **** last = charset.from_splittable(splittable[halfway:], False) # Do the split ! return self._split(first, charset, firstline) + \ ! self._split(last, charset) ! def _ascii_split(self, s, charset, firstline): ! # Attempt to split the line at the highest-level syntactic break ! # possible. Note that we don't have a lot of smarts about field ! # syntax; we just try to break on semi-colons, then whitespace. ! rtn = [] ! lines = s.splitlines() ! while lines: ! line = lines.pop(0) ! if firstline: ! maxlinelen = self._firstlinelen ! firstline = False ! else: ! #line = line.lstrip() ! maxlinelen = self._maxlinelen ! # Short lines can remain unchanged ! if len(line.replace('\t', SPACE8)) <= maxlinelen: ! rtn.append(line) ! else: ! oldlen = len(line) ! # Try to break the line on semicolons, but if that doesn't ! # work, try to split on folding whitespace. ! while len(line) > maxlinelen: ! i = line.rfind(';', 0, maxlinelen) ! if i < 0: ! break ! rtn.append(line[:i] + ';') ! line = line[i+1:] ! # Is the remaining stuff still longer than maxlinelen? ! if len(line) <= maxlinelen: ! # Splitting on semis worked ! rtn.append(line) ! continue ! # Splitting on semis didn't finish the job. If it did any ! # work at all, stick the remaining junk on the front of the ! # `lines' sequence and let the next pass do its thing. ! if len(line) <> oldlen: ! lines.insert(0, line) ! continue ! # Otherwise, splitting on semis didn't help at all. ! parts = re.split(r'(\s+)', line) ! if len(parts) == 1 or (len(parts) == 3 and ! parts[0].endswith(':')): ! # This line can't be split on whitespace. There's now ! # little we can do to get this into maxlinelen. BAW: ! # We're still potentially breaking the RFC by possibly ! # allowing lines longer than the absolute maximum of 998 ! # characters. For now, let it slide. ! # ! # len(parts) will be 1 if this line has no `Field: ' ! # prefix, otherwise it will be len(3). ! rtn.append(line) ! continue ! # There is whitespace we can split on. ! first = parts.pop(0) ! sublines = [first] ! acc = len(first) ! while parts: ! len0 = len(parts[0]) ! len1 = len(parts[1]) ! if acc + len0 + len1 <= maxlinelen: ! 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 ! if first <> '': ! rtn.append(EMPTYSTRING.join(sublines)) ! del parts[0] ! first = parts.pop(0) ! sublines = [first] ! acc = len(first) ! rtn.append(EMPTYSTRING.join(sublines)) ! return [(chunk, charset) for chunk in rtn] def _encode_chunks(self, newchunks): --- 305,321 ---- last = charset.from_splittable(splittable[halfway:], False) # Do the split ! return self._split(first, charset, firstline, splitchars) + \ ! self._split(last, charset, False, splitchars) ! def _split_ascii(self, s, charset, firstline, splitchars): ! if firstline: ! firstlen = self._firstlinelen ! restlen = self._maxlinelen ! else: ! firstlen = restlen = self._maxlinelen ! line = _split_ascii(s, firstlen, restlen, ! self._continuation_ws, splitchars) ! lines = line.splitlines() ! return zip(lines, [charset]*len(lines)) def _encode_chunks(self, newchunks): *************** *** 397,409 **** for header, charset in newchunks: if charset is None or charset.header_encoding is None: ! # There's no encoding for this chunk's charsets ! _max_append(chunks, header, self._maxlinelen) else: ! _max_append(chunks, charset.header_encode(header), ! self._maxlinelen, ' ') joiner = NL + self._continuation_ws return joiner.join(chunks) ! def encode(self): """Encode a message header into an RFC-compliant format. --- 341,352 ---- for header, charset in newchunks: if charset is None or charset.header_encoding is None: ! s = header else: ! s = charset.header_encode(header) ! _max_append(chunks, s, self._maxlinelen, ' ') joiner = NL + self._continuation_ws return joiner.join(chunks) ! def encode(self, splitchars=';, '): """Encode a message header into an RFC-compliant format. *************** *** 422,428 **** If the given charset is not known or an error occurs during conversion, this function will return the header untouched. """ newchunks = [] for s, charset in self._chunks: ! newchunks += self._split(s, charset, True) return self._encode_chunks(newchunks) --- 365,434 ---- If the given charset is not known or an error occurs during conversion, this function will return the header untouched. + + Optional splitchars is a string containing characters to split long + ASCII lines on, in rough support of RFC 2822's `highest level + syntactic breaks'. This doesn't affect RFC 2047 encoded lines. """ newchunks = [] for s, charset in self._chunks: ! newchunks += self._split(s, charset, True, splitchars) return self._encode_chunks(newchunks) + + + + def _split_ascii(s, firstlen, restlen, continuation_ws, splitchars): + lines = [] + maxlen = firstlen + for line in s.splitlines(): + if len(line) < maxlen: + lines.append(line) + maxlen = restlen + continue + # Attempt to split the line at the highest-level syntactic break + # possible. Note that we don't have a lot of smarts about field + # syntax; we just try to break on semi-colons, then commas, then + # whitespace. + for ch in splitchars: + if line.find(ch) >= 0: + break + else: + # There's nothing useful to split the line on, not even spaces, so + # just append this line unchanged + lines.append(line) + maxlen = restlen + continue + # Now split the line on the character plus trailing whitespace + cre = re.compile(r'%s\s*' % ch) + if ch in ';,': + eol = ch + else: + eol = '' + joiner = eol + ' ' + joinlen = len(joiner) + wslen = len(continuation_ws.replace('\t', SPACE8)) + this = [] + linelen = 0 + for part in cre.split(line): + curlen = linelen + max(0, len(this)-1) * joinlen + partlen = len(part) + onfirstline = not lines + # We don't want to split after the field name, if we're on the + # first line and the field name is present in the header string. + if ch == ' ' and onfirstline and \ + len(this) == 1 and fcre.match(this[0]): + this.append(part) + linelen += partlen + elif curlen + partlen > maxlen: + if this: + lines.append(joiner.join(this) + eol) + this = [part] + linelen = wslen + partlen + maxlen = restlen + else: + this.append(part) + linelen += partlen + # Put any left over parts on a line by themselves + if this: + lines.append(joiner.join(this)) + linejoiner = '\n' + continuation_ws + return linejoiner.join(lines) From tim_one@users.sourceforge.net Sun Mar 2 04:54:26 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Sat, 01 Mar 2003 20:54:26 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.53,1.54 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv25054/Lib/test Modified Files: pickletester.py Log Message: test_load_from_canned_string(): Created a DATA2 string to test a canned proto 2 pickle too. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -d -r1.53 -r1.54 *** pickletester.py 18 Feb 2003 22:41:24 -0000 1.53 --- pickletester.py 2 Mar 2003 04:54:24 -0000 1.54 *************** *** 89,93 **** # DATA0 .. DATA2 are the pickles we expect under the various protocols, for # the object returned by create_data(). - # XXX DATA2 doesn't exist yet, as it's not fully implemented in cPickle. # break into multiple strings to avoid confusing font-lock-mode --- 89,92 ---- *************** *** 277,280 **** --- 276,344 ---- """ + DATA2 = ('\x80\x02]q\x01(K\x00\x8a\x01\x01G@\x00\x00\x00\x00\x00\x00\x00' + 'c__builtin__\ncomplex\nq\x02G@\x08\x00\x00\x00\x00\x00\x00G\x00' + '\x00\x00\x00\x00\x00\x00\x00\x86Rq\x03K\x01J\xff\xff\xff\xffK' + '\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xff' + 'J\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00' + '\x80(U\x03abcq\x04h\x04(c__main__\nC\nq\x05oq\x06}q\x07(U\x03foo' + 'q\x08K\x01U\x03barq\tK\x02ubh\x06tq\nh\nK\x05e.') + + # Disassembly of DATA2. + DATA2_DIS = """\ + 0: \x80 PROTO 2 + 2: ] EMPTY_LIST + 3: q BINPUT 1 + 5: ( MARK + 6: K BININT1 0 + 8: \x8a LONG1 1L + 11: G BINFLOAT 2.0 + 20: c GLOBAL '__builtin__ complex' + 41: q BINPUT 2 + 43: G BINFLOAT 3.0 + 52: G BINFLOAT 0.0 + 61: \x86 TUPLE2 + 62: R REDUCE + 63: q BINPUT 3 + 65: K BININT1 1 + 67: J BININT -1 + 72: K BININT1 255 + 74: J BININT -255 + 79: J BININT -256 + 84: M BININT2 65535 + 87: J BININT -65535 + 92: J BININT -65536 + 97: J BININT 2147483647 + 102: J BININT -2147483647 + 107: J BININT -2147483648 + 112: ( MARK + 113: U SHORT_BINSTRING 'abc' + 118: q BINPUT 4 + 120: h BINGET 4 + 122: ( MARK + 123: c GLOBAL '__main__ C' + 135: q BINPUT 5 + 137: o OBJ (MARK at 122) + 138: q BINPUT 6 + 140: } EMPTY_DICT + 141: q BINPUT 7 + 143: ( MARK + 144: U SHORT_BINSTRING 'foo' + 149: q BINPUT 8 + 151: K BININT1 1 + 153: U SHORT_BINSTRING 'bar' + 158: q BINPUT 9 + 160: K BININT1 2 + 162: u SETITEMS (MARK at 143) + 163: b BUILD + 164: h BINGET 6 + 166: t TUPLE (MARK at 112) + 167: q BINPUT 10 + 169: h BINGET 10 + 171: K BININT1 5 + 173: e APPENDS (MARK at 5) + 174: . STOP + highest protocol among opcodes = 2 + """ + def create_data(): c = C() *************** *** 334,338 **** def test_load_from_canned_string(self): expected = self._testdata ! for canned in DATA0, DATA1: got = self.loads(canned) self.assertEqual(expected, got) --- 398,402 ---- def test_load_from_canned_string(self): expected = self._testdata ! for canned in DATA0, DATA1, DATA2: got = self.loads(canned) self.assertEqual(expected, got) From bwarsaw@users.sourceforge.net Sun Mar 2 05:32:41 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sat, 01 Mar 2003 21:32:41 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Header.py,1.17.6.1,1.17.6.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv1551 Modified Files: Tag: folding-reimpl-branch Header.py Log Message: Experimental binary search for a better split point. Index: Header.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Header.py,v retrieving revision 1.17.6.1 retrieving revision 1.17.6.2 diff -C2 -d -r1.17.6.1 -r1.17.6.2 *** Header.py 2 Mar 2003 03:37:19 -0000 1.17.6.1 --- Header.py 2 Mar 2003 05:32:38 -0000 1.17.6.2 *************** *** 266,273 **** # Split up a header safely for use with encode_chunks. splittable = charset.to_splittable(s) ! encoded = charset.from_splittable(splittable) elen = charset.encoded_header_len(encoded) ! ! if elen <= self._maxlinelen: return [(encoded, charset)] # If we have undetermined raw 8bit characters sitting in a byte --- 266,279 ---- # Split up a header safely for use with encode_chunks. splittable = charset.to_splittable(s) ! encoded = charset.from_splittable(splittable, True) elen = charset.encoded_header_len(encoded) ! # The maxlinelen depends on whether we're on the first line or not, to ! # take account of any header field name. ! if firstline: ! maxlinelen = self._firstlinelen ! else: ! maxlinelen = self._maxlinelen ! # If the line's encoded length first, just return it ! if elen <= maxlinelen: return [(encoded, charset)] # If we have undetermined raw 8bit characters sitting in a byte *************** *** 277,281 **** # be to not split the header at all, but that means they could go out # longer than maxlinelen. ! elif charset == '8bit': return [(s, charset)] # BAW: I'm not sure what the right test here is. What we're trying to --- 283,287 ---- # be to not split the header at all, but that means they could go out # longer than maxlinelen. ! if charset == '8bit': return [(s, charset)] # BAW: I'm not sure what the right test here is. What we're trying to *************** *** 296,307 **** # We can split on _maxlinelen boundaries because we know that the # encoding won't change the size of the string ! splitpnt = self._maxlinelen first = charset.from_splittable(splittable[:splitpnt], False) last = charset.from_splittable(splittable[splitpnt:], False) else: # Divide and conquer. ! halfway = _floordiv(len(splittable), 2) ! first = charset.from_splittable(splittable[:halfway], False) ! last = charset.from_splittable(splittable[halfway:], False) # Do the split return self._split(first, charset, firstline, splitchars) + \ --- 302,315 ---- # We can split on _maxlinelen boundaries because we know that the # encoding won't change the size of the string ! splitpnt = maxlinelen first = charset.from_splittable(splittable[:splitpnt], False) last = charset.from_splittable(splittable[splitpnt:], False) else: + # Binary search for split point + first, last = _binsplit(splittable, charset, maxlinelen) # Divide and conquer. ! ## halfway = _floordiv(len(splittable), 2) ! ## first = charset.from_splittable(splittable[:halfway], False) ! ## last = charset.from_splittable(splittable[halfway:], False) # Do the split return self._split(first, charset, firstline, splitchars) + \ *************** *** 433,434 **** --- 441,464 ---- linejoiner = '\n' + continuation_ws return linejoiner.join(lines) + + + + def _binsplit(splittable, charset, maxlinelen): + i = lastm = 0 + j = len(splittable) - 1 + while True: + if j < i: + break + m = (i + j) / 2 + chunk = charset.from_splittable(splittable[:m], True) + chunklen = charset.encoded_header_len(chunk) + if chunklen < maxlinelen: + lastm = m + i = m + 1 + elif chunklen > maxlinelen: + j = m - 1 + else: + break + first = charset.from_splittable(splittable[:lastm], False) + last = charset.from_splittable(splittable[lastm:], False) + return first, last From gvanrossum@users.sourceforge.net Sun Mar 2 13:17:22 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Sun, 02 Mar 2003 05:17:22 -0800 Subject: [Python-checkins] python/dist/src/Doc/api init.tex,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1:/tmp/cvs-serv11849 Modified Files: init.tex Log Message: Commit MvL's doc patch for SF bug #221327. This adds an example of calling into Python from a C thread. Index: init.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/init.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** init.tex 10 Feb 2003 19:12:42 -0000 1.6 --- init.tex 2 Mar 2003 13:17:20 -0000 1.7 *************** *** 467,470 **** --- 467,492 ---- thread after Python is initialized). + Assuming you have access to an interpreter object, the typical idiom + for calling into Python from a C thread is + + \begin{verbatim} + PyThreadState *tstate; + PyObject *result; + + /* interp is your reference to an interpreter object. */ + tstate = PyThreadState_New(interp); + PyEval_AcquireThread(tstate); + + /* Perform Python actions here. */ + result = CallSomeFunction(); + /* evaluate result */ + + /* Release the thread. No Python API allowed beyond this point. */ + PyEval_ReleaseThread(tstate); + + /* You can either delete the thread state, or save it + until you need it the next time. */ + PyThreadState_Delete(tstate); + \end{verbatim} \begin{ctypedesc}{PyInterpreterState} From gvanrossum@users.sourceforge.net Sun Mar 2 13:51:49 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Sun, 02 Mar 2003 05:51:49 -0800 Subject: [Python-checkins] python/dist/src/Objects complexobject.c,2.65,2.66 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv21390 Modified Files: complexobject.c Log Message: Fix from Greg Chapman from SF bug #695651: a complex subclass constructor, when passed a single complex argument, returns the argument unchanged. This should be done only for the complex base class; a complex subclass should of course cast the value to the subclass in this case. The fix also revealed a segfault in complex_getnewargs(): the argument for the Py_BuildValue() format code "D" is the *address* of a Py_complex struct, not the value. (This corroborated by the API documentation.) I expect this needs to be backported to 2.2.3. Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.65 retrieving revision 2.66 diff -C2 -d -r2.65 -r2.66 *** complexobject.c 29 Jan 2003 17:58:44 -0000 2.65 --- complexobject.c 2 Mar 2003 13:51:47 -0000 2.66 *************** *** 643,647 **** complex_getnewargs(PyComplexObject *v) { ! return Py_BuildValue("(D)", v->cval); } --- 643,647 ---- complex_getnewargs(PyComplexObject *v) { ! return Py_BuildValue("(D)", &v->cval); } *************** *** 833,837 **** /* Special-case for single argumet that is already complex */ ! if (PyComplex_CheckExact(r) && i == NULL) { /* Note that we can't know whether it's safe to return a complex *subclass* instance as-is, hence the restriction --- 833,838 ---- /* Special-case for single argumet that is already complex */ ! if (PyComplex_CheckExact(r) && i == NULL && ! type == &PyComplex_Type) { /* Note that we can't know whether it's safe to return a complex *subclass* instance as-is, hence the restriction From gvanrossum@users.sourceforge.net Sun Mar 2 13:53:20 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Sun, 02 Mar 2003 05:53:20 -0800 Subject: [Python-checkins] python/dist/src/Lib/test pickletester.py,1.54,1.55 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv21813a Modified Files: pickletester.py Log Message: MyComplex now works. Index: pickletester.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/pickletester.py,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -d -r1.54 -r1.55 *** pickletester.py 2 Mar 2003 04:54:24 -0000 1.54 --- pickletester.py 2 Mar 2003 13:53:18 -0000 1.55 *************** *** 885,889 **** myclasses = [MyInt, MyLong, MyFloat, ! # MyComplex, # XXX complex somehow doesn't work here :-( MyStr, MyUnicode, MyTuple, MyList, MyDict] --- 885,889 ---- myclasses = [MyInt, MyLong, MyFloat, ! MyComplex, MyStr, MyUnicode, MyTuple, MyList, MyDict] From guido@python.org Sun Mar 2 14:11:50 2003 From: guido@python.org (Guido van Rossum) Date: Sun, 02 Mar 2003 09:11:50 -0500 Subject: [Python-checkins] python/dist/src/Objects complexobject.c,2.65,2.66 In-Reply-To: "Your message of Sun, 02 Mar 2003 05:51:49 PST." References: Message-ID: <200303021411.h22EBoA18584@pcp02138704pcs.reston01.va.comcast.net> > I expect this needs to be backported to 2.2.3. I take that back. The 2.2 complex_new() looks vey different, and __getnewargs__ didn't exist then. --Guido van Rossum (home page: http://www.python.org/~guido/) From tim.one@comcast.net Sun Mar 2 19:00:58 2003 From: tim.one@comcast.net (Tim Peters) Date: Sun, 02 Mar 2003 14:00:58 -0500 Subject: [Python-checkins] python/dist/src/Lib/email Header.py,1.17.6.1,1.17.6.2 In-Reply-To: Message-ID: > Modified Files: > Tag: folding-reimpl-branch > Header.py > Log Message: > Experimental binary search for a better split point. ... > + def _binsplit(splittable, charset, maxlinelen): > + i = lastm = 0 > + j = len(splittable) - 1 > + while True: > + if j < i: > + break > + m = (i + j) / 2 > + chunk = charset.from_splittable(splittable[:m], True) > + chunklen = charset.encoded_header_len(chunk) > + if chunklen < maxlinelen: > + lastm = m > + i = m + 1 > + elif chunklen > maxlinelen: > + j = m - 1 > + else: > + break > + first = charset.from_splittable(splittable[:lastm], False) > + last = charset.from_splittable(splittable[lastm:], False) > + return first, last I'm not entirely sure what this is doing, but if I grok it I trust this version more : def _binsplit(splittable, charset, maxlinelen): i, j = 0, len(splittable) while i < j: # Invariants: # 1. splittable[:k] fits for all k <= i (note that we *assume*, # at the start, that splittable[:0] fits). # 2. splittable[:k] does not fit for any k > j (at the start, # this means we shouldn't look at any k > len(splittable)). # 3. We don't know about splittable[:k] for k in i+1..j. # 4. We want to set i to the largest k that fits, with i <= k <= j. m = (i+j+1) >> 1 # ceiling((i+j)/2); i < m <= j chunk = charset.from_splittable(splittable[:m], True) chunklen = charset.encoded_header_len(chunk) if chunklen <= maxlinelen: # m is acceptable, so is a new lower bound. i = m else: # m is not acceptable, so final i must be < j. j = m-1 # i == j. Invariant #1 implies that splittable[:i] fits, and # invariant #2 implies that splittable[:i+1] does not fit, so i # is what we're looking for. first = charset.from_splittable(splittable[:i], False) last = charset.from_splittable(splittable[i:], False) return first, last You could break out early when chunklen == maxlinelen, but it's not necessary and *usually* slows binary searches. From gvanrossum@users.sourceforge.net Sun Mar 2 20:47:35 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Sun, 02 Mar 2003 12:47:35 -0800 Subject: [Python-checkins] python/dist/src/Lib/logging __init__.py,1.7,1.8 config.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/logging In directory sc8-pr-cvs1:/tmp/cvs-serv15153 Modified Files: __init__.py config.py Log Message: Undo the apply() removals; this code needs to run under Python 1.5.2. Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/logging/__init__.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** __init__.py 27 Feb 2003 20:14:47 -0000 1.7 --- __init__.py 2 Mar 2003 20:47:28 -0000 1.8 *************** *** 875,879 **** return if DEBUG >= self.getEffectiveLevel(): ! self._log(DEBUG, msg, args, **kwargs) def info(self, msg, *args, **kwargs): --- 875,879 ---- return if DEBUG >= self.getEffectiveLevel(): ! apply(self._log, (DEBUG, msg, args), kwargs) def info(self, msg, *args, **kwargs): *************** *** 889,893 **** return if INFO >= self.getEffectiveLevel(): ! self._log(INFO, msg, args, **kwargs) def warning(self, msg, *args, **kwargs): --- 889,893 ---- return if INFO >= self.getEffectiveLevel(): ! apply(self._log, (INFO, msg, args), kwargs) def warning(self, msg, *args, **kwargs): *************** *** 903,907 **** return if self.isEnabledFor(WARNING): ! self._log(WARNING, msg, args, **kwargs) warn = warning --- 903,907 ---- return if self.isEnabledFor(WARNING): ! apply(self._log, (WARNING, msg, args), kwargs) warn = warning *************** *** 919,923 **** return if self.isEnabledFor(ERROR): ! self._log(ERROR, msg, args, **kwargs) def exception(self, msg, *args): --- 919,923 ---- return if self.isEnabledFor(ERROR): ! apply(self._log, (ERROR, msg, args), kwargs) def exception(self, msg, *args): *************** *** 925,929 **** Convenience method for logging an ERROR with exception information. """ ! self.error(msg, exc_info=1, *args) def critical(self, msg, *args, **kwargs): --- 925,929 ---- Convenience method for logging an ERROR with exception information. """ ! apply(self.error, (msg,) + args, {'exc_info': 1}) def critical(self, msg, *args, **kwargs): *************** *** 939,943 **** return if CRITICAL >= self.getEffectiveLevel(): ! self._log(CRITICAL, msg, args, **kwargs) fatal = critical --- 939,943 ---- return if CRITICAL >= self.getEffectiveLevel(): ! apply(self._log, (CRITICAL, msg, args), kwargs) fatal = critical *************** *** 955,959 **** return if self.isEnabledFor(level): ! self._log(level, msg, args, **kwargs) def findCaller(self): --- 955,959 ---- return if self.isEnabledFor(level): ! apply(self._log, (level, msg, args), kwargs) def findCaller(self): *************** *** 1132,1136 **** if len(root.handlers) == 0: basicConfig() ! root.critical(msg, *args, **kwargs) fatal = critical --- 1132,1136 ---- if len(root.handlers) == 0: basicConfig() ! apply(root.critical, (msg,)+args, kwargs) fatal = critical *************** *** 1142,1146 **** if len(root.handlers) == 0: basicConfig() ! root.error(msg, *args, **kwargs) def exception(msg, *args): --- 1142,1146 ---- if len(root.handlers) == 0: basicConfig() ! apply(root.error, (msg,)+args, kwargs) def exception(msg, *args): *************** *** 1149,1153 **** with exception information. """ ! error(msg, exc_info=1, *args) def warning(msg, *args, **kwargs): --- 1149,1153 ---- with exception information. """ ! apply(error, (msg,)+args, {'exc_info': 1}) def warning(msg, *args, **kwargs): *************** *** 1157,1161 **** if len(root.handlers) == 0: basicConfig() ! root.warning(msg, *args, **kwargs) warn = warning --- 1157,1161 ---- if len(root.handlers) == 0: basicConfig() ! apply(root.warning, (msg,)+args, kwargs) warn = warning *************** *** 1167,1171 **** if len(root.handlers) == 0: basicConfig() ! root.info(msg, *args, **kwargs) def debug(msg, *args, **kwargs): --- 1167,1171 ---- if len(root.handlers) == 0: basicConfig() ! apply(root.info, (msg,)+args, kwargs) def debug(msg, *args, **kwargs): *************** *** 1175,1179 **** if len(root.handlers) == 0: basicConfig() ! root.debug(msg, *args, **kwargs) def disable(level): --- 1175,1179 ---- if len(root.handlers) == 0: basicConfig() ! apply(root.debug, (msg,)+args, kwargs) def disable(level): Index: config.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/logging/config.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** config.py 27 Feb 2003 20:14:48 -0000 1.6 --- config.py 2 Mar 2003 20:47:29 -0000 1.7 *************** *** 103,107 **** args = cp.get(sectname, "args") args = eval(args, vars(logging)) ! h = klass(*args) if "level" in opts: level = cp.get(sectname, "level") --- 103,107 ---- args = cp.get(sectname, "args") args = eval(args, vars(logging)) ! h = apply(klass, args) if "level" in opts: level = cp.get(sectname, "level") From jackjansen@users.sourceforge.net Sun Mar 2 21:31:55 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 02 Mar 2003 13:31:55 -0800 Subject: [Python-checkins] python/dist/src setup.py,1.153,1.154 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv31568 Modified Files: setup.py Log Message: _CG module only needs the ApplicationServices framework, not Carbon. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.153 retrieving revision 1.154 diff -C2 -d -r1.153 -r1.154 *** setup.py 28 Feb 2003 17:39:42 -0000 1.153 --- setup.py 2 Mar 2003 21:31:51 -0000 1.154 *************** *** 777,782 **** extra_link_args=['-framework', 'Carbon']) ) exts.append( Extension('_CG', ['cg/_CGmodule.c'], ! extra_link_args=['-framework', 'ApplicationServices', ! '-framework', 'Carbon']) ) exts.append( Extension('_Cm', ['cm/_Cmmodule.c'], extra_link_args=['-framework', 'Carbon']) ) --- 777,781 ---- extra_link_args=['-framework', 'Carbon']) ) exts.append( Extension('_CG', ['cg/_CGmodule.c'], ! extra_link_args=['-framework', 'ApplicationServices']) ) exts.append( Extension('_Cm', ['cm/_Cmmodule.c'], extra_link_args=['-framework', 'Carbon']) ) From jackjansen@users.sourceforge.net Sun Mar 2 23:16:52 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 02 Mar 2003 15:16:52 -0800 Subject: [Python-checkins] python/dist/src/Python mactoolboxglue.c,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv6543 Modified Files: mactoolboxglue.c Log Message: Use Carbon.File for FSSpec and FSRef conversion, not macfs. Index: mactoolboxglue.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/mactoolboxglue.c,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** mactoolboxglue.c 17 Jan 2003 23:11:17 -0000 1.16 --- mactoolboxglue.c 2 Mar 2003 23:16:50 -0000 1.17 *************** *** 529,536 **** } ! GLUE_NEW(FSSpec *, PyMac_BuildFSSpec, "macfs") ! GLUE_CONVERT(FSSpec, PyMac_GetFSSpec, "macfs") ! GLUE_NEW(FSRef *, PyMac_BuildFSRef, "macfs") ! GLUE_CONVERT(FSRef, PyMac_GetFSRef, "macfs") GLUE_NEW(AppleEvent *, AEDesc_New, "Carbon.AE") /* XXXX Why by address? */ --- 529,536 ---- } ! GLUE_NEW(FSSpec *, PyMac_BuildFSSpec, "Carbon.File") ! GLUE_CONVERT(FSSpec, PyMac_GetFSSpec, "Carbon.File") ! GLUE_NEW(FSRef *, PyMac_BuildFSRef, "Carbon.File") ! GLUE_CONVERT(FSRef, PyMac_GetFSRef, "Carbon.File") GLUE_NEW(AppleEvent *, AEDesc_New, "Carbon.AE") /* XXXX Why by address? */ From klm@users.sourceforge.net Mon Mar 3 00:35:35 2003 From: klm@users.sourceforge.net (klm@users.sourceforge.net) Date: Sun, 02 Mar 2003 16:35:35 -0800 Subject: [Python-checkins] python/dist/src/Misc python-mode.el,4.29,4.30 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv650 Modified Files: python-mode.el Log Message: Enhanced pdbtrack to provide for source code that's not findable by the reported path. (Eg, precompiled scripts with a file path suitable for a different host, scripts actually running on a remote system or with no valid path, like Zope through-the-web python scripts.) On failing to find the code on the reported path, pdbtrack takes the function name and looks through the buffers, from most to least recent, seeking the first python-mode buffer that either is named for the function or has a definition (def or class) for that function. So to get source tracking for code that's not located where the path indicates, you put a copy of the script in a buffer, and pdbtrack will find it. Also, fixed a small bug so pdbtrack now properly presents the overlay arrow when you run the pdb 'w'here command. Index: python-mode.el =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/python-mode.el,v retrieving revision 4.29 retrieving revision 4.30 diff -C2 -d -r4.29 -r4.30 *** python-mode.el 31 Dec 2002 16:56:20 -0000 4.29 --- python-mode.el 3 Mar 2003 00:35:32 -0000 4.30 *************** *** 473,477 **** ;; pdbtrack contants (defconst py-pdbtrack-stack-entry-regexp ! "> \\([^(]+\\)(\\([0-9]+\\))[?a-zA-Z0-9_]+()" "Regular expression pdbtrack uses to find a stack trace entry.") --- 473,478 ---- ;; pdbtrack contants (defconst py-pdbtrack-stack-entry-regexp ! ; "^> \\([^(]+\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_]+\\)()" ! "^> \\(.*\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_]+\\)()" "Regular expression pdbtrack uses to find a stack trace entry.") *************** *** 1277,1281 **** We depend on the pdb input prompt matching `py-pdbtrack-input-prompt' ! at the beginning of the line." ;; Instead of trying to piece things together from partial text ;; (which can be almost useless depending on Emacs version), we --- 1278,1289 ---- We depend on the pdb input prompt matching `py-pdbtrack-input-prompt' ! at the beginning of the line. ! ! If the traceback target file path is invalid, we look for the most ! recently visited python-mode buffer which either has the name of the ! current function \(or class) or which defines the function \(or ! class). This is to provide for remote scripts, eg, Zope's 'Script ! (Python)' - put a _copy_ of the script in a python-mode buffer named ! for the script and pdbtrack will find it.)" ;; Instead of trying to piece things together from partial text ;; (which can be almost useless depending on Emacs version), we *************** *** 1283,1323 **** ;; check all text from comint-last-input-end to process-mark. ;; ! ;; KLM: It might be nice to provide an optional override, so this ! ;; routine could be fed debugger output strings as the text ! ;; argument, for deliberate application elsewhere. ! ;; ! ;; KLM: We're very conservative about clearing the overlay arrow, to ! ;; minimize residue. This means, for instance, that executing other ! ;; pdb commands wipes out the highlight. (let* ((origbuf (current-buffer)) (currproc (get-buffer-process origbuf))) (if (not (and currproc py-pdbtrack-do-tracking-p)) (py-pdbtrack-overlay-arrow nil) ! (let* (;(origdir default-directory) ! (procmark (process-mark currproc)) (block (buffer-substring (max comint-last-input-end (- procmark py-pdbtrack-track-range)) procmark)) ! fname lineno) (if (not (string-match (concat py-pdbtrack-input-prompt "$") block)) (py-pdbtrack-overlay-arrow nil) ! (if (not (string-match ! (concat ".*" py-pdbtrack-stack-entry-regexp ".*") ! block)) ! (py-pdbtrack-overlay-arrow nil) ! (setq fname (match-string 1 block) ! lineno (match-string 2 block)) ! (if (file-exists-p fname) ! (progn ! (find-file-other-window fname) ! (goto-line (string-to-int lineno)) ! (message "pdbtrack: line %s, file %s" lineno fname) ! (py-pdbtrack-overlay-arrow t) ! (pop-to-buffer origbuf t) ) ! (if (= (elt fname 0) ?\<) ! (message "pdbtrack: (Non-file source: '%s')" fname) ! (message "pdbtrack: File not found: %s" fname)) ! ))))))) (defun py-postprocess-output-buffer (buf) --- 1291,1399 ---- ;; check all text from comint-last-input-end to process-mark. ;; ! ;; Also, we're very conservative about clearing the overlay arrow, ! ;; to minimize residue. This means, for instance, that executing ! ;; other pdb commands wipe out the highlight. You can always do a ! ;; 'where' (aka 'w') command to reveal the overlay arrow. (let* ((origbuf (current-buffer)) (currproc (get-buffer-process origbuf))) + (if (not (and currproc py-pdbtrack-do-tracking-p)) (py-pdbtrack-overlay-arrow nil) ! ! (let* ((procmark (process-mark currproc)) (block (buffer-substring (max comint-last-input-end (- procmark py-pdbtrack-track-range)) procmark)) ! target target_fname target_lineno) ! (if (not (string-match (concat py-pdbtrack-input-prompt "$") block)) (py-pdbtrack-overlay-arrow nil) ! ! (setq target (py-pdbtrack-get-source-buffer block)) ! ! (if (stringp target) ! (message "pdbtrack: %s" target) ! ! (setq target_lineno (car target)) ! (setq target_buffer (cadr target)) ! (setq target_fname (buffer-file-name target_buffer)) ! (switch-to-buffer-other-window target_buffer) ! (goto-line target_lineno) ! (message "pdbtrack: line %s, file %s" target_lineno target_fname) ! (py-pdbtrack-overlay-arrow t) ! (pop-to-buffer origbuf t) ! ! ))))) ! ) ! ! (defun py-pdbtrack-get-source-buffer (block) ! "Return line number and buffer of code indicated by block's traceback text. ! ! We look first to visit the file indicated in the trace. ! ! Failing that, we look for the most recently visited python-mode buffer ! with the same name or having ! having the named function. ! ! If we're unable find the source code we return a string describing the ! problem as best as we can determine." ! ! (if (not (string-match py-pdbtrack-stack-entry-regexp block)) ! ! "Traceback cue not found" ! ! (let* ((filename (match-string 1 block)) ! (lineno (string-to-int (match-string 2 block))) ! (funcname (match-string 3 block)) ! funcbuffer) ! ! (cond ((file-exists-p filename) ! (list lineno (find-file-noselect filename))) ! ! ((setq funcbuffer (py-pdbtrack-grub-for-buffer funcname lineno)) ! (if (string-match "/Script (Python)$" filename) ! ;; Add in number of lines for leading '##' comments: ! (setq lineno ! (+ lineno ! (save-excursion ! (set-buffer funcbuffer) ! (count-lines ! (point-min) ! (string-match "^\\([^#]\\|#[^#]\\|#$\\)" ! (buffer-substring (point-min) ! (point-max) ! funcbuffer))))))) ! (list lineno funcbuffer)) ! ! ((= (elt filename 0) ?\<) ! (format "(Non-file source: '%s')" filename)) ! ! (t (format "Function/file not found: %s(), %s" funcname filename))) ! ) ! ) ! ) ! ! (defun py-pdbtrack-grub-for-buffer (funcname lineno) ! "Find most recent buffer itself named or having function funcname. ! ! Must have a least int(lineno) lines in it." ! (let ((buffers (buffer-list)) ! ;(buffers (list (get-buffer "workflow_do_action.py"))) ! curbuf ! got) ! (while (and buffers (not got)) ! (setq buf (car buffers) ! buffers (cdr buffers)) ! (if (or (save-excursion (set-buffer buf) ! (string= major-mode "python-mode")) ! (and (string-match funcname (buffer-name buf)) ! (string-match (concat "^\\s-*\\(def\\|class\\)\\s-+" ! funcname "\\s-*(") ! (buffer-substring (point-min buf) ! (point-max buf) ! buf)))) ! (setq got buf))) ! got)) (defun py-postprocess-output-buffer (buf) From klm@users.sourceforge.net Mon Mar 3 04:05:09 2003 From: klm@users.sourceforge.net (klm@users.sourceforge.net) Date: Sun, 02 Mar 2003 20:05:09 -0800 Subject: [Python-checkins] python/dist/src/Misc python-mode.el,4.30,4.31 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv26759 Modified Files: python-mode.el Log Message: Guard advancing past leading meta-comments. Index: python-mode.el =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/python-mode.el,v retrieving revision 4.30 retrieving revision 4.31 diff -C2 -d -r4.30 -r4.31 *** python-mode.el 3 Mar 2003 00:35:32 -0000 4.30 --- python-mode.el 3 Mar 2003 04:05:03 -0000 4.31 *************** *** 1361,1368 **** (count-lines (point-min) ! (string-match "^\\([^#]\\|#[^#]\\|#$\\)" ! (buffer-substring (point-min) ! (point-max) ! funcbuffer))))))) (list lineno funcbuffer)) --- 1361,1370 ---- (count-lines (point-min) ! (max (point-min) ! (string-match "^\\([^#]\\|#[^#]\\|#$\\)" ! (buffer-substring (point-min) ! (point-max) ! funcbuffer)) ! )))))) (list lineno funcbuffer)) From bwarsaw@users.sourceforge.net Mon Mar 3 06:41:58 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sun, 02 Mar 2003 22:41:58 -0800 Subject: [Python-checkins] python/dist/src/Lib/email base64MIME.py,1.5,1.5.8.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv2091 Modified Files: Tag: folding-reimpl-branch base64MIME.py Log Message: Remove an outdated comment. Index: base64MIME.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/base64MIME.py,v retrieving revision 1.5 retrieving revision 1.5.8.1 diff -C2 -d -r1.5 -r1.5.8.1 *** base64MIME.py 28 Sep 2002 20:59:12 -0000 1.5 --- base64MIME.py 3 Mar 2003 06:41:55 -0000 1.5.8.1 *************** *** 103,109 **** max_unencoded = _floordiv(max_encoded * 3, 4) - # BAW: Ben's original code used a step of max_unencoded, but I think it - # ought to be max_encoded. Otherwise, where's max_encoded used? I'm - # still not sure what the for i in range(0, len(header), max_unencoded): base64ed.append(b2a_base64(header[i:i+max_unencoded])) --- 103,106 ---- From bwarsaw@users.sourceforge.net Mon Mar 3 06:51:29 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sun, 02 Mar 2003 22:51:29 -0800 Subject: [Python-checkins] python/dist/src/Lib/email quopriMIME.py,1.4,1.4.8.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv4379 Modified Files: Tag: folding-reimpl-branch quopriMIME.py Log Message: _max_append(): Comparison should allow for concatenation if the resulting length is equal to the max length. header_encode(): Allow for maxlinelen=None to mean no splitting of long lines. Higher level functions such as Header.encode() know what the chunk lengths should be so they don't want header_encode() second guessing them (there isn't a convenient way to thread the maxlinelen and continuation_ws all the way through). Index: quopriMIME.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/quopriMIME.py,v retrieving revision 1.4 retrieving revision 1.4.8.1 diff -C2 -d -r1.4 -r1.4.8.1 *** quopriMIME.py 28 Sep 2002 21:02:51 -0000 1.4 --- quopriMIME.py 3 Mar 2003 06:51:27 -0000 1.4.8.1 *************** *** 83,87 **** if not L: L.append(s.lstrip()) ! elif len(L[-1]) + len(s) < maxlen: L[-1] += extra + s else: --- 83,87 ---- if not L: L.append(s.lstrip()) ! elif len(L[-1]) + len(s) <= maxlen: L[-1] += extra + s else: *************** *** 117,121 **** with each line wrapped safely at, at most, maxlinelen characters (defaults ! to 76 characters). End-of-line characters (\\r, \\n, \\r\\n) will be automatically converted --- 117,122 ---- with each line wrapped safely at, at most, maxlinelen characters (defaults ! to 76 characters). If maxlinelen is None, the entire string is encoded in ! one chunk with no splitting. End-of-line characters (\\r, \\n, \\r\\n) will be automatically converted *************** *** 135,141 **** # Quopri encode each line, in encoded chunks no greater than maxlinelen in ! # lenght, after the RFC chrome is added in. quoted = [] ! max_encoded = maxlinelen - len(charset) - MISC_LEN for c in header: --- 136,146 ---- # Quopri encode each line, in encoded chunks no greater than maxlinelen in ! # length, after the RFC chrome is added in. quoted = [] ! if maxlinelen is None: ! # An obnoxiously large number that's good enough ! max_encoded = 100000 ! else: ! max_encoded = maxlinelen - len(charset) - MISC_LEN - 1 for c in header: From bwarsaw@users.sourceforge.net Mon Mar 3 06:55:36 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sun, 02 Mar 2003 22:55:36 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Charset.py,1.12,1.12.4.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv5405 Modified Files: Tag: folding-reimpl-branch Charset.py Log Message: __repr__: Added header_encode(): When calling quopriMIME.header_encode(), pass in maxlinelen=None since we've already split the line into properly sized chunks. Index: Charset.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Charset.py,v retrieving revision 1.12 retrieving revision 1.12.4.1 diff -C2 -d -r1.12 -r1.12.4.1 *** Charset.py 7 Jan 2003 00:29:07 -0000 1.12 --- Charset.py 3 Mar 2003 06:55:34 -0000 1.12.4.1 *************** *** 235,238 **** --- 235,240 ---- return self.input_charset.lower() + __repr__ = __str__ + def __eq__(self, other): return str(self) == str(other).lower() *************** *** 359,363 **** return email.base64MIME.header_encode(s, cset) elif self.header_encoding == QP: ! return email.quopriMIME.header_encode(s, cset) elif self.header_encoding == SHORTEST: lenb64 = email.base64MIME.base64_len(s) --- 361,365 ---- return email.base64MIME.header_encode(s, cset) elif self.header_encoding == QP: ! return email.quopriMIME.header_encode(s, cset, maxlinelen=None) elif self.header_encoding == SHORTEST: lenb64 = email.base64MIME.base64_len(s) *************** *** 366,370 **** return email.base64MIME.header_encode(s, cset) else: ! return email.quopriMIME.header_encode(s, cset) else: return s --- 368,372 ---- return email.base64MIME.header_encode(s, cset) else: ! return email.quopriMIME.header_encode(s, cset, maxlinelen=None) else: return s From bwarsaw@users.sourceforge.net Mon Mar 3 06:59:16 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sun, 02 Mar 2003 22:59:16 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Header.py,1.17.6.2,1.17.6.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv6405 Modified Files: Tag: folding-reimpl-branch Header.py Log Message: Internal changes to improve the packing of encoded headers. This makes sure that different charsets can appear on the same line. Uncle Timmie gives us a better binary split implementation. Index: Header.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Header.py,v retrieving revision 1.17.6.2 retrieving revision 1.17.6.3 diff -C2 -d -r1.17.6.2 -r1.17.6.3 *** Header.py 2 Mar 2003 05:32:38 -0000 1.17.6.2 --- Header.py 3 Mar 2003 06:59:14 -0000 1.17.6.3 *************** *** 263,277 **** self._chunks.append((s, charset)) ! def _split(self, s, charset, firstline, splitchars): # Split up a header safely for use with encode_chunks. splittable = charset.to_splittable(s) encoded = charset.from_splittable(splittable, True) elen = charset.encoded_header_len(encoded) - # The maxlinelen depends on whether we're on the first line or not, to - # take account of any header field name. - if firstline: - maxlinelen = self._firstlinelen - else: - maxlinelen = self._maxlinelen # If the line's encoded length first, just return it if elen <= maxlinelen: --- 263,271 ---- self._chunks.append((s, charset)) ! def _split(self, s, charset, maxlinelen, splitchars): # Split up a header safely for use with encode_chunks. splittable = charset.to_splittable(s) encoded = charset.from_splittable(splittable, True) elen = charset.encoded_header_len(encoded) # If the line's encoded length first, just return it if elen <= maxlinelen: *************** *** 297,301 **** # higher-level syntactic breaks. elif charset == 'us-ascii': ! return self._split_ascii(s, charset, firstline, splitchars) # BAW: should we use encoded? elif elen == len(s): --- 291,295 ---- # higher-level syntactic breaks. elif charset == 'us-ascii': ! return self._split_ascii(s, charset, maxlinelen, splitchars) # BAW: should we use encoded? elif elen == len(s): *************** *** 308,326 **** # Binary search for split point first, last = _binsplit(splittable, charset, maxlinelen) - # Divide and conquer. - ## halfway = _floordiv(len(splittable), 2) - ## first = charset.from_splittable(splittable[:halfway], False) - ## last = charset.from_splittable(splittable[halfway:], False) # Do the split ! return self._split(first, charset, firstline, splitchars) + \ ! self._split(last, charset, False, splitchars) ! def _split_ascii(self, s, charset, firstline, splitchars): ! if firstline: ! firstlen = self._firstlinelen ! restlen = self._maxlinelen ! else: ! firstlen = restlen = self._maxlinelen ! line = _split_ascii(s, firstlen, restlen, self._continuation_ws, splitchars) lines = line.splitlines() --- 302,311 ---- # Binary search for split point first, last = _binsplit(splittable, charset, maxlinelen) # Do the split ! return self._split(first, charset, maxlinelen, splitchars) + \ ! self._split(last, charset, self._maxlinelen, splitchars) ! def _split_ascii(self, s, charset, firstlen, splitchars): ! line = _split_ascii(s, firstlen, self._maxlinelen, self._continuation_ws, splitchars) lines = line.splitlines() *************** *** 379,384 **** """ newchunks = [] for s, charset in self._chunks: ! newchunks += self._split(s, charset, True, splitchars) return self._encode_chunks(newchunks) --- 364,380 ---- """ newchunks = [] + maxlinelen = self._firstlinelen + lastlen = 0 for s, charset in self._chunks: ! # The first bit of the next chunk should be just long enough to ! # fill the next line. Don't forget the space separating the ! # encoded words. ! targetlen = maxlinelen - lastlen - 1 ! if targetlen < charset.encoded_header_len(''): ! # Stick it on the next line ! targetlen = maxlinelen ! newchunks += self._split(s, charset, targetlen, splitchars) ! lastchunk, lastcharset = newchunks[-1] ! lastlen = lastcharset.encoded_header_len(lastchunk) return self._encode_chunks(newchunks) *************** *** 445,464 **** def _binsplit(splittable, charset, maxlinelen): ! i = lastm = 0 ! j = len(splittable) - 1 ! while True: ! if j < i: ! break ! m = (i + j) / 2 chunk = charset.from_splittable(splittable[:m], True) chunklen = charset.encoded_header_len(chunk) ! if chunklen < maxlinelen: ! lastm = m ! i = m + 1 ! elif chunklen > maxlinelen: ! j = m - 1 else: ! break ! first = charset.from_splittable(splittable[:lastm], False) ! last = charset.from_splittable(splittable[lastm:], False) return first, last --- 441,468 ---- def _binsplit(splittable, charset, maxlinelen): ! i = 0 ! j = len(splittable) ! while i < j: ! # Invariants: ! # 1. splittable[:k] fits for all k <= i (note that we *assume*, ! # at the start, that splittable[:0] fits). ! # 2. splittable[:k] does not fit for any k > j (at the start, ! # this means we shouldn't look at any k > len(splittable)). ! # 3. We don't know about splittable[:k] for k in i+1..j. ! # 4. We want to set i to the largest k that fits, with i <= k <= j. ! # ! m = (i+j+1) >> 1 # ceiling((i+j)/2); i < m <= j chunk = charset.from_splittable(splittable[:m], True) chunklen = charset.encoded_header_len(chunk) ! if chunklen <= maxlinelen: ! # m is acceptable, so is a new lower bound. ! i = m else: ! # m is not acceptable, so final i must be < j. ! j = m - 1 ! # i == j. Invariant #1 implies that splittable[:i] fits, and ! # invariant #2 implies that splittable[:i+1] does not fit, so i ! # is what we're looking for. ! first = charset.from_splittable(splittable[:i], False) ! last = charset.from_splittable(splittable[i:], False) return first, last From bwarsaw@users.sourceforge.net Mon Mar 3 07:00:04 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sun, 02 Mar 2003 23:00:04 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.29.4.1,1.29.4.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv6548 Modified Files: Tag: folding-reimpl-branch test_email.py Log Message: Update some of the more complicated encoded header tests. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.29.4.1 retrieving revision 1.29.4.2 diff -C2 -d -r1.29.4.1 -r1.29.4.2 *** test_email.py 2 Mar 2003 03:35:33 -0000 1.29.4.1 --- test_email.py 3 Mar 2003 07:00:01 -0000 1.29.4.2 *************** *** 577,604 **** eq(sfp.getvalue(), """\ Subject: =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?= ! =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCnd?= ! =?iso-8859-1?q?ischen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kli?= ! =?iso-8859-1?q?ngen_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_metropol?= ! =?iso-8859-2?q?e_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= ! =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE44G+44Gb?= ! =?utf-8?b?44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB44GC44Go?= ! =?utf-8?b?44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBp?= ! =?utf-8?q?st_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das_Oder?= ! =?utf-8?b?IGRpZSBGbGlwcGVyd2FsZHQgZ2Vyc3B1dC7jgI3jgajoqIDjgaPjgabjgYQ=?= ! =?utf-8?b?44G+44GZ44CC?= """) eq(h.encode(), """\ =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?= ! =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCnd?= ! =?iso-8859-1?q?ischen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kli?= ! =?iso-8859-1?q?ngen_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_metropol?= ! =?iso-8859-2?q?e_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= ! =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE44G+44Gb?= ! =?utf-8?b?44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB44GC44Go?= ! =?utf-8?b?44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBp?= ! =?utf-8?q?st_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das_Oder?= ! =?utf-8?b?IGRpZSBGbGlwcGVyd2FsZHQgZ2Vyc3B1dC7jgI3jgajoqIDjgaPjgabjgYQ=?= ! =?utf-8?b?44G+44GZ44CC?=""") def test_long_header_encode(self): --- 577,604 ---- eq(sfp.getvalue(), """\ Subject: =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?= ! =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndi?= ! =?iso-8859-1?q?schen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kling?= ! =?iso-8859-1?q?en_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_met?= ! =?iso-8859-2?q?ropole_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= ! =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE?= ! =?utf-8?b?44G+44Gb44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB?= ! =?utf-8?b?44GC44Go44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CM?= ! =?utf-8?q?Wenn_ist_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das?= ! =?utf-8?b?IE9kZXIgZGllIEZsaXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBow==?= ! =?utf-8?b?44Gm44GE44G+44GZ44CC?= """) eq(h.encode(), """\ =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?= ! =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndi?= ! =?iso-8859-1?q?schen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kling?= ! =?iso-8859-1?q?en_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_met?= ! =?iso-8859-2?q?ropole_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= ! =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE?= ! =?utf-8?b?44G+44Gb44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB?= ! =?utf-8?b?44GC44Go44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CM?= ! =?utf-8?q?Wenn_ist_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das?= ! =?utf-8?b?IE9kZXIgZGllIEZsaXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBow==?= ! =?utf-8?b?44Gm44GE44G+44GZ44CC?=""") def test_long_header_encode(self): *************** *** 761,768 **** # BAW: this seems broken because the first line is too long eq(h.encode(), """\ ! X-Very-Very-Very-Long-Header-Name: =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_eine?= ! =?iso-8859-1?q?m_Foerderband_komfortabel_den_Korridor_ent?= ! =?iso-8859-1?q?lang=2C_an_s=FCdl=FCndischen_Wandgem=E4lden_vorbei?= ! =?iso-8859-1?q?=2C_gegen_die_rotierenden_Klingen_bef=F6rdert=2E_?=""") --- 761,768 ---- # BAW: this seems broken because the first line is too long eq(h.encode(), """\ ! =?iso-8859-1?q?Die_Mieter_treten_hier_?= ! =?iso-8859-1?q?ein_werden_mit_einem_Foerderband_komfortabel_den_Korridor_?= ! =?iso-8859-1?q?entlang=2C_an_s=FCdl=FCndischen_Wandgem=E4lden_vorbei=2C_g?= ! =?iso-8859-1?q?egen_die_rotierenden_Klingen_bef=F6rdert=2E_?=""") *************** *** 2250,2263 **** eq(enc, """\ =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerderband_ko?= ! =?iso-8859-1?q?mfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndischen_Wa?= ! =?iso-8859-1?q?ndgem=E4lden_vorbei=2C_gegen_die_rotierenden_Klingen_bef?= ! =?iso-8859-1?q?=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_metropole_se_hro?= ! =?iso-8859-2?q?utily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= =?utf-8?b?5q2j?= ! =?utf-8?b?56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE44G+44Gb44KT?= ! =?utf-8?b?44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB44GC44Go44Gv?= ! =?utf-8?b?44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBpc3Qg?= ! =?utf-8?q?das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das_Oder_di?= ! =?utf-8?b?ZSBGbGlwcGVyd2FsZHQgZ2Vyc3B1dC7jgI3jgajoqIDjgaPjgabjgYTjgb4=?= ! =?utf-8?b?44GZ44CC?=""") eq(decode_header(enc), [(g_head, "iso-8859-1"), (cz_head, "iso-8859-2"), --- 2250,2263 ---- eq(enc, """\ =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerderband_ko?= ! =?iso-8859-1?q?mfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndischen_Wan?= ! =?iso-8859-1?q?dgem=E4lden_vorbei=2C_gegen_die_rotierenden_Klingen_bef=F6?= ! =?iso-8859-1?q?rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_metropole_se_hroutily?= ! =?iso-8859-2?q?_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= =?utf-8?b?5q2j56K6?= ! =?utf-8?b?44Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE44G+44Gb44KT44CC?= ! =?utf-8?b?5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB44GC44Go44Gv44Gn?= ! =?utf-8?b?44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBpc3QgZGFz?= ! =?utf-8?q?_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das_Oder_die_Fl?= ! =?utf-8?b?aXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBo+OBpuOBhOOBvuOBmQ==?= ! =?utf-8?b?44CC?=""") eq(decode_header(enc), [(g_head, "iso-8859-1"), (cz_head, "iso-8859-2"), From bwarsaw@users.sourceforge.net Mon Mar 3 07:02:04 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Sun, 02 Mar 2003 23:02:04 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email_codecs.py,1.3.8.1,1.3.8.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv7092 Modified Files: Tag: folding-reimpl-branch test_email_codecs.py Log Message: Update a test but see the BAW comment. Index: test_email_codecs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email_codecs.py,v retrieving revision 1.3.8.1 retrieving revision 1.3.8.2 diff -C2 -d -r1.3.8.1 -r1.3.8.2 *** test_email_codecs.py 2 Mar 2003 03:35:53 -0000 1.3.8.1 --- test_email_codecs.py 3 Mar 2003 07:02:02 -0000 1.3.8.2 *************** *** 27,31 **** h.append(jhello, j) h.append(ghello, g) ! eq(h.encode(), 'Hello World! =?iso-2022-jp?b?GyRCJU8lbSE8JW8hPCVrJUkhKhsoQg==?=\n =?iso-8859-1?q?Gr=FC=DF_Gott!?=') eq(decode_header(h.encode()), [('Hello World!', None), --- 27,38 ---- h.append(jhello, j) h.append(ghello, g) ! # BAW: This used to -- and maybe should -- fold the two iso-8859-1 ! # chunks into a single encoded word. However it doesn't violate the ! # standard to have them as two encoded chunks and maybe it's ! # reasonable for each .append() call to result in a separate ! # encoded word. ! eq(h.encode(), """\ ! Hello World! =?iso-2022-jp?b?GyRCJU8lbSE8JW8hPCVrJUkhKhsoQg==?= ! =?iso-8859-1?q?Gr=FC=DF?= =?iso-8859-1?q?_Gott!?=""") eq(decode_header(h.encode()), [('Hello World!', None), From loewis@users.sourceforge.net Mon Mar 3 09:34:05 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Mon, 03 Mar 2003 01:34:05 -0800 Subject: [Python-checkins] python/dist/src/Lib site.py,1.47,1.48 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv23190 Modified Files: site.py Log Message: Patch #671666: Alias ANSI code page to "mbcs". Index: site.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/site.py,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -d -r1.47 -r1.48 *** site.py 30 Dec 2002 22:08:02 -0000 1.47 --- site.py 3 Mar 2003 09:34:01 -0000 1.48 *************** *** 283,286 **** --- 283,302 ---- + # On Windows, some default encodings are not provided + # by Python (e.g. "cp932" in Japanese locale), while they + # are always available as "mbcs" in each locale. + # Make them usable by aliasing to "mbcs" in such a case. + + if sys.platform == 'win32': + import locale, codecs + enc = locale.getdefaultlocale()[1] + if enc.startswith('cp'): # "cp***" ? + try: + codecs.lookup(enc) + except LookupError: + import encodings + encodings._cache[enc] = encodings._unknown + encodings.aliases.aliases[enc] = 'mbcs' + # Set the string encoding used by the Unicode implementation. The # default is 'ascii', but if you're willing to experiment, you can From loewis@users.sourceforge.net Mon Mar 3 10:40:16 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Mon, 03 Mar 2003 02:40:16 -0800 Subject: [Python-checkins] python/dist/src/Modules _tkinter.c,1.149,1.150 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv19890 Modified Files: _tkinter.c Log Message: Don't crash on _tkinter.createfilehandler in non-threaded Tcl; disable this function in threaded Tcl. Likewise for creaetetimerhandler. Fixes #692416. Index: _tkinter.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v retrieving revision 1.149 retrieving revision 1.150 diff -C2 -d -r1.149 -r1.150 *** _tkinter.c 11 Feb 2003 23:05:40 -0000 1.149 --- _tkinter.c 3 Mar 2003 10:40:01 -0000 1.150 *************** *** 2203,2207 **** &file, &mask, &func)) return NULL; ! CHECK_TCL_APPARTMENT; tfile = PyObject_AsFileDescriptor(file); if (tfile < 0) --- 2203,2219 ---- &file, &mask, &func)) return NULL; ! ! if (!self && !tcl_lock) { ! /* We don't have the Tcl lock since Tcl is threaded. */ ! PyErr_SetString(PyExc_RuntimeError, ! "_tkinter.createfilehandler not supported " ! "for threaded Tcl"); ! return NULL; ! } ! ! if (self) { ! CHECK_TCL_APPARTMENT; ! } ! tfile = PyObject_AsFileDescriptor(file); if (tfile < 0) *************** *** 2397,2400 **** --- 2409,2425 ---- return NULL; } + + if (!self && !tcl_lock) { + /* We don't have the Tcl lock since Tcl is threaded. */ + PyErr_SetString(PyExc_RuntimeError, + "_tkinter.createtimerhandler not supported " + "for threaded Tcl"); + return NULL; + } + + if (self) { + CHECK_TCL_APPARTMENT; + } + v = Tktt_New(func); v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler, From jackjansen@users.sourceforge.net Mon Mar 3 12:25:05 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Mon, 03 Mar 2003 04:25:05 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac EasyDialogs.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv29414 Modified Files: EasyDialogs.py Log Message: Call AEInteractWithUser() before bringing up any of the dialogs (with the exception of the ProgressBar, which I think is okay to show in the background). This is a prerequisitite for the fix of #684975. Index: EasyDialogs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/EasyDialogs.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** EasyDialogs.py 21 Feb 2003 23:18:48 -0000 1.9 --- EasyDialogs.py 3 Mar 2003 12:25:02 -0000 1.10 *************** *** 28,31 **** --- 28,32 ---- from Carbon import Controls from Carbon import Menu + from Carbon import AE import Nav import MacOS *************** *** 47,51 **** if _initialized: return macresource.need("DLOG", 260, "dialogs.rsrc", __name__) ! def cr2lf(text): --- 48,55 ---- if _initialized: return macresource.need("DLOG", 260, "dialogs.rsrc", __name__) ! ! def _interact(): ! """Make sure the application is in the foreground""" ! AE.AEInteractWithUser(50000000) def cr2lf(text): *************** *** 69,72 **** --- 73,77 ---- """ _initialize() + _interact() d = GetNewDialog(id, -1) if not d: *************** *** 101,104 **** --- 106,110 ---- _initialize() + _interact() d = GetNewDialog(id, -1) if not d: *************** *** 142,145 **** --- 148,152 ---- """ _initialize() + _interact() d = GetNewDialog(id, -1) if not d: *************** *** 185,188 **** --- 192,196 ---- _initialize() + _interact() d = GetNewDialog(id, -1) if not d: *************** *** 417,420 **** --- 425,429 ---- def GetArgv(optionlist=None, commandlist=None, addoldfile=1, addnewfile=1, addfolder=1, id=ARGV_ID): _initialize() + _interact() d = GetNewDialog(id, -1) if not d: *************** *** 637,640 **** --- 646,650 ---- popupExtension=popupExtension,eventProc=eventProc,previewProc=previewProc, filterProc=filterProc,typeList=typeList,wanted=wanted,multiple=multiple) + _interact() try: rr = Nav.NavChooseFile(args) *************** *** 689,692 **** --- 699,703 ---- popupExtension=popupExtension,eventProc=eventProc,fileType=fileType, fileCreator=fileCreator,wanted=wanted,multiple=multiple) + _interact() try: rr = Nav.NavPutFile(args) *************** *** 748,751 **** --- 759,763 ---- popupExtension=popupExtension,eventProc=eventProc,filterProc=filterProc, wanted=wanted,multiple=multiple) + _interact() try: rr = Nav.NavChooseFolder(args) From jackjansen@users.sourceforge.net Mon Mar 3 12:28:07 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Mon, 03 Mar 2003 04:28:07 -0800 Subject: [Python-checkins] python/dist/src/Mac/Tools/IDE PythonIDEMain.py,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory sc8-pr-cvs1:/tmp/cvs-serv32050 Modified Files: PythonIDEMain.py Log Message: Don't call AEInteractWithUser unconditionally on a quit appleevent. The EasyDIalogs methods will call it if needed. Fixes #684975. Index: PythonIDEMain.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PythonIDEMain.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** PythonIDEMain.py 28 Feb 2003 15:18:59 -0000 1.30 --- PythonIDEMain.py 3 Mar 2003 12:28:04 -0000 1.31 *************** *** 157,162 **** def quitevent(self, theAppleEvent, theReply): - from Carbon import AE - AE.AEInteractWithUser(50000000) self._quit() --- 157,160 ---- From mwh@users.sourceforge.net Mon Mar 3 12:29:44 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Mon, 03 Mar 2003 04:29:44 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.685,1.686 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv423/Misc Modified Files: NEWS Log Message: Fix bug [ 555817 ] Flawed fcntl.ioctl implementation. with my patch that allows for an array to be mutated when passed as the buffer argument to ioctl() (details complicated by backwards compatibility considerations -- read the docs!). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.685 retrieving revision 1.686 diff -C2 -d -r1.685 -r1.686 *** NEWS 2 Mar 2003 00:19:49 -0000 1.685 --- NEWS 3 Mar 2003 12:29:41 -0000 1.686 *************** *** 25,28 **** --- 25,31 ---- ----------------- + - Modified the fcntl.ioctl() function to allow modification of a passed + mutable buffer (for details see the reference documentation). + - Made user requested changes to the itertools module. Subsumed the times() function into repeat(). From mwh@users.sourceforge.net Mon Mar 3 12:29:44 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Mon, 03 Mar 2003 04:29:44 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_ioctl.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv423/Lib/test Added Files: test_ioctl.py Log Message: Fix bug [ 555817 ] Flawed fcntl.ioctl implementation. with my patch that allows for an array to be mutated when passed as the buffer argument to ioctl() (details complicated by backwards compatibility considerations -- read the docs!). --- NEW FILE: test_ioctl.py --- import unittest from test_support import TestSkipped, run_unittest import os, struct try: import fcntl, termios except ImportError: raise TestSkipped("No fcntl or termios module") if not hasattr(termios,'TIOCGPGRP'): raise TestSkipped("termios module doesn't have TIOCGPGRP") class IoctlTests(unittest.TestCase): def test_ioctl(self): pgrp = os.getpgrp() tty = open("/dev/tty", "r") r = fcntl.ioctl(tty, termios.TIOCGPGRP, " ") self.assertEquals(pgrp, struct.unpack("i", r)[0]) def test_ioctl_mutate(self): import array buf = array.array('i', [0]) pgrp = os.getpgrp() tty = open("/dev/tty", "r") r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1) self.assertEquals(r, 0) self.assertEquals(pgrp, buf[0]) def test_main(): run_unittest(IoctlTests) if __name__ == "__main__": test_main() From mwh@users.sourceforge.net Mon Mar 3 12:29:44 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Mon, 03 Mar 2003 04:29:44 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libfcntl.tex,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv423/Doc/lib Modified Files: libfcntl.tex Log Message: Fix bug [ 555817 ] Flawed fcntl.ioctl implementation. with my patch that allows for an array to be mutated when passed as the buffer argument to ioctl() (details complicated by backwards compatibility considerations -- read the docs!). Index: libfcntl.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfcntl.tex,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** libfcntl.tex 15 Jan 2003 21:08:19 -0000 1.30 --- libfcntl.tex 3 Mar 2003 12:29:42 -0000 1.31 *************** *** 48,55 **** \end{funcdesc} ! \begin{funcdesc}{ioctl}{fd, op, arg} ! This function is identical to the \function{fcntl()} function, except ! that the operations are typically defined in the library module ! \refmodule{termios}. \end{funcdesc} --- 48,102 ---- \end{funcdesc} ! \begin{funcdesc}{ioctl}{fd, op\optional{, arg\optional{, mutate_flag}}} ! This function is identical to the \function{fcntl()} function, ! except that the operations are typically defined in the library ! module \refmodule{termios} and the argument handling is even more ! complicated. ! ! The parameter \var{arg} can be one of an integer, absent (treated ! identically to the integer \code{0}), an object supporting the ! read-only buffer interface (most likely a plain Python string) or an ! object supporting the read-write buffer interface. ! ! In all but the last case, behaviour is as for the \function{fcntl()} ! function. ! ! If a mutable buffer is passed, then the behaviour is determined by ! the value of the \var{mutate_flag} parameter. ! ! If it is false, the buffer's mutability is ignored and behaviour is ! as for a read-only buffer, except that the 1024 byte limit mentioned ! above is avoided -- so long as the buffer you pass is longer than ! what the operating system wants to put there, things should work. ! ! If \var{mutate_flag} is true, then the buffer is (in effect) passed ! to the underlying \function{ioctl()} system call, the latter's ! return code is passed back to the calling Python, and the buffer's ! new contents reflect the action of the \function{ioctl}. This is a ! slight simplification, because if the supplied buffer is less than ! 1024 bytes long it is first copied into a static buffer 1024 bytes ! long which is then passed to \function{ioctl} and copied back into ! the supplied buffer. ! ! If \var{mutate_flag} is not supplied, then in 2.3 it defaults to ! false. This is planned to change over the next few Python versions: ! in 2.4 failing to supply \var{mutate_flag} will get a warning but ! the same behavior and in versions later than 2.5 it will default to ! true. ! ! An example: ! ! \begin{verbatim} ! >>> import array, fnctl, struct, termios, os ! >>> os.getpgrp() ! 13341 ! >>> struct.unpack('h', fcntl.ioctl(0, termios.TIOCGPGRP, " "))[0] ! 13341 ! >>> buf = array.array('h', [0]) ! >>> fcntl.ioctl(0, termios.TIOCGPGRP, buf, 1) ! 0 ! >>> buf ! array('h', [13341]) ! \end{verbatim} \end{funcdesc} *************** *** 123,128 **** \seemodule{os}{The \function{os.open} function supports locking flags and is available on a wider variety of platforms than ! the \function{fcntl.lockf} and \function{fcntl.flock} ! functions, providing a more platform-independent file ! locking facility.} \end{seealso} --- 170,175 ---- \seemodule{os}{The \function{os.open} function supports locking flags and is available on a wider variety of platforms than ! the \function{fcntl.lockf} and \function{fcntl.flock} ! functions, providing a more platform-independent file ! locking facility.} \end{seealso} From mwh@users.sourceforge.net Mon Mar 3 12:29:45 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Mon, 03 Mar 2003 04:29:45 -0800 Subject: [Python-checkins] python/dist/src/Modules fcntlmodule.c,2.37,2.38 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv423/Modules Modified Files: fcntlmodule.c Log Message: Fix bug [ 555817 ] Flawed fcntl.ioctl implementation. with my patch that allows for an array to be mutated when passed as the buffer argument to ioctl() (details complicated by backwards compatibility considerations -- read the docs!). Index: fcntlmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/fcntlmodule.c,v retrieving revision 2.37 retrieving revision 2.38 diff -C2 -d -r2.37 -r2.38 *** fcntlmodule.c 1 Jan 2003 09:51:12 -0000 2.37 --- fcntlmodule.c 3 Mar 2003 12:29:42 -0000 2.38 *************** *** 100,105 **** --- 100,159 ---- char *str; int len; + int mutate_arg = 0; char buf[1024]; + if (PyArg_ParseTuple(args, "O&iw#|i:ioctl", + conv_descriptor, &fd, &code, + &str, &len, &mutate_arg)) { + char *arg; + + if (PyTuple_Size(args) == 3) { + /* warning goes here in 2.4 */ + mutate_arg = 0; + } + if (mutate_arg) { + if (len <= sizeof buf) { + memcpy(buf, str, len); + arg = buf; + } + else { + arg = str; + } + } + else { + if (len > sizeof buf) { + PyErr_SetString(PyExc_ValueError, + "ioctl string arg too long"); + return NULL; + } + else { + memcpy(buf, str, len); + arg = buf; + } + } + if (buf == arg) { + Py_BEGIN_ALLOW_THREADS /* think array.resize() */ + ret = ioctl(fd, code, arg); + Py_END_ALLOW_THREADS + } + else { + ret = ioctl(fd, code, arg); + } + if (mutate_arg && (len < sizeof buf)) { + memcpy(str, buf, len); + } + if (ret < 0) { + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + if (mutate_arg) { + return PyInt_FromLong(ret); + } + else { + return PyString_FromStringAndSize(buf, len); + } + } + + PyErr_Clear(); if (PyArg_ParseTuple(args, "O&is#:ioctl", conv_descriptor, &fd, &code, &str, &len)) { *************** *** 124,128 **** if (!PyArg_ParseTuple(args, "O&i|i;ioctl requires a file or file descriptor," ! " an integer and optionally a third integer or a string", conv_descriptor, &fd, &code, &arg)) { return NULL; --- 178,182 ---- if (!PyArg_ParseTuple(args, "O&i|i;ioctl requires a file or file descriptor," ! " an integer and optionally a integer or buffer argument", conv_descriptor, &fd, &code, &arg)) { return NULL; *************** *** 139,153 **** PyDoc_STRVAR(ioctl_doc, ! "ioctl(fd, opt, [arg])\n\ \n\ ! Perform the requested operation on file descriptor fd. The operation\n\ ! is defined by op and is operating system dependent. Typically these\n\ ! codes can be retrieved from the library module IOCTL. The argument arg\n\ ! is optional, and defaults to 0; it may be an int or a string. If arg is\n\ ! given as a string, the return value of ioctl is a string of that length,\n\ ! containing the resulting value put in the arg buffer by the operating system.\n\ ! The length of the arg string is not allowed to exceed 1024 bytes. If the arg\n\ ! given is an integer or if none is specified, the result value is an integer\n\ ! corresponding to the return value of the ioctl call in the C code."); --- 193,225 ---- PyDoc_STRVAR(ioctl_doc, ! "ioctl(fd, opt[, arg[, mutate_flag]])\n\ \n\ ! Perform the requested operation on file descriptor fd. The operation is\n\ ! defined by op and is operating system dependent. Typically these codes are\n\ ! retrieved from the fcntl or termios library modules.\n\ ! \n\ ! The argument arg is optional, and defaults to 0; it may be an int or a\n\ ! buffer containing character data (most likely a string or an array). \n\ ! \n\ ! If the argument is a mutable buffer (such as an array) and if the\n\ ! mutate_flag argument (which is only allowed in this case) is true then the\n\ ! buffer is (in effect) passed to the operating system and changes made by\n\ ! the OS will be reflected in the contents of the buffer after the call has\n\ ! returned. The return value is the integer returned by the ioctl system\n\ ! call.\n\ ! \n\ ! If the argument is a mutable buffer and the mutable_flag argument is not\n\ ! passed or is false, the behavior is as if a string had been passed. This\n\ ! behavior will change in future releases of Python.\n\ ! \n\ ! If the argument is an immutable buffer (most likely a string) then a copy\n\ ! of the buffer is passed to the operating system and the return value is a\n\ ! string of the same length containing whatever the operating system put in\n\ ! the buffer. The length of the arg buffer in this case is not allowed to\n\ ! exceed 1024 bytes.\n\ ! \n\ ! If the arg given is an integer or if none is specified, the result value is\n\ ! an integer corresponding to the return value of the ioctl call in the C\n\ ! code."); From jackjansen@users.sourceforge.net Mon Mar 3 13:13:01 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Mon, 03 Mar 2003 05:13:01 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules/cf _CFmodule.c,1.19,1.20 cfsupport.py,1.19,1.20 pycfbridge.c,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory sc8-pr-cvs1:/tmp/cvs-serv17271 Modified Files: _CFmodule.c cfsupport.py pycfbridge.c Log Message: Accept only the system default encoding when converting Python strings to CF strings. Fixes 682215. Index: _CFmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/_CFmodule.c,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** _CFmodule.c 23 Dec 2002 22:35:38 -0000 1.19 --- _CFmodule.c 3 Mar 2003 13:12:58 -0000 1.20 *************** *** 15,21 **** /* Macro to test whether a weak-loaded CFM function exists */ #define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\ ! PyErr_SetString(PyExc_NotImplementedError, \ ! "Not available in this shared library/OS version"); \ ! return NULL; \ }} while(0) --- 15,21 ---- /* Macro to test whether a weak-loaded CFM function exists */ #define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\ ! PyErr_SetString(PyExc_NotImplementedError, \ ! "Not available in this shared library/OS version"); \ ! return NULL; \ }} while(0) *************** *** 1459,1463 **** if (PyString_Check(v)) { char *cStr = PyString_AsString(v); ! *p_itself = CFStringCreateWithCString((CFAllocatorRef)NULL, cStr, 0); return 1; } --- 1459,1463 ---- if (PyString_Check(v)) { char *cStr = PyString_AsString(v); ! *p_itself = CFStringCreateWithCString((CFAllocatorRef)NULL, cStr, kCFStringEncodingASCII); return 1; } Index: cfsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/cfsupport.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** cfsupport.py 23 Dec 2002 22:35:38 -0000 1.19 --- cfsupport.py 3 Mar 2003 13:12:59 -0000 1.20 *************** *** 360,365 **** if (v == Py_None) { *p_itself = NULL; return 1; } if (PyString_Check(v)) { ! char *cStr = PyString_AsString(v); ! *p_itself = CFStringCreateWithCString((CFAllocatorRef)NULL, cStr, 0); return 1; } --- 360,367 ---- if (v == Py_None) { *p_itself = NULL; return 1; } if (PyString_Check(v)) { ! char *cStr; ! if (!PyArg_Parse(v, "et", "ascii", &cStr)) ! return NULL; ! *p_itself = CFStringCreateWithCString((CFAllocatorRef)NULL, cStr, kCFStringEncodingASCII); return 1; } Index: pycfbridge.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/pycfbridge.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pycfbridge.c 13 May 2002 21:23:10 -0000 1.5 --- pycfbridge.c 3 Mar 2003 13:12:59 -0000 1.6 *************** *** 293,298 **** if (PyString_Check(src)) { ! if ((chars = PyString_AsString(src)) == NULL ) goto err; ! *dst = CFStringCreateWithCString((CFAllocatorRef)NULL, chars, 0); return 1; } --- 293,299 ---- if (PyString_Check(src)) { ! if (!PyArg_Parse(src, "es", NULL, &chars)) ! return NULL; /* This error is more descriptive than the general one below */ ! *dst = CFStringCreateWithCString((CFAllocatorRef)NULL, chars, kCFStringEncodingASCII); return 1; } From jackjansen@users.sourceforge.net Mon Mar 3 13:19:46 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Mon, 03 Mar 2003 05:19:46 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules/cf cfsupport.py,1.20,1.21 pycfbridge.c,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory sc8-pr-cvs1:/tmp/cvs-serv19892 Modified Files: cfsupport.py pycfbridge.c Log Message: Mod to previous checkin: we must require ascii, not system defautl encoding, because we have no easy way to convert the python encoding string to a CF encoding parameter. Index: cfsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/cfsupport.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** cfsupport.py 3 Mar 2003 13:12:59 -0000 1.20 --- cfsupport.py 3 Mar 2003 13:19:43 -0000 1.21 *************** *** 361,365 **** if (PyString_Check(v)) { char *cStr; ! if (!PyArg_Parse(v, "et", "ascii", &cStr)) return NULL; *p_itself = CFStringCreateWithCString((CFAllocatorRef)NULL, cStr, kCFStringEncodingASCII); --- 361,365 ---- if (PyString_Check(v)) { char *cStr; ! if (!PyArg_Parse(v, "es", "ascii", &cStr)) return NULL; *p_itself = CFStringCreateWithCString((CFAllocatorRef)NULL, cStr, kCFStringEncodingASCII); Index: pycfbridge.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/pycfbridge.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pycfbridge.c 3 Mar 2003 13:12:59 -0000 1.6 --- pycfbridge.c 3 Mar 2003 13:19:44 -0000 1.7 *************** *** 293,297 **** if (PyString_Check(src)) { ! if (!PyArg_Parse(src, "es", NULL, &chars)) return NULL; /* This error is more descriptive than the general one below */ *dst = CFStringCreateWithCString((CFAllocatorRef)NULL, chars, kCFStringEncodingASCII); --- 293,297 ---- if (PyString_Check(src)) { ! if (!PyArg_Parse(src, "es", "ascii", &chars)) return NULL; /* This error is more descriptive than the general one below */ *dst = CFStringCreateWithCString((CFAllocatorRef)NULL, chars, kCFStringEncodingASCII); From jackjansen@users.sourceforge.net Mon Mar 3 14:57:02 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Mon, 03 Mar 2003 06:57:02 -0800 Subject: [Python-checkins] python/dist/src/Mac/Tools/IDE PyDebugger.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory sc8-pr-cvs1:/tmp/cvs-serv28847 Modified Files: PyDebugger.py Log Message: Gave the text fields a little more space, so they don't get cut off. Index: PyDebugger.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PyDebugger.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** PyDebugger.py 13 Dec 2002 23:31:55 -0000 1.12 --- PyDebugger.py 3 Mar 2003 14:56:59 -0000 1.13 *************** *** 154,158 **** w.panes.bottom = bottom = W.Group(None) ! bottom.src = src = W.Group((0, 52, 0, 0)) source = SourceViewer((1, 1, -15, -15), readonly = 1, debugger = self) src.optionsmenu = W.PopupMenu((-16, 0, 16, 16), []) --- 154,158 ---- w.panes.bottom = bottom = W.Group(None) ! bottom.src = src = W.Group((0, 64, 0, 0)) source = SourceViewer((1, 1, -15, -15), readonly = 1, debugger = self) src.optionsmenu = W.PopupMenu((-16, 0, 16, 16), []) *************** *** 165,172 **** bottom.tracingmonitor = TracingMonitor((0, 23, 6, 6)) ! bottom.state = W.TextBox((12, 20, 0, 16), self.reason) ! bottom.srctitle = W.TextBox((12, 36, 0, 14)) ! bottom.buttons = buttons = W.Group((12, 0, 0, 16)) buttons.runbutton = W.Button((0, 0, 50, 16), "Run", self.do_run) --- 165,172 ---- bottom.tracingmonitor = TracingMonitor((0, 23, 6, 6)) ! bottom.state = W.TextBox((12, 24, 0, 16), self.reason) ! bottom.srctitle = W.TextBox((12, 44, 0, 16)) ! bottom.buttons = buttons = W.Group((12, 0, 0, 20)) buttons.runbutton = W.Button((0, 0, 50, 16), "Run", self.do_run) From bwarsaw@users.sourceforge.net Mon Mar 3 15:40:33 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 03 Mar 2003 07:40:33 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.29.4.2,1.29.4.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv22260 Modified Files: Tag: folding-reimpl-branch test_email.py Log Message: test_whitespace_eater(): Test for complaint in SF patch #585600. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.29.4.2 retrieving revision 1.29.4.3 diff -C2 -d -r1.29.4.2 -r1.29.4.3 *** test_email.py 3 Mar 2003 07:00:01 -0000 1.29.4.2 --- test_email.py 3 Mar 2003 15:40:28 -0000 1.29.4.3 *************** *** 2361,2364 **** --- 2361,2373 ---- eq(h.encode(), s) + def test_whitespace_eater(self): + eq = self.assertEqual + s = 'Subject: =?koi8-r?b?8NLP18XSy8EgzsEgxsnOwczYztk=?= =?koi8-r?q?=CA?= zz.' + parts = decode_header(s) + eq(parts, [('Subject:', None), ('\xf0\xd2\xcf\xd7\xc5\xd2\xcb\xc1 \xce\xc1 \xc6\xc9\xce\xc1\xcc\xd8\xce\xd9\xca', 'koi8-r'), ('zz.', None)]) + hdr = make_header(parts) + eq(hdr.encode(), + 'Subject: =?koi8-r?b?8NLP18XSy8EgzsEgxsnOwczYztnK?= zz.') + From bwarsaw@users.sourceforge.net Mon Mar 3 15:48:15 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 03 Mar 2003 07:48:15 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Generator.py,1.17,1.17.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv26220 Modified Files: Tag: folding-reimpl-branch Generator.py Log Message: _make_boundary(): Some locales don't use periods as th decimal point character. SF patch #652497 by Dmitry Azhichakov (slightly modified by Barry). Index: Generator.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Generator.py,v retrieving revision 1.17 retrieving revision 1.17.6.1 diff -C2 -d -r1.17 -r1.17.6.1 *** Generator.py 14 Oct 2002 15:09:30 -0000 1.17 --- Generator.py 3 Mar 2003 15:48:08 -0000 1.17.6.1 *************** *** 5,10 **** """ - import time import re import random --- 5,11 ---- """ import re + import time + import locale import random *************** *** 365,369 **** # Craft a random boundary. If text is given, ensure that the chosen # boundary doesn't appear in the text. ! boundary = ('=' * 15) + repr(random.random()).split('.')[1] + '==' if text is None: return boundary --- 366,371 ---- # Craft a random boundary. If text is given, ensure that the chosen # boundary doesn't appear in the text. ! dp = locale.localeconv().get('decimal_point', '.') ! boundary = ('=' * 15) + repr(random.random()).split(dp)[1] + '==' if text is None: return boundary From bwarsaw@users.sourceforge.net Mon Mar 3 15:57:20 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 03 Mar 2003 07:57:20 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Header.py,1.17.6.3,1.17.6.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv30969 Modified Files: Tag: folding-reimpl-branch Header.py Log Message: _split(): `first' is now guaranteed to be of the correct length so we don't need to recursively split it. We just wrap it in the appropriate chrome, then add it to the recursively split remainder. Index: Header.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Header.py,v retrieving revision 1.17.6.3 retrieving revision 1.17.6.4 diff -C2 -d -r1.17.6.3 -r1.17.6.4 *** Header.py 3 Mar 2003 06:59:14 -0000 1.17.6.3 --- Header.py 3 Mar 2003 15:57:17 -0000 1.17.6.4 *************** *** 302,308 **** # Binary search for split point first, last = _binsplit(splittable, charset, maxlinelen) ! # Do the split ! return self._split(first, charset, maxlinelen, splitchars) + \ ! self._split(last, charset, self._maxlinelen, splitchars) def _split_ascii(self, s, charset, firstlen, splitchars): --- 302,311 ---- # Binary search for split point first, last = _binsplit(splittable, charset, maxlinelen) ! # first is of the proper length so just wrap it in the appropriate ! # chrome. last must be recursively split. ! fsplittable = charset.to_splittable(first) ! fencoded = charset.from_splittable(fsplittable, True) ! chunk = [(fencoded, charset)] ! return chunk + self._split(last, charset, self._maxlinelen, splitchars) def _split_ascii(self, s, charset, firstlen, splitchars): From bwarsaw@users.sourceforge.net Mon Mar 3 16:33:44 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 03 Mar 2003 08:33:44 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.29.4.3,1.29.4.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv16057 Modified Files: Tag: folding-reimpl-branch test_email.py Log Message: test_no_nl_preamble(): New test for preamble not being line terminated. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.29.4.3 retrieving revision 1.29.4.4 diff -C2 -d -r1.29.4.3 -r1.29.4.4 *** test_email.py 3 Mar 2003 15:40:28 -0000 1.29.4.3 --- test_email.py 3 Mar 2003 16:33:35 -0000 1.29.4.4 *************** *** 1345,1348 **** --- 1345,1385 ---- self.assertEqual(sfp.getvalue(), text) + def test_no_nl_preamble(self): + eq = self.ndiffAssertEqual + msg = Message() + msg['From'] = 'aperson@dom.ain' + msg['To'] = 'bperson@dom.ain' + msg['Subject'] = 'Test' + msg.preamble = 'MIME message' + msg.epilogue = '' + msg1 = MIMEText('One') + msg2 = MIMEText('Two') + msg.add_header('Content-Type', 'multipart/mixed', boundary='BOUNDARY') + msg.attach(msg1) + msg.attach(msg2) + eq(msg.as_string(), """\ + 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-- + """) + def test_default_type(self): eq = self.assertEqual From bwarsaw@users.sourceforge.net Mon Mar 3 16:36:28 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 03 Mar 2003 08:36:28 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Generator.py,1.17.6.1,1.17.6.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv17277 Modified Files: Tag: folding-reimpl-branch Generator.py Log Message: _handle_multipart(): If the preamble doesn't end in a line break, we must add one otherwise the following boundary separator will be broken. Closes SF bug #682504. Index: Generator.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Generator.py,v retrieving revision 1.17.6.1 retrieving revision 1.17.6.2 diff -C2 -d -r1.17.6.1 -r1.17.6.2 *** Generator.py 3 Mar 2003 15:48:08 -0000 1.17.6.1 --- Generator.py 3 Mar 2003 16:36:23 -0000 1.17.6.2 *************** *** 14,17 **** --- 14,18 ---- from email.Header import Header + from email.Parser import NLCRE try: *************** *** 260,263 **** --- 261,272 ---- if msg.preamble is not None: self._fp.write(msg.preamble) + # If preamble is the empty string, the length of the split will be + # 1, but the last element will be the empty string. If it's + # anything else but does not end in a line separator, the length + # will be > 1 and not end in an empty string. We need to + # guarantee a newline after the preamble, but don't add too many. + plines = NLCRE.split(msg.preamble) + if plines <> [''] and plines[-1] <> '': + self._fp.write('\n') # First boundary is a bit different; it doesn't have a leading extra # newline. From bwarsaw@users.sourceforge.net Mon Mar 3 16:37:19 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 03 Mar 2003 08:37:19 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Parser.py,1.19,1.19.6.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv17645 Modified Files: Tag: folding-reimpl-branch Parser.py Log Message: Cosmetic Index: Parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Parser.py,v retrieving revision 1.19 retrieving revision 1.19.6.1 diff -C2 -d -r1.19 -r1.19.6.1 *** Parser.py 5 Nov 2002 21:44:06 -0000 1.19 --- Parser.py 3 Mar 2003 16:37:12 -0000 1.19.6.1 *************** *** 21,25 **** False = 0 ! nlcre = re.compile('\r\n|\r|\n') --- 21,25 ---- False = 0 ! NLCRE = re.compile('\r\n|\r|\n') *************** *** 177,181 **** # Find out what kind of line endings we're using start += len(mo.group('sep')) + len(mo.group('ws')) ! mo = nlcre.search(payload, start) if mo: start += len(mo.group(0)) --- 177,181 ---- # Find out what kind of line endings we're using start += len(mo.group('sep')) + len(mo.group('ws')) ! mo = NLCRE.search(payload, start) if mo: start += len(mo.group(0)) From klm@users.sourceforge.net Mon Mar 3 17:09:47 2003 From: klm@users.sourceforge.net (klm@users.sourceforge.net) Date: Mon, 03 Mar 2003 09:09:47 -0800 Subject: [Python-checkins] python/dist/src/Misc python-mode.el,4.31,4.32 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv728 Modified Files: python-mode.el Log Message: py-pdbtrack-grub-for-buffer(): Rectified some logic errors i introduced when shifting around some code, and added some redundancy to reduce chances of hitting the wrong source code. (This is experimental - it will improve the accuracy, but will reduce the ability of the user to deliberately select the buffer they want the buffer grubbing stuff to find. I think the accuracy improvement will be worth it, but am not sure, so may remove this.) Index: python-mode.el =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/python-mode.el,v retrieving revision 4.31 retrieving revision 4.32 diff -C2 -d -r4.31 -r4.32 *** python-mode.el 3 Mar 2003 04:05:03 -0000 4.31 --- python-mode.el 3 Mar 2003 17:09:44 -0000 4.32 *************** *** 387,390 **** --- 387,397 ---- (defvar py-pdbtrack-is-tracking-p nil) + (defvar py-pdbtrack-last-grubbed-buffer nil + "Record of the last buffer used when the source path was invalid. + + This buffer is consulted before the buffer-list history for satisfying + `py-pdbtrack-grub-for-buffer', since it's the most often the likely + prospect as debugging continues.") + (make-variable-buffer-local 'py-pdbtrack-last-grubbed-buffer) (defvar py-pychecker-history nil) *************** *** 1380,1394 **** "Find most recent buffer itself named or having function funcname. ! Must have a least int(lineno) lines in it." (let ((buffers (buffer-list)) - ;(buffers (list (get-buffer "workflow_do_action.py"))) curbuf got) (while (and buffers (not got)) (setq buf (car buffers) buffers (cdr buffers)) ! (if (or (save-excursion (set-buffer buf) ! (string= major-mode "python-mode")) ! (and (string-match funcname (buffer-name buf)) (string-match (concat "^\\s-*\\(def\\|class\\)\\s-+" funcname "\\s-*(") --- 1387,1406 ---- "Find most recent buffer itself named or having function funcname. ! We first check the last buffer this function found, if any, then walk ! throught the buffer-list history for python-mode buffers that are ! named for funcname or define a function funcname." (let ((buffers (buffer-list)) curbuf got) + (if (and py-pdbtrack-last-grubbed-buffer + (member py-pdbtrack-last-grubbed-buffer buffers)) + ; Prefer last grubbed buffer by putting it at the front of the list: + (setq buffers (cons py-pdbtrack-last-grubbed-buffer buffers))) (while (and buffers (not got)) (setq buf (car buffers) buffers (cdr buffers)) ! (if (and (save-excursion (set-buffer buf) ! (string= major-mode "python-mode")) ! (or (string-match funcname (buffer-name buf)) (string-match (concat "^\\s-*\\(def\\|class\\)\\s-+" funcname "\\s-*(") *************** *** 1397,1401 **** buf)))) (setq got buf))) ! got)) (defun py-postprocess-output-buffer (buf) --- 1409,1413 ---- buf)))) (setq got buf))) ! (setq py-pdbtrack-last-grubbed-buffer got))) (defun py-postprocess-output-buffer (buf) From jvr@users.sourceforge.net Mon Mar 3 17:32:22 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Mon, 03 Mar 2003 09:32:22 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.686,1.687 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv13097/Misc Modified Files: NEWS Log Message: Patch #683592 revisited, after discussions with MvL: - Implement the behavior as specified in PEP 277, meaning os.listdir() will only return unicode strings if it is _called_ with a unicode argument. - And then return only unicode, don't attempt to convert to ASCII. - Don't switch on Py_FileSystemDefaultEncoding, but simply use the default encoding if Py_FileSystemDefaultEncoding is NULL. This means os.listdir() can now raise UnicodeDecodeError if the default encoding can't represent the directory entry. (This seems better than silcencing the error and fall back to a byte string.) - Attempted to decribe the above in Doc/lib/libos.tex. - Reworded the Misc/NEWS items to reflect the current situation. This checkin also fixes bug #696261, which was due to os.listdir() not using Py_FileSystemDefaultEncoding, like all file system calls are supposed to. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.686 retrieving revision 1.687 diff -C2 -d -r1.686 -r1.687 *** NEWS 3 Mar 2003 12:29:41 -0000 1.686 --- NEWS 3 Mar 2003 17:32:15 -0000 1.687 *************** *** 42,50 **** report . ! - os.listdir() now returns Unicode strings on platforms that set ! Py_FileSystemDefaultEncoding, for file names that are not representable ! in ASCII. (This currently only affects MacOS X; on Windows versions ! with wide file name support os.listdir() already returned Unicode ! strings.) - Distutils: both 'py_modules' and 'packages' keywords can now be specified --- 42,48 ---- report . ! - On Unix platforms, if os.listdir() is called with a Unicode argument, ! it now returns Unicode strings. (This behavior was added earlier ! to the Windows NT/2k/XP version of os.listdir().) - Distutils: both 'py_modules' and 'packages' keywords can now be specified *************** *** 89,94 **** --- ! - os.listdir() now may return Unicode strings on MacOS X. See the general ! news item under "Library". - A new method MacOS.WMAvailable() returns true if it is safe to access --- 87,92 ---- --- ! - os.listdir() now returns Unicode strings on MacOS X when called with ! a Unicode argument. See the general news item under "Library". - A new method MacOS.WMAvailable() returns true if it is safe to access From jvr@users.sourceforge.net Mon Mar 3 17:32:45 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Mon, 03 Mar 2003 09:32:45 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libos.tex,1.114,1.115 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv13097/Doc/lib Modified Files: libos.tex Log Message: Patch #683592 revisited, after discussions with MvL: - Implement the behavior as specified in PEP 277, meaning os.listdir() will only return unicode strings if it is _called_ with a unicode argument. - And then return only unicode, don't attempt to convert to ASCII. - Don't switch on Py_FileSystemDefaultEncoding, but simply use the default encoding if Py_FileSystemDefaultEncoding is NULL. This means os.listdir() can now raise UnicodeDecodeError if the default encoding can't represent the directory entry. (This seems better than silcencing the error and fall back to a byte string.) - Attempted to decribe the above in Doc/lib/libos.tex. - Reworded the Misc/NEWS items to reflect the current situation. This checkin also fixes bug #696261, which was due to os.listdir() not using Py_FileSystemDefaultEncoding, like all file system calls are supposed to. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.114 retrieving revision 1.115 diff -C2 -d -r1.114 -r1.115 *** libos.tex 14 Feb 2003 19:35:31 -0000 1.114 --- libos.tex 3 Mar 2003 17:32:12 -0000 1.115 *************** *** 712,717 **** Availability: Macintosh, \UNIX, Windows. ! \versionadded[On Windows NT/2k/XP, if \var{path} is a Unicode object, ! the result will be a list of Unicode objects.]{2.3} \end{funcdesc} --- 712,717 ---- Availability: Macintosh, \UNIX, Windows. ! \versionadded[On Windows NT/2k/XP and Unix, if \var{path} is a Unicode ! object, the result will be a list of Unicode objects.]{2.3} \end{funcdesc} From jvr@users.sourceforge.net Mon Mar 3 17:32:47 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Mon, 03 Mar 2003 09:32:47 -0800 Subject: [Python-checkins] python/dist/src/Modules posixmodule.c,2.287,2.288 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv13097/Modules Modified Files: posixmodule.c Log Message: Patch #683592 revisited, after discussions with MvL: - Implement the behavior as specified in PEP 277, meaning os.listdir() will only return unicode strings if it is _called_ with a unicode argument. - And then return only unicode, don't attempt to convert to ASCII. - Don't switch on Py_FileSystemDefaultEncoding, but simply use the default encoding if Py_FileSystemDefaultEncoding is NULL. This means os.listdir() can now raise UnicodeDecodeError if the default encoding can't represent the directory entry. (This seems better than silcencing the error and fall back to a byte string.) - Attempted to decribe the above in Doc/lib/libos.tex. - Reworded the Misc/NEWS items to reflect the current situation. This checkin also fixes bug #696261, which was due to os.listdir() not using Py_FileSystemDefaultEncoding, like all file system calls are supposed to. Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.287 retrieving revision 2.288 diff -C2 -d -r2.287 -r2.288 *** posixmodule.c 25 Feb 2003 21:42:15 -0000 2.287 --- posixmodule.c 3 Mar 2003 17:32:13 -0000 2.288 *************** *** 1776,1780 **** DIR *dirp; struct dirent *ep; ! if (!PyArg_ParseTuple(args, "s:listdir", &name)) return NULL; if ((dirp = opendir(name)) == NULL) { --- 1776,1786 ---- DIR *dirp; struct dirent *ep; ! int arg_is_unicode = 1; ! ! if (!PyArg_ParseTuple(args, "U:listdir", &v)) { ! arg_is_unicode = 0; ! PyErr_Clear(); ! } ! if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name)) return NULL; if ((dirp = opendir(name)) == NULL) { *************** *** 1797,1801 **** } #ifdef Py_USING_UNICODE ! if (Py_FileSystemDefaultEncoding != NULL) { PyObject *w; --- 1803,1807 ---- } #ifdef Py_USING_UNICODE ! if (arg_is_unicode) { PyObject *w; *************** *** 1810,1821 **** break; } - /* attempt to convert to ASCII */ - w = PyUnicode_AsASCIIString(v); - if (w != NULL) { - Py_DECREF(v); - v = w; - } - else - PyErr_Clear(); } #endif --- 1816,1819 ---- From akuchling@users.sourceforge.net Mon Mar 3 18:26:04 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 03 Mar 2003 10:26:04 -0800 Subject: [Python-checkins] python/dist/src/Lib/distutils/command register.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils/command In directory sc8-pr-cvs1:/tmp/cvs-serv13971 Modified Files: register.py Log Message: Improve description Index: register.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/command/register.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** register.py 19 Feb 2003 14:27:21 -0000 1.4 --- register.py 3 Mar 2003 18:26:01 -0000 1.5 *************** *** 16,20 **** class register(Command): ! description = "register the distribution with the repository" DEFAULT_REPOSITORY = 'http://www.python.org/pypi' --- 16,20 ---- class register(Command): ! description = ("register the distribution with the Python package index") DEFAULT_REPOSITORY = 'http://www.python.org/pypi' From akuchling@users.sourceforge.net Mon Mar 3 18:37:19 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 03 Mar 2003 10:37:19 -0800 Subject: [Python-checkins] python/dist/src/Lib/distutils/command __init__.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils/command In directory sc8-pr-cvs1:/tmp/cvs-serv17894 Modified Files: __init__.py Log Message: [Bug #69389] List register command in __all__, so setup.py --help-commands will now list it Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/command/__init__.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** __init__.py 19 Nov 2002 13:12:27 -0000 1.17 --- __init__.py 3 Mar 2003 18:37:16 -0000 1.18 *************** *** 20,23 **** --- 20,24 ---- 'install_data', 'sdist', + 'register', 'bdist', 'bdist_dumb', From jvr@users.sourceforge.net Mon Mar 3 19:07:16 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Mon, 03 Mar 2003 11:07:16 -0800 Subject: [Python-checkins] python/dist/src/Modules posixmodule.c,2.288,2.289 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv32165/Modules Modified Files: posixmodule.c Log Message: plugged leak noted by nnorwitz: the 'et' format returns allocated memory Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.288 retrieving revision 2.289 diff -C2 -d -r2.288 -r2.289 *** posixmodule.c 3 Mar 2003 17:32:13 -0000 2.288 --- posixmodule.c 3 Mar 2003 19:07:13 -0000 2.289 *************** *** 1772,1776 **** #else ! char *name; PyObject *d, *v; DIR *dirp; --- 1772,1776 ---- #else ! char *name = NULL; PyObject *d, *v; DIR *dirp; *************** *** 1785,1792 **** return NULL; if ((dirp = opendir(name)) == NULL) { ! return posix_error_with_filename(name); } if ((d = PyList_New(0)) == NULL) { closedir(dirp); return NULL; } --- 1785,1793 ---- return NULL; if ((dirp = opendir(name)) == NULL) { ! return posix_error_with_allocated_filename(name); } if ((d = PyList_New(0)) == NULL) { closedir(dirp); + PyMem_Free(name); return NULL; } *************** *** 1827,1830 **** --- 1828,1832 ---- } closedir(dirp); + PyMem_Free(name); return d; From akuchling@users.sourceforge.net Mon Mar 3 20:07:32 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 03 Mar 2003 12:07:32 -0800 Subject: [Python-checkins] python/dist/src/Lib/distutils dist.py,1.62,1.63 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory sc8-pr-cvs1:/tmp/cvs-serv25442 Modified Files: dist.py Log Message: [Bug #693470] 'licence' as an alias for 'license' doesn't work. This patch makes it work again. Index: dist.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/dist.py,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** dist.py 19 Feb 2003 14:16:01 -0000 1.62 --- dist.py 3 Mar 2003 20:07:27 -0000 1.63 *************** *** 206,209 **** --- 206,218 ---- opt_dict[opt] = ("setup script", val) + if attrs.has_key('licence'): + attrs['license'] = attrs['licence'] + del attrs['licence'] + msg = "'licence' distribution option is deprecated; use 'license'" + if warnings is not None: + warnings.warn(msg) + else: + sys.stderr.write(msg + "\n") + # Now work on the rest of the attributes. Any attribute that's # not already defined is invalid! *************** *** 967,971 **** "license", "description", "long_description", "keywords", "platforms", "fullname", "contact", ! "contact_email", "licence", "classifiers", "download_url") --- 976,980 ---- "license", "description", "long_description", "keywords", "platforms", "fullname", "contact", ! "contact_email", "license", "classifiers", "download_url") From nnorwitz@users.sourceforge.net Mon Mar 3 21:16:41 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 03 Mar 2003 13:16:41 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.687,1.688 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv30451/Misc Modified Files: NEWS Log Message: Fix SF #692416, don't crash interpreter for _tkinter.deletefilehandler in addition to createfilehandler and creaetetimerhandler. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.687 retrieving revision 1.688 diff -C2 -d -r1.687 -r1.688 *** NEWS 3 Mar 2003 17:32:15 -0000 1.687 --- NEWS 3 Mar 2003 21:16:38 -0000 1.688 *************** *** 25,28 **** --- 25,32 ---- ----------------- + - Using createfilehandler, deletefilehandler, createtimerhandler functions + on Tkinter.tkinter (_tkinter module) no longer crashes the interpreter. + See SF bug #692416. + - Modified the fcntl.ioctl() function to allow modification of a passed mutable buffer (for details see the reference documentation). From nnorwitz@users.sourceforge.net Mon Mar 3 21:16:42 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Mon, 03 Mar 2003 13:16:42 -0800 Subject: [Python-checkins] python/dist/src/Modules _tkinter.c,1.150,1.151 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv30451/Modules Modified Files: _tkinter.c Log Message: Fix SF #692416, don't crash interpreter for _tkinter.deletefilehandler in addition to createfilehandler and creaetetimerhandler. Index: _tkinter.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v retrieving revision 1.150 retrieving revision 1.151 diff -C2 -d -r1.150 -r1.151 *** _tkinter.c 3 Mar 2003 10:40:01 -0000 1.150 --- _tkinter.c 3 Mar 2003 21:16:39 -0000 1.151 *************** *** 2244,2248 **** if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file)) return NULL; ! CHECK_TCL_APPARTMENT; tfile = PyObject_AsFileDescriptor(file); if (tfile < 0) --- 2244,2260 ---- if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file)) return NULL; ! ! if (!self && !tcl_lock) { ! /* We don't have the Tcl lock since Tcl is threaded. */ ! PyErr_SetString(PyExc_RuntimeError, ! "_tkinter.deletefilehandler not supported " ! "for threaded Tcl"); ! return NULL; ! } ! ! if (self) { ! CHECK_TCL_APPARTMENT; ! } ! tfile = PyObject_AsFileDescriptor(file); if (tfile < 0) From tim_one@users.sourceforge.net Tue Mar 4 00:26:43 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Mon, 03 Mar 2003 16:26:43 -0800 Subject: [Python-checkins] python/dist/src/Lib/test regrtest.py,1.132,1.133 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv17965/Lib/test Modified Files: regrtest.py Log Message: test_ioctl is an expected skip on Windows. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.132 retrieving revision 1.133 diff -C2 -d -r1.132 -r1.133 *** regrtest.py 28 Feb 2003 19:53:32 -0000 1.132 --- regrtest.py 4 Mar 2003 00:26:38 -0000 1.133 *************** *** 568,571 **** --- 568,572 ---- test_iconv_codecs test_imgfile + test_ioctl test_largefile test_linuxaudiodev From niemeyer@users.sourceforge.net Tue Mar 4 00:50:26 2003 From: niemeyer@users.sourceforge.net (niemeyer@users.sourceforge.net) Date: Mon, 03 Mar 2003 16:50:26 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.337.2.4.2.64,1.337.2.4.2.65 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv25505/Misc Modified Files: Tag: release22-maint NEWS Log Message: Backported fix to [521782] unreliable file.read() error handling. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.337.2.4.2.64 retrieving revision 1.337.2.4.2.65 diff -C2 -d -r1.337.2.4.2.64 -r1.337.2.4.2.65 *** NEWS 1 Mar 2003 02:14:52 -0000 1.337.2.4.2.64 --- NEWS 4 Mar 2003 00:50:23 -0000 1.337.2.4.2.65 *************** *** 296,299 **** --- 296,302 ---- class than for instances of that class. + - Fixed bug #521782: when a file was in non-blocking mode, file.read() + could silently lose data or wrongly throw an unknown error. + Extension modules From niemeyer@users.sourceforge.net Tue Mar 4 00:50:27 2003 From: niemeyer@users.sourceforge.net (niemeyer@users.sourceforge.net) Date: Mon, 03 Mar 2003 16:50:27 -0800 Subject: [Python-checkins] python/dist/src/Objects fileobject.c,2.141.6.6,2.141.6.7 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv25505/Objects Modified Files: Tag: release22-maint fileobject.c Log Message: Backported fix to [521782] unreliable file.read() error handling. Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.141.6.6 retrieving revision 2.141.6.7 diff -C2 -d -r2.141.6.6 -r2.141.6.7 *** fileobject.c 25 Sep 2002 18:06:48 -0000 2.141.6.6 --- fileobject.c 4 Mar 2003 00:50:24 -0000 2.141.6.7 *************** *** 569,572 **** --- 569,586 ---- } + #if defined(EWOULDBLOCK) && defined(EAGAIN) && EWOULDBLOCK != EAGAIN + #define BLOCKED_ERRNO(x) ((x) == EWOULDBLOCK || (x) == EAGAIN) + #else + #ifdef EWOULDBLOCK + #define BLOCKED_ERRNO(x) ((x) == EWOULDBLOCK) + #else + #ifdef EAGAIN + #define BLOCKED_ERRNO(x) ((x) == EAGAIN) + #else + #define BLOCKED_ERRNO(x) 0 + #endif + #endif + #endif + static PyObject * file_read(PyFileObject *f, PyObject *args) *************** *** 602,617 **** if (!ferror(f->f_fp)) break; - PyErr_SetFromErrno(PyExc_IOError); clearerr(f->f_fp); Py_DECREF(v); return NULL; } bytesread += chunksize; ! if (bytesread < buffersize) break; if (bytesrequested < 0) { buffersize = new_buffersize(f, buffersize); if (_PyString_Resize(&v, buffersize) < 0) return NULL; } } --- 616,642 ---- if (!ferror(f->f_fp)) break; clearerr(f->f_fp); + /* When in non-blocking mode, data shouldn't + * be discarded if a blocking signal was + * received. That will also happen if + * chunksize != 0, but bytesread < buffersize. */ + if (bytesread > 0 && BLOCKED_ERRNO(errno)) + break; + PyErr_SetFromErrno(PyExc_IOError); Py_DECREF(v); return NULL; } bytesread += chunksize; ! if (bytesread < buffersize) { ! clearerr(f->f_fp); break; + } if (bytesrequested < 0) { buffersize = new_buffersize(f, buffersize); if (_PyString_Resize(&v, buffersize) < 0) return NULL; + } else { + /* Got what was requested. */ + break; } } *************** *** 1322,1326 **** "read([size]) -> read at most size bytes, returned as a string.\n" "\n" ! "If the size argument is negative or omitted, read until EOF is reached."; static char write_doc[] = --- 1347,1353 ---- "read([size]) -> read at most size bytes, returned as a string.\n" "\n" ! "If the size argument is negative or omitted, read until EOF is reached.\n" ! "Notice that when in non-blocking mode, less data than what was requested\n" ! "may be returned, even if no size parameter was given."; static char write_doc[] = From niemeyer@users.sourceforge.net Tue Mar 4 00:50:55 2003 From: niemeyer@users.sourceforge.net (niemeyer@users.sourceforge.net) Date: Mon, 03 Mar 2003 16:50:55 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libstdtypes.tex,1.80.6.19,1.80.6.20 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv25505/Doc/lib Modified Files: Tag: release22-maint libstdtypes.tex Log Message: Backported fix to [521782] unreliable file.read() error handling. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.80.6.19 retrieving revision 1.80.6.20 diff -C2 -d -r1.80.6.19 -r1.80.6.20 *** libstdtypes.tex 17 Feb 2003 18:59:54 -0000 1.80.6.19 --- libstdtypes.tex 4 Mar 2003 00:50:20 -0000 1.80.6.20 *************** *** 1164,1168 **** an \EOF{} is hit.) Note that this method may call the underlying C function \cfunction{fread()} more than once in an effort to ! acquire as close to \var{size} bytes as possible. \end{methoddesc} --- 1164,1170 ---- an \EOF{} is hit.) Note that this method may call the underlying C function \cfunction{fread()} more than once in an effort to ! acquire as close to \var{size} bytes as possible. Also note that ! when in non-blocking mode, less data than what was requested may ! be returned, even if no \var{size} parameter was given. \end{methoddesc} From jackjansen@users.sourceforge.net Tue Mar 4 10:52:41 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 04 Mar 2003 02:52:41 -0800 Subject: [Python-checkins] python/dist/src Makefile.pre.in,1.115,1.116 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv2738 Modified Files: Makefile.pre.in Log Message: Patch #696613 by Ben Laurie: use "test -L" to test for symlinks in stead of the older (and, according to some manpages, deprecated) "test -h". Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.115 retrieving revision 1.116 diff -C2 -d -r1.115 -r1.116 *** Makefile.pre.in 27 Feb 2003 23:19:46 -0000 1.115 --- Makefile.pre.in 4 Mar 2003 10:52:39 -0000 1.116 *************** *** 564,568 **** # Install the interpreter (by creating a hard link to python$(VERSION)) bininstall: altbininstall ! -if test -f $(BINDIR)/$(PYTHON) -o -L $(BINDIR)/$(PYTHON); \ then rm -f $(BINDIR)/$(PYTHON); \ else true; \ --- 564,568 ---- # Install the interpreter (by creating a hard link to python$(VERSION)) bininstall: altbininstall ! -if test -f $(BINDIR)/$(PYTHON) -o -h $(BINDIR)/$(PYTHON); \ then rm -f $(BINDIR)/$(PYTHON); \ else true; \ From akuchling@users.sourceforge.net Tue Mar 4 14:07:55 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Tue, 04 Mar 2003 06:07:55 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libre.tex,1.93,1.94 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv16125 Modified Files: libre.tex Log Message: [bug #696771] Remove misleading parenthetical aside Index: libre.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libre.tex,v retrieving revision 1.93 retrieving revision 1.94 diff -C2 -d -r1.93 -r1.94 *** libre.tex 3 Dec 2002 18:49:17 -0000 1.93 --- libre.tex 4 Mar 2003 14:07:51 -0000 1.94 *************** *** 314,319 **** is 0, or \var{number} is 3 octal digits long, it will not be interpreted as a group match, but as the character with octal value \var{number}. - (There is a group 0, which is the entire matched pattern, but it can't - be referenced with \regexp{\e 0}; instead, use \regexp{\e g<0>}.) Inside the \character{[} and \character{]} of a character class, all numeric escapes are treated as characters. --- 314,317 ---- From akuchling@users.sourceforge.net Tue Mar 4 14:12:28 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Tue, 04 Mar 2003 06:12:28 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libre.tex,1.94,1.95 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv17967 Modified Files: libre.tex Log Message: [bug #692016] update description of {m,n} modifier; you can omit the lower bound Index: libre.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libre.tex,v retrieving revision 1.94 retrieving revision 1.95 diff -C2 -d -r1.94 -r1.95 *** libre.tex 4 Mar 2003 14:07:51 -0000 1.94 --- libre.tex 4 Mar 2003 14:12:24 -0000 1.95 *************** *** 130,136 **** \var{m} to \var{n} repetitions of the preceding RE, attempting to match as many repetitions as possible. For example, \regexp{a\{3,5\}} ! will match from 3 to 5 \character{a} characters. Omitting \var{n} ! specifies an infinite upper bound; you can't omit \var{m}. As an ! example, \regexp{a\{4,\}b} will match \code{aaaab}, a thousand \character{a} characters followed by a \code{b}, but not \code{aaab}. The comma may not be omitted or the modifier would be confused with --- 130,137 ---- \var{m} to \var{n} repetitions of the preceding RE, attempting to match as many repetitions as possible. For example, \regexp{a\{3,5\}} ! will match from 3 to 5 \character{a} characters. Omitting \var{m} ! specifies a lower bound of zero, ! and omitting \var{n} specifies an infinite upper bound. As an ! example, \regexp{a\{4,\}b} will match \code{aaaab} or a thousand \character{a} characters followed by a \code{b}, but not \code{aaab}. The comma may not be omitted or the modifier would be confused with From akuchling@users.sourceforge.net Tue Mar 4 14:17:09 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Tue, 04 Mar 2003 06:17:09 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libre.tex,1.95,1.96 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv19475 Modified Files: libre.tex Log Message: Weaken recommendation of Friedl book; fix reference Index: libre.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libre.tex,v retrieving revision 1.95 retrieving revision 1.96 diff -C2 -d -r1.95 -r1.96 *** libre.tex 4 Mar 2003 14:12:24 -0000 1.95 --- libre.tex 4 Mar 2003 14:17:05 -0000 1.96 *************** *** 36,42 **** \begin{seealso} \seetitle{Mastering Regular Expressions}{Book on regular expressions ! by Jeffrey Friedl, published by O'Reilly. The Python ! material in this book dates from before the \refmodule{re} ! module, but it covers writing good regular expression patterns in great detail.} \end{seealso} --- 36,42 ---- \begin{seealso} \seetitle{Mastering Regular Expressions}{Book on regular expressions ! by Jeffrey Friedl, published by O'Reilly. The second ! edition of the book no longer covers Python at all, ! but the first edition covered writing good regular expression patterns in great detail.} \end{seealso} *************** *** 59,63 **** expressions like the ones described here. For details of the theory and implementation of regular expressions, consult the Friedl book ! referenced below, or almost any textbook about compiler construction. A brief explanation of the format of regular expressions follows. For --- 59,63 ---- expressions like the ones described here. For details of the theory and implementation of regular expressions, consult the Friedl book ! referenced above, or almost any textbook about compiler construction. A brief explanation of the format of regular expressions follows. For From nnorwitz@users.sourceforge.net Tue Mar 4 17:44:38 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 04 Mar 2003 09:44:38 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libstring.tex,1.45.8.3,1.45.8.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv17613 Modified Files: Tag: release22-maint libstring.tex Log Message: SF bug #697220, string.strip implementation/doc mismatch Index: libstring.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstring.tex,v retrieving revision 1.45.8.3 retrieving revision 1.45.8.4 diff -C2 -d -r1.45.8.3 -r1.45.8.4 *** libstring.tex 12 Sep 2002 14:16:31 -0000 1.45.8.3 --- libstring.tex 4 Mar 2003 17:44:34 -0000 1.45.8.4 *************** *** 260,263 **** --- 260,265 ---- must be a string; the characters in the string will be stripped from the both ends of the string this method is called on. + \versionchanged[The \var{chars} parameter was added. The \var{chars} + parameter cannot be passed in 2.2 or 2.2.1]{2.2.2} \end{funcdesc} From jvr@users.sourceforge.net Tue Mar 4 19:30:49 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Tue, 04 Mar 2003 11:30:49 -0800 Subject: [Python-checkins] python/dist/src/Modules posixmodule.c,2.289,2.290 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv977/Modules Modified Files: posixmodule.c Log Message: os.listdir(): Fall back to the original byte string if conversion to unicode fails, as discussed in patch #683592. Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.289 retrieving revision 2.290 diff -C2 -d -r2.289 -r2.290 *** posixmodule.c 3 Mar 2003 19:07:13 -0000 2.289 --- posixmodule.c 4 Mar 2003 19:30:44 -0000 2.290 *************** *** 1810,1819 **** Py_FileSystemDefaultEncoding, "strict"); ! Py_DECREF(v); ! v = w; ! if (v == NULL) { ! Py_DECREF(d); ! d = NULL; ! break; } } --- 1810,1821 ---- Py_FileSystemDefaultEncoding, "strict"); ! if (w != NULL) { ! Py_DECREF(v); ! v = w; ! } ! else { ! /* fall back to the original byte string, as ! discussed in patch #683592 */ ! PyErr_Clear(); } } From akuchling@users.sourceforge.net Tue Mar 4 19:35:45 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Tue, 04 Mar 2003 11:35:45 -0800 Subject: [Python-checkins] python/dist/src/Doc/dist dist.tex,1.50,1.51 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/dist In directory sc8-pr-cvs1:/tmp/cvs-serv4014 Modified Files: dist.tex Log Message: Point e-mail address at the SIG Index: dist.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/dist/dist.tex,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -d -r1.50 -r1.51 *** dist.tex 26 Feb 2003 18:58:46 -0000 1.50 --- dist.tex 4 Mar 2003 19:35:40 -0000 1.51 *************** *** 12,16 **** \author{Greg Ward} ! \authoraddress{Email: \email{gward@python.net}} \makeindex --- 12,16 ---- \author{Greg Ward} ! \authoraddress{Email: \email{distutils-sig@python.org}} \makeindex From akuchling@users.sourceforge.net Tue Mar 4 19:36:16 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Tue, 04 Mar 2003 11:36:16 -0800 Subject: [Python-checkins] python/dist/src/Doc/inst inst.tex,1.46,1.47 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/inst In directory sc8-pr-cvs1:/tmp/cvs-serv4217 Modified Files: inst.tex Log Message: Point e-mail address at the SIG Index: inst.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/inst/inst.tex,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -d -r1.46 -r1.47 *** inst.tex 27 Nov 2002 13:34:20 -0000 1.46 --- inst.tex 4 Mar 2003 19:36:11 -0000 1.47 *************** *** 18,22 **** \author{Greg Ward} ! \authoraddress{Email: \email{gward@python.net}} \makeindex --- 18,22 ---- \author{Greg Ward} ! \authoraddress{Email: \email{distutils-sig@python.org}} \makeindex From jackjansen@users.sourceforge.net Wed Mar 5 09:37:23 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Mar 2003 01:37:23 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSXResources/app/Resources Applet-Info.plist,1.2,NONE Applet-InfoPlist.strings,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources In directory sc8-pr-cvs1:/tmp/cvs-serv3466 Removed Files: Applet-Info.plist Applet-InfoPlist.strings Log Message: These are no longer used. --- Applet-Info.plist DELETED --- --- Applet-InfoPlist.strings DELETED --- From loewis@users.sourceforge.net Wed Mar 5 14:15:30 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 05 Mar 2003 06:15:30 -0800 Subject: [Python-checkins] python/dist/src/Modules getbuildinfo.c,2.9,2.10 main.c,1.72,1.73 posixmodule.c,2.290,2.291 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv26905 Modified Files: getbuildinfo.c main.c posixmodule.c Log Message: Patch #696645: Remove VMS code with uncertain authorship. Index: getbuildinfo.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/getbuildinfo.c,v retrieving revision 2.9 retrieving revision 2.10 diff -C2 -d -r2.9 -r2.10 *** getbuildinfo.c 6 Dec 2002 12:48:49 -0000 2.9 --- getbuildinfo.c 5 Mar 2003 14:15:18 -0000 2.10 *************** *** 29,97 **** #endif - #ifdef __VMS - # ifdef __DECC - # pragma extern_model save - # pragma extern_model strict_refdef - extern long ctl$gl_imghdrbf; - # pragma extern_model restore - # endif - - # ifdef __ALPHA - # define EIHD$L_IMGIDOFF 24 - # define EIHI$Q_LINKTIME 8 - # define _IMGIDOFF EIHD$L_IMGIDOFF - # define _LINKTIME EIHI$Q_LINKTIME - # else - # define IHD$W_IMGIDOFF 6 - # define IHI$Q_LINKTIME 56 - # define _IMGIDOFF IHD$W_IMGIDOFF - # define _LINKTIME IHI$Q_LINKTIME - # endif /* __VMS */ - - long* - vms__get_linktime (void) - { - long* al_imghdrbf; - unsigned short* aw_imgidoff; - unsigned short w_imgidoff; - long* aq_linktime; - unsigned char* ab_ihi; - - al_imghdrbf = &ctl$gl_imghdrbf; - - al_imghdrbf = (long *)*al_imghdrbf; - al_imghdrbf = (long *)*al_imghdrbf; - - aw_imgidoff = (unsigned short *) - ((unsigned char *)al_imghdrbf + _IMGIDOFF); - - w_imgidoff = *aw_imgidoff; - - ab_ihi = (unsigned char *)al_imghdrbf + w_imgidoff; - - aq_linktime = (long *) (ab_ihi + _LINKTIME); - - return aq_linktime; - } /* vms__get_linktime (void) */ - extern void vms__cvt_v2u_time (long * aq_vmstime, time_t * al_unixtime); - /* input , output */ - #endif /* __VMS */ - - const char * Py_GetBuildInfo(void) { static char buildinfo[50]; - #ifdef __VMS - time_t l_unixtime; - - vms__cvt_v2u_time(vms__get_linktime (), &l_unixtime ); - - memset(buildinfo, 0, 40); - sprintf(buildinfo, "#%d, %.24s", BUILD, ctime (&l_unixtime)); - #else PyOS_snprintf(buildinfo, sizeof(buildinfo), "#%d, %.20s, %.9s", BUILD, DATE, TIME); - #endif return buildinfo; } --- 29,38 ---- Index: main.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v retrieving revision 1.72 retrieving revision 1.73 diff -C2 -d -r1.72 -r1.73 *** main.c 23 Dec 2002 21:03:36 -0000 1.72 --- main.c 5 Mar 2003 14:15:19 -0000 1.73 *************** *** 6,11 **** #ifdef __VMS ! extern int PyVMS_init(int* pvi_argc, char*** pvi_argv); ! extern PyObject* pyvms_gr_empty_string; #endif --- 6,10 ---- #ifdef __VMS ! #include #endif *************** *** 306,310 **** --- 305,316 ---- strcmp(argv[_PyOS_optind], "-") != 0) { + #ifdef __VMS + filename = decc$translate_vms(argv[_PyOS_optind]); + if (filename == (char *)0 || filename == (char *)-1) + filename = argv[_PyOS_optind]; + + #else filename = argv[_PyOS_optind]; + #endif if (filename != NULL) { if ((fp = fopen(filename, "r")) == NULL) { *************** *** 371,411 **** Py_SetProgramName(argv[0]); - #ifdef __VMS - PyVMS_init(&argc, &argv); - #endif Py_Initialize(); - #ifdef __VMS - /* create an empty string object */ - pyvms_gr_empty_string = Py_BuildValue("s#", Py_None, (unsigned int)0); - #endif - if (Py_VerboseFlag || (command == NULL && filename == NULL && stdin_is_interactive)) - #ifndef __VMS fprintf(stderr, "Python %s on %s\n%s\n", Py_GetVersion(), Py_GetPlatform(), COPYRIGHT); - #else - fprintf(stderr, "Python %s on %s %s (%s_float)\n%s\n", - Py_GetVersion(), Py_GetPlatform(), - # ifdef __ALPHA - "Alpha", - # else - "VAX", - # endif - # if __IEEE_FLOAT - "T", - # else - # if __D_FLOAT - "D", - # else - # if __G_FLOAT - "G", - # endif /* __G_FLOAT */ - # endif /* __D_FLOAT */ - # endif /* __IEEE_FLOAT */ - COPYRIGHT); /* << @@ defined above in this file */ - /* Py_GetCopyright()); */ - #endif /* __VMS */ if (command != NULL) { --- 377,386 ---- Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.290 retrieving revision 2.291 diff -C2 -d -r2.290 -r2.291 *** posixmodule.c 4 Mar 2003 19:30:44 -0000 2.290 --- posixmodule.c 5 Mar 2003 14:15:21 -0000 2.291 *************** *** 29,44 **** # include # include - /* ----- */ - /* DECC on Alpha does redefine these already */ - # ifndef shell$from_vms - # define shell$from_vms(_p1_,_p2_,_p3_) decc$from_vms(_p1_,_p2_,_p3_) - # endif - # ifndef shell$translate_vms - # define shell$translate_vms(_p1_) decc$translate_vms(_p1_) - # endif - # ifndef shell$to_vms - # define shell$to_vms(_p1_,_p2_,_p3_,_p4_,_p5_) \ - decc$to_vms(_p1_,_p2_,_p3_,_p4_,_p5_) - # endif # include /* define wait() */ #endif /* defined(__VMS) */ --- 29,32 ---- *************** *** 148,152 **** #define HAVE_WAIT 1 #define HAVE_TTYNAME 1 ! #endif /* PYOS_OS2 && PYCC_GCC */ #endif /* _MSC_VER */ #endif /* __BORLANDC__ */ --- 136,140 ---- #define HAVE_WAIT 1 #define HAVE_TTYNAME 1 ! #endif /* PYOS_OS2 && PYCC_GCC && __VMS */ #endif /* _MSC_VER */ #endif /* __BORLANDC__ */ *************** *** 337,488 **** #if defined(__VMS) - static char psxmod_gt_psxpath[1026]; - - static int - psxmod_from_vms_action (char *spec) - { - (void)strcpy(psxmod_gt_psxpath, spec); - return 1; - } - - /* Return a dictionary corresponding to the VMS 'environment table' */ - static char* at_home = "HOME"; - static char* at_path = "PATH"; - - static char psxmod_t_command [] = "SYS$COMMAND"; /* add some values to provide a similar environment like POSIX */ void ! psmmod_add_posix_env(PyObject *d) { - /* -------------------- */ - struct dsc$descriptor_s r_device_name; - long l_devbufsiz; - long l_tt_page; - long l_item_code; - long l_status; PyObject *o; ! struct dsc$descriptor_s r_resultant_string; ! char t_resultant_string[13]; /* enough space for username (12)+ '\0' */ ! char *at_resultant_string; ! short int w_resultant_length; ! ! /* set up string descriptor */ ! r_device_name.dsc$w_length = strlen(psxmod_t_command); ! r_device_name.dsc$b_dtype = DSC$K_DTYPE_T; ! r_device_name.dsc$b_class = DSC$K_CLASS_S; ! r_device_name.dsc$a_pointer = &psxmod_t_command[0]; ! ! /* -------------------- */ ! /* COLUMNS = $getdvi("SYS$COMMAND","DEVBUFSIZ") */ ! l_item_code = DVI$_DEVBUFSIZ; ! l_status = lib$getdvi(&l_item_code, ! 0, /* [channel] */ ! &r_device_name, ! &l_devbufsiz, /* integer-value */ ! 0, /* resultant_string */ ! 0); /* resultant_length */ ! if (l_status == SS$_NORMAL) { ! /* create a string object here to comply with POSIX */ ! ! /* set up string descriptor */ ! r_resultant_string.dsc$w_length = ! (sizeof(t_resultant_string) - 1); /* ommit '\0' at end */ ! r_resultant_string.dsc$b_dtype = DSC$K_DTYPE_T; ! r_resultant_string.dsc$b_class = DSC$K_CLASS_S; ! r_resultant_string.dsc$a_pointer = &t_resultant_string[0]; ! ! /* Convert Signed Integer to Decimal Text */ ! l_status = ots$cvt_l_ti(&l_devbufsiz, &r_resultant_string, 1, ! 4, 0); ! if (l_status == SS$_NORMAL) { ! /* terminate string for 'C'-style */ ! t_resultant_string[sizeof(t_resultant_string)-1] = '\0'; ! /* string appears as: ' value' -- skip ' ' */ ! at_resultant_string = &t_resultant_string[0]; ! while ((*at_resultant_string == ' ' ) && ! (*at_resultant_string != '\0')) { ! at_resultant_string++; /* skip prefix spaces */ ! } ! ! o = Py_BuildValue("s", at_resultant_string); ! if (o != NULL) { ! (void) PyDict_SetItemString(d, "COLUMNS", o); ! Py_DECREF(o); ! } ! } /* (l_status = ots$cvt_l_ti() == SS$_NORMAL) */ ! } /* (l_status = lib$getdvi(DVI$_DEVBUFSIZ) == SS$_NORMAL) */ ! /* LINES = $getdvi("SYS$COMMAND","TT_PAGE") */ ! l_item_code = DVI$_TT_PAGE; ! l_status = lib$getdvi(&l_item_code, ! 0, /* [channel] */ ! &r_device_name, ! &l_tt_page, /* integer-value */ ! 0, /* resultant_string */ ! 0); /* resultant_length */ ! if (l_status == SS$_NORMAL) { ! /* create a string object here to comply with POSIX */ ! ! /* set up string descriptor */ ! r_resultant_string.dsc$w_length = ! (sizeof(t_resultant_string) - 1); /* ommit '\0' at end */ ! r_resultant_string.dsc$b_dtype = DSC$K_DTYPE_T; ! r_resultant_string.dsc$b_class = DSC$K_CLASS_S; ! r_resultant_string.dsc$a_pointer = &t_resultant_string[0]; ! ! /* Convert Signed Integer to Decimal Text */ ! l_status = ots$cvt_l_ti(&l_tt_page, &r_resultant_string, ! 1, 4, 0); ! if (l_status == SS$_NORMAL) { ! /* terminate string for 'C'-style */ ! t_resultant_string[sizeof(t_resultant_string)-1] = '\0'; ! /* string appears as: ' value' -- skip ' ' */ ! at_resultant_string = &t_resultant_string[0]; ! while ((*at_resultant_string == ' ' ) && ! (*at_resultant_string != '\0')) { ! at_resultant_string++; /* skip prefix spaces */ ! } ! ! o = Py_BuildValue("s", at_resultant_string); ! if (o != NULL) { ! (void)PyDict_SetItemString(d, "LINES", o); ! Py_DECREF(o); ! } ! } /* (l_status = ots$cvt_l_ti() == SS$_NORMAL) */ ! } /* (l_status = lib$getdvi(DVI$_TT_PAGE) == SS$_NORMAL) */ ! /* else -- ignore error */ ! ! /* LOGNAME = $getjpi(0,"USERNAME") */ ! l_item_code = JPI$_USERNAME; ! /* set up string descriptor */ ! r_resultant_string.dsc$w_length = ! (sizeof(t_resultant_string) - 1); /* ommit '\0' at end */ ! r_resultant_string.dsc$b_dtype = DSC$K_DTYPE_T; ! r_resultant_string.dsc$b_class = DSC$K_CLASS_S; ! r_resultant_string.dsc$a_pointer = &t_resultant_string[0]; ! l_status = lib$getjpi(&l_item_code, 0, 0, 0, ! &r_resultant_string, &w_resultant_length); ! if (l_status == SS$_NORMAL){ ! t_resultant_string[w_resultant_length] = '\0'; ! /* remove any trailing spaces by replacing 1st one with '\0' */ ! at_resultant_string = &t_resultant_string[0]; ! while ((*at_resultant_string != ' ' ) && ! (*at_resultant_string != '\0')) { ! /* lowercase for compatibility with POSIX */ ! *at_resultant_string = tolower(*at_resultant_string); ! at_resultant_string++; /* skip non-blank */ ! } ! *at_resultant_string = '\0'; /* terminate */ ! o = Py_BuildValue("s", &t_resultant_string[0]); ! if (o != NULL) { ! (void) PyDict_SetItemString(d, "LOGNAME", o); ! (void) PyDict_SetItemString(d, "USERNAME", o); ! Py_DECREF(o); ! } ! } /* (l_status == SS$_NORMAL) */ /* OS = "OpenVMS" */ o = PyString_FromString ("OpenVMS"); --- 325,375 ---- #if defined(__VMS) /* add some values to provide a similar environment like POSIX */ + static void ! vms_add_posix_env(PyObject *d) { PyObject *o; ! char* str; ! str = getenv("LINES"); ! o = Py_BuildValue("s", str); ! if (o != NULL) { ! (void)PyDict_SetItemString(d, "LINES", o); ! Py_DECREF(o); ! } ! str = getenv("COLUMNS"); ! o = Py_BuildValue("s", str); ! if (o != NULL) { ! (void)PyDict_SetItemString(d, "COLUMNS", o); ! Py_DECREF(o); ! } ! str = getenv("USER"); ! o = Py_BuildValue("s", str); ! if (o != NULL) { ! (void)PyDict_SetItemString(d, "USERNAME", o); ! Py_DECREF(o); ! } ! o = Py_BuildValue("s", str); ! if (o != NULL) { ! (void)PyDict_SetItemString(d, "LOGNAME", o); ! Py_DECREF(o); ! } ! str = getenv("HOME"); ! o = Py_BuildValue("s", str); ! if (o != NULL) { ! (void)PyDict_SetItemString(d, "HOME", o); ! Py_DECREF(o); ! } + str = getenv("PATH"); + o = Py_BuildValue("s", str); + if (o != NULL) { + (void)PyDict_SetItemString(d, "PATH", o); + Py_DECREF(o); + } /* OS = "OpenVMS" */ o = PyString_FromString ("OpenVMS"); *************** *** 492,529 **** } } - - /* @@ posix env: - COLUMNS=80 $ write sys$output f$getdvi("SYS$COMMAND","DEVBUFSIZ") - LINES=47 $ write sys$output f$getdvi("SYS$COMMAND","TT_PAGE") - LOGNAME=zessin $ write sys$output f$edit(f$getjpi(0,"username"), - - "collapse,lowercase") - OS=OpenVMS - PS1=HERE $ - - TZ=CET-1:00CET DST,M3.5.0/2:00,M10.5.0/3:00 - $ write sys$output f$trnlnm("POSIX$DEFAULT_TZ") - "CET-1:00CET DST-2:00,M3.5.0/2:00,M10.5.0/3:00" - $ write sys$output f$trnlnm("UCX$TZ") - "MET-1MET_DST-2,M3.5.0/2,M10.5.0/3" - PAGER=more - TERM=vt300_series - SHELL=/bin/sh - HOME=/dka100/user/zessin - _=/bin/env - - >>> for v in os.environ.items(): - ... print v - ... - ('HOME', '/user_here/zessin') - ('COLUMNS', '80') - ('LINES', '24') - ('PATH', '/python_disk/python/python-1_5_2/vms') - ('OS', 'OpenVMS') - ('USER', 'ZESSIN') - ('LOGNAME', 'zessin') - ('TERM', 'vt300-80') - ('USERNAME', 'zessin') - >>> - */ #endif /* __VMS */ --- 379,382 ---- *************** *** 554,570 **** continue; } - #if defined(__VMS) - if ((strncmp(at_home, *e, sizeof(at_home)) == 0) || - (strncmp(at_path, *e, sizeof(at_path)) == 0)) { - (void)shell$from_vms(p+1, psxmod_from_vms_action, 0); - /* 0 = no wildcard expansion */ - v = PyString_FromString(psxmod_gt_psxpath); - } - else { - v = PyString_FromString(p+1); - } - #else v = PyString_FromString(p+1); - #endif if (v == NULL) { PyErr_Clear(); --- 407,411 ---- *************** *** 580,586 **** } #if defined(__VMS) ! psmmod_add_posix_env(d); ! #endif /* defined(__VMS) */ ! #if defined(PYOS_OS2) { APIRET rc; --- 421,426 ---- } #if defined(__VMS) ! vms_add_posix_env(d); ! #elif defined(PYOS_OS2) { APIRET rc; *************** *** 1341,1346 **** #elif defined(PYOS_OS2) && defined(PYCC_GCC) return posix_1str(args, "et:chdir", _chdir2, NULL, NULL); ! #else ! #ifdef __VMS return posix_1str(args, "et:chdir", (int (*)(const char *))chdir, NULL, NULL); --- 1181,1185 ---- #elif defined(PYOS_OS2) && defined(PYCC_GCC) return posix_1str(args, "et:chdir", _chdir2, NULL, NULL); ! #elif defined(__VMS) return posix_1str(args, "et:chdir", (int (*)(const char *))chdir, NULL, NULL); *************** *** 1348,1352 **** return posix_1str(args, "et:chdir", chdir, NULL, NULL); #endif - #endif } --- 1187,1190 ---- *************** *** 1500,1505 **** #if defined(PYOS_OS2) && defined(PYCC_GCC) res = _getcwd2(buf, sizeof buf); ! #else ! #if defined(__VMS) /* 0 = force Unix-style path if in the VMS DCL environment! */ res = getcwd(buf, sizeof buf, 0); --- 1338,1342 ---- #if defined(PYOS_OS2) && defined(PYCC_GCC) res = _getcwd2(buf, sizeof buf); ! #elif defined(__VMS) /* 0 = force Unix-style path if in the VMS DCL environment! */ res = getcwd(buf, sizeof buf, 0); *************** *** 1507,1511 **** res = getcwd(buf, sizeof buf); #endif - #endif Py_END_ALLOW_THREADS if (res == NULL) --- 1344,1347 ---- *************** *** 1541,1544 **** --- 1377,1383 ---- #if defined(PYOS_OS2) && defined(PYCC_GCC) res = _getcwd2(buf, sizeof buf); + #elif defined(__VMS) + /* 0 = force Unix-style path if in the VMS DCL environment! */ + res = getcwd(buf, sizeof buf, 0); #else res = getcwd(buf, sizeof buf); *************** *** 5339,5342 **** --- 5178,5185 ---- if (!PyArg_ParseTuple(args, "i:fstat", &fd)) return NULL; + #ifdef __VMS + /* on OpenVMS we must ensure that all bytes are written to the file */ + fsync(fd); + #endif Py_BEGIN_ALLOW_THREADS res = FSTAT(fd, &st); From mwh@users.sourceforge.net Wed Mar 5 14:21:03 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Wed, 05 Mar 2003 06:21:03 -0800 Subject: [Python-checkins] python/dist/src/Doc/ref ref3.tex,1.100,1.101 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1:/tmp/cvs-serv28992 Modified Files: ref3.tex Log Message: I thought it was common practice to check things compiled before checking them in? Oh well, this fixes various obvious mistakes and changes a subsubsubsection (which doesn't exist) into a subsubsection (which does). I'm not sure this matches the intent, but it seems to read OK on a quick skim. Index: ref3.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v retrieving revision 1.100 retrieving revision 1.101 diff -C2 -d -r1.100 -r1.101 *** ref3.tex 28 Feb 2003 14:11:45 -0000 1.100 --- ref3.tex 5 Mar 2003 14:20:58 -0000 1.101 *************** *** 1200,1204 **** \end{methoddesc} ! \subsubsection{More attribute access for new-style classes \lable{new-style-attribute-access}} The following methods only apply to new-style classes. --- 1200,1204 ---- \end{methoddesc} ! \subsubsection{More attribute access for new-style classes \label{new-style-attribute-access}} The following methods only apply to new-style classes. *************** *** 1216,1220 **** \end{methoddesc} ! \subsubsubsection{Implementing Descriptors \label{descriptors}} The following methods only apply when an instance of the class --- 1216,1220 ---- \end{methoddesc} ! \subsubsection{Implementing Descriptors \label{descriptors}} The following methods only apply when an instance of the class *************** *** 1236,1246 **** \begin{methoddesc}[object]{__set__}{self, instance, value} ! Called to set the attribute on an instance \{instance} of the owner class to a new value, \var{value}. \end{methoddesc} \begin{methoddesc}[object]{__delete__}{self, instance} ! Called to delete the attribute on an instance \{instance} of the owner ! class. \end{methoddesc} --- 1236,1246 ---- \begin{methoddesc}[object]{__set__}{self, instance, value} ! Called to set the attribute on an instance \var{instance} of the owner class to a new value, \var{value}. \end{methoddesc} \begin{methoddesc}[object]{__delete__}{self, instance} ! Called to delete the attribute on an instance \var{instance} of the ! owner class. \end{methoddesc} From mwh@users.sourceforge.net Wed Mar 5 14:42:15 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Wed, 05 Mar 2003 06:42:15 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libstdtypes.tex,1.118,1.119 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv5741 Modified Files: libstdtypes.tex Log Message: Back in June in revision 1.98 Steve (accidentally, presumably) wiped out a month's worth of checkins to libstdtypes.tex (including my extended slice docs). I think this checkin merges them all back in, but if you make one of these checkins: revision 1.97 date: 2002/06/14 00:27:13; author: nnorwitz Use \code{True} (or False) instead of true/false. Not sure if code is correct, but that is what's in this file. I've seen \constant{True} in other places. ---------------------------- revision 1.95 date: 2002/05/22 20:39:43; author: bwarsaw Jack's documentation for the U mode character on the file() constructor, vetted by Barry. ---------------------------- revision 1.94 date: 2002/05/21 18:19:15; author: rhettinger Patch 543387. Document deprecation of complex %, //,and divmod(). ---------------------------- revision 1.93 date: 2002/05/15 15:45:25; author: rhettinger Added missing index entries for mapping methods. Closes patch #548693. some checking may be in order. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.118 retrieving revision 1.119 diff -C2 -d -r1.118 -r1.119 *** libstdtypes.tex 17 Feb 2003 18:57:06 -0000 1.118 --- libstdtypes.tex 5 Mar 2003 14:42:09 -0000 1.119 *************** *** 229,234 **** \bifuncindex{complex} ! All numeric types support the following operations, sorted by ! ascending priority (operations in the same box have the same priority; all numeric operations have a higher priority than comparison operations): --- 229,234 ---- \bifuncindex{complex} ! All numeric types (except complex) support the following operations, ! sorted by ascending priority (operations in the same box have the same priority; all numeric operations have a higher priority than comparison operations): *************** *** 240,244 **** \lineiii{\var{x} * \var{y}}{product of \var{x} and \var{y}}{} \lineiii{\var{x} / \var{y}}{quotient of \var{x} and \var{y}}{(1)} ! \lineiii{\var{x} \%{} \var{y}}{remainder of \code{\var{x} / \var{y}}}{} \hline \lineiii{-\var{x}}{\var{x} negated}{} --- 240,244 ---- \lineiii{\var{x} * \var{y}}{product of \var{x} and \var{y}}{} \lineiii{\var{x} / \var{y}}{quotient of \var{x} and \var{y}}{(1)} ! \lineiii{\var{x} \%{} \var{y}}{remainder of \code{\var{x} / \var{y}}}{(4)} \hline \lineiii{-\var{x}}{\var{x} negated}{} *************** *** 251,255 **** \lineiii{complex(\var{re},\var{im})}{a complex number with real part \var{re}, imaginary part \var{im}. \var{im} defaults to zero.}{} \lineiii{\var{c}.conjugate()}{conjugate of the complex number \var{c}}{} ! \lineiii{divmod(\var{x}, \var{y})}{the pair \code{(\var{x} / \var{y}, \var{x} \%{} \var{y})}}{(3)} \lineiii{pow(\var{x}, \var{y})}{\var{x} to the power \var{y}}{} \lineiii{\var{x} ** \var{y}}{\var{x} to the power \var{y}}{} --- 251,255 ---- \lineiii{complex(\var{re},\var{im})}{a complex number with real part \var{re}, imaginary part \var{im}. \var{im} defaults to zero.}{} \lineiii{\var{c}.conjugate()}{conjugate of the complex number \var{c}}{} ! \lineiii{divmod(\var{x}, \var{y})}{the pair \code{(\var{x} / \var{y}, \var{x} \%{} \var{y})}}{(3)(4)} \lineiii{pow(\var{x}, \var{y})}{\var{x} to the power \var{y}}{} \lineiii{\var{x} ** \var{y}}{\var{x} to the power \var{y}}{} *************** *** 284,287 **** --- 284,293 ---- description. + \item[(4)] + Complex floor division operator, modulo operator, and \function{divmod()}. + + \deprecated{2.3}{Instead convert to float using \function{abs()} + if appropriate.} + \end{description} % XXXJH exceptions: overflow (when? what operations?) zerodivision *************** *** 443,446 **** --- 449,453 ---- \lineiii{\var{s}[\var{i}]}{\var{i}'th item of \var{s}, origin 0}{(3)} \lineiii{\var{s}[\var{i}:\var{j}]}{slice of \var{s} from \var{i} to \var{j}}{(3), (4)} + \lineiii{\var{s}[\var{i}:\var{j}:\var{k}]}{slice of \var{s} from \var{i} to \var{j} with step \var{k}}{(3), (5)} \hline \lineiii{len(\var{s})}{length of \var{s}}{} *************** *** 456,459 **** --- 463,467 ---- \indexii{subscript}{operation} \indexii{slice}{operation} + \indexii{extended slice}{operation} \opindex{in} \opindex{not in} *************** *** 507,510 **** --- 515,527 ---- use \code{0}. If \var{j} is omitted, use \code{len(\var{s})}. If \var{i} is greater than or equal to \var{j}, the slice is empty. + + \item[(5)] The slice of \var{s} from \var{i} to \var{j} with step + \var{k} is defined as the sequence of items with index + \code{\var{x} = \var{i} + \var{n}*\var{k}} such that \code{0} + \code{<=} \var{n} \code{<} \code{abs(i-j)}. If \var{i} or \var{j} + is greater than \code{len(\var{s})}, use \code{len(\var{s})}. If + \var{i} or \var{j} are ommitted then they become ``end'' values + (which end depends on the sign of \var{k}). + \end{description} *************** *** 551,556 **** \begin{methoddesc}[string]{endswith}{suffix\optional{, start\optional{, end}}} ! Return true if the string ends with the specified \var{suffix}, ! otherwise return false. With optional \var{start}, test beginning at that position. With optional \var{end}, stop comparing at that position. \end{methoddesc} --- 568,573 ---- \begin{methoddesc}[string]{endswith}{suffix\optional{, start\optional{, end}}} ! Return \code{True} if the string ends with the specified \var{suffix}, ! otherwise return \code{False}. With optional \var{start}, test beginning at that position. With optional \var{end}, stop comparing at that position. \end{methoddesc} *************** *** 684,689 **** \begin{methoddesc}[string]{startswith}{prefix\optional{, start\optional{, end}}} ! Return true if string starts with the \var{prefix}, otherwise ! return false. With optional \var{start}, test string beginning at that position. With optional \var{end}, stop comparing string at that position. --- 701,706 ---- \begin{methoddesc}[string]{startswith}{prefix\optional{, start\optional{, end}}} ! Return \code{True} if string starts with the \var{prefix}, otherwise ! return \code{False}. With optional \var{start}, test string beginning at that position. With optional \var{end}, stop comparing string at that position. *************** *** 912,934 **** \lineiii{del \var{s}[\var{i}:\var{j}]} {same as \code{\var{s}[\var{i}:\var{j}] = []}}{} \lineiii{\var{s}.append(\var{x})} ! {same as \code{\var{s}[len(\var{s}):len(\var{s})] = [\var{x}]}}{(1)} \lineiii{\var{s}.extend(\var{x})} ! {same as \code{\var{s}[len(\var{s}):len(\var{s})] = \var{x}}}{(2)} \lineiii{\var{s}.count(\var{x})} {return number of \var{i}'s for which \code{\var{s}[\var{i}] == \var{x}}}{} \lineiii{\var{s}.index(\var{x})} ! {return smallest \var{i} such that \code{\var{s}[\var{i}] == \var{x}}}{(3)} \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=None}})} ! {sort the items of \var{s} in place}{(6), (7), (8), (9)} \end{tableiii} \indexiv{operations on}{mutable}{sequence}{types} --- 929,955 ---- \lineiii{del \var{s}[\var{i}:\var{j}]} {same as \code{\var{s}[\var{i}:\var{j}] = []}}{} + \lineiii{\var{s}[\var{i}:\var{j}:\var{k}] = \var{t}} + {the elements of \code{\var{s}[\var{i}:\var{j}:\var{k}]} are replaced by those of \var{t}}{(1)} + \lineiii{del \var{s}[\var{i}:\var{j}:\var{k}]} + {removes the elements of \code{\var{s}[\var{i}:\var{j}:\var{k}]} from the list}{} \lineiii{\var{s}.append(\var{x})} ! {same as \code{\var{s}[len(\var{s}):len(\var{s})] = [\var{x}]}}{(2)} \lineiii{\var{s}.extend(\var{x})} ! {same as \code{\var{s}[len(\var{s}):len(\var{s})] = \var{x}}}{(3)} \lineiii{\var{s}.count(\var{x})} {return number of \var{i}'s for which \code{\var{s}[\var{i}] == \var{x}}}{} \lineiii{\var{s}.index(\var{x})} ! {return smallest \var{i} such that \code{\var{s}[\var{i}] == \var{x}}}{(4)} \lineiii{\var{s}.insert(\var{i}, \var{x})} {same as \code{\var{s}[\var{i}:\var{i}] = [\var{x}]} ! if \code{\var{i} >= 0}}{(5)} \lineiii{\var{s}.pop(\optional{\var{i}})} ! {same as \code{\var{x} = \var{s}[\var{i}]; del \var{s}[\var{i}]; return \var{x}}}{(6)} \lineiii{\var{s}.remove(\var{x})} ! {same as \code{del \var{s}[\var{s}.index(\var{x})]}}{(4)} \lineiii{\var{s}.reverse()} ! {reverses the items of \var{s} in place}{(7)} \lineiii{\var{s}.sort(\optional{\var{cmpfunc=None}})} ! {sort the items of \var{s} in place}{(7), (8), (9), (10)} \end{tableiii} \indexiv{operations on}{mutable}{sequence}{types} *************** *** 937,940 **** --- 958,962 ---- \indexii{subscript}{assignment} \indexii{slice}{assignment} + \indexii{extended slice}{assignment} \stindex{del} \withsubitem{(list method)}{ *************** *** 945,972 **** Notes: \begin{description} ! \item[(1)] The C implementation of Python historically accepted ! multiple parameters and implicitly joined them into a tuple; ! Use of this misfeature has been deprecated since Python 1.4, ! and became an error with the introduction of Python 2.0. ! \item[(2)] Raises an exception when \var{x} is not an iterable object. ! \item[(3)] Raises \exception{ValueError} when \var{x} is not found in \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 --- 967,999 ---- Notes: \begin{description} ! \item[(1)] \var{t} must have the same length as the slice it is ! replacing. ! \item[(2)] The C implementation of Python has historically accepted ! multiple parameters and implicitly joined them into a tuple; this ! no longer works in Python 2.0. Use of this misfeature has been ! deprecated since Python 1.4. ! \item[(3)] Raises an exception when \var{x} is not a list object. The ! \method{extend()} method is experimental and not supported by ! mutable sequence types other than lists. ! ! \item[(4)] Raises \exception{ValueError} when \var{x} is not found in \var{s}. ! \item[(5)] When a negative index is passed as the first parameter to the \method{insert()} method, the new element is prepended to the sequence. ! \item[(6)] 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[(7)] 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[(8)] 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 *************** *** 980,984 **** \method{sort()} with no comparison function. ! \item[(8)] Whether the \method{sort()} method is stable is not defined by the language (a sort is stable if it guarantees not to change the relative order of elements that compare equal). In the C --- 1007,1011 ---- \method{sort()} with no comparison function. ! \item[(9)] Whether the \method{sort()} method is stable is not defined by the language (a sort is stable if it guarantees not to change the relative order of elements that compare equal). In the C *************** *** 988,992 **** implementations and versions must not rely on stability. ! \item[(9)] While a list is being sorted, the effect of attempting to mutate, or even inspect, the list is undefined. The C implementation of Python 2.3 makes the list appear empty for the duration, and raises --- 1015,1019 ---- implementations and versions must not rely on stability. ! \item[(10)] While a list is being sorted, the effect of attempting to mutate, or even inspect, the list is undefined. The C implementation of Python 2.3 makes the list appear empty for the duration, and raises *************** *** 1031,1035 **** \ttindex{update()} \ttindex{values()} ! \ttindex{get()}} \begin{tableiii}{c|l|c}{code}{Operation}{Result}{Notes} --- 1058,1068 ---- \ttindex{update()} \ttindex{values()} ! \ttindex{get()} ! \ttindex{setdefault()} ! \ttindex{pop()} ! \ttindex{popitem()} ! \ttindex{iteritems()} ! \ttindex{iterkeys)} ! \ttindex{itervalues()}} \begin{tableiii}{c|l|c}{code}{Operation}{Result}{Notes} *************** *** 1321,1324 **** --- 1354,1369 ---- file object, of the form \samp{<\mbox{\ldots}>}. This is a read-only attribute and may not be present on all file-like objects. + \end{memberdesc} + + \begin{memberdesc}[file]{newlines} + If Python was built with the \code{--with-universal-newlines} option + (the default) this read-only attribute exists, and for files opened in + universal newline read mode it keeps track of the types of newlines + encountered while reading the file. The values it can take are + \code{'\e r'}, \code{'\e n'}, \code{'\e r\e n'}, \code{None} (unknown, + no newlines read yet) or a tuple containing all the newline + types seen, to indicate that multiple + newline conventions were encountered. For files not opened in universal + newline read mode the value of this attribute will be \code{None}. \end{memberdesc} From jackjansen@users.sourceforge.net Wed Mar 5 14:42:23 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Mar 2003 06:42:23 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac bundlebuilder.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv4960 Modified Files: bundlebuilder.py Log Message: Moved some application-bundle specific code from the BundleBuilder class to AppBuilder, and set the default type to BNDL (overridden in AppBuilder). This surfaced when trying to build help bundles. Index: bundlebuilder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/bundlebuilder.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** bundlebuilder.py 26 Feb 2003 11:27:56 -0000 1.18 --- bundlebuilder.py 5 Mar 2003 14:42:18 -0000 1.19 *************** *** 84,88 **** # The type of the bundle. ! type = "APPL" # The creator code of the bundle. creator = None --- 84,88 ---- # The type of the bundle. ! type = "BNDL" # The creator code of the bundle. creator = None *************** *** 98,104 **** builddir = "build" - # platform, name of the subfolder of Contents that contains the executable. - platform = "MacOS" - # Make symlinks instead copying files. This is handy during debugging, but # makes the bundle non-distributable. --- 98,101 ---- *************** *** 116,120 **** # misc (derived) attributes self.bundlepath = pathjoin(self.builddir, self.name + bundleextension) - self.execdir = pathjoin("Contents", self.platform) plist = self.plist --- 113,116 ---- *************** *** 295,298 **** --- 291,300 ---- class AppBuilder(BundleBuilder): + # Override type of the bundle. + type = "BNDL" + + # platform, name of the subfolder of Contents that contains the executable. + platform = "MacOS" + # A Python main program. If this argument is given, the main # executable in the bundle will be a small wrapper that invokes *************** *** 355,358 **** --- 357,362 ---- raise BundleBuilderError, ("must specify either or both of " "'executable' and 'mainprogram'") + + self.execdir = pathjoin("Contents", self.platform) if self.name is not None: From jackjansen@users.sourceforge.net Wed Mar 5 14:44:57 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Mar 2003 06:44:57 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac bundlebuilder.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv6590 Modified Files: bundlebuilder.py Log Message: Actually *do* override the type in AppBuilder. Index: bundlebuilder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/bundlebuilder.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** bundlebuilder.py 5 Mar 2003 14:42:18 -0000 1.19 --- bundlebuilder.py 5 Mar 2003 14:44:54 -0000 1.20 *************** *** 292,296 **** # Override type of the bundle. ! type = "BNDL" # platform, name of the subfolder of Contents that contains the executable. --- 292,296 ---- # Override type of the bundle. ! type = "APPL" # platform, name of the subfolder of Contents that contains the executable. From loewis@users.sourceforge.net Wed Mar 5 15:14:14 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 05 Mar 2003 07:14:14 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_support.py,1.48,1.49 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv18533/Lib/test Modified Files: test_support.py Log Message: Always initialize Py_FileSystemDefaultEncoding on Unix in Py_Initialize, and not as a side effect of setlocale. Expose it as sys.getfilesystemencoding. Adjust test case. Index: test_support.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_support.py,v retrieving revision 1.48 retrieving revision 1.49 diff -C2 -d -r1.48 -r1.49 *** test_support.py 3 Feb 2003 15:19:30 -0000 1.48 --- test_support.py 5 Mar 2003 15:13:40 -0000 1.49 *************** *** 110,115 **** else: TESTFN_UNICODE=unicode("@test-\xe0\xf2", "latin-1") # 2 latin characters. ! if os.name=="nt": ! TESTFN_ENCODING="mbcs" else: TESTFN = 'test' --- 110,114 ---- else: TESTFN_UNICODE=unicode("@test-\xe0\xf2", "latin-1") # 2 latin characters. ! TESTFN_ENCODING=sys.getfilesystemencoding() else: TESTFN = 'test' From loewis@users.sourceforge.net Wed Mar 5 15:14:13 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 05 Mar 2003 07:14:13 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libsys.tex,1.62,1.63 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv18533/Doc/lib Modified Files: libsys.tex Log Message: Always initialize Py_FileSystemDefaultEncoding on Unix in Py_Initialize, and not as a side effect of setlocale. Expose it as sys.getfilesystemencoding. Adjust test case. Index: libsys.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsys.tex,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** libsys.tex 1 Mar 2003 03:20:38 -0000 1.62 --- libsys.tex 5 Mar 2003 15:13:38 -0000 1.63 *************** *** 212,215 **** --- 212,231 ---- \end{funcdesc} + \begin{funcdesc}{getfilesystemencoding}{} + Return the name of the encoding used to convert Unicode filenames + into system file names, or \code{None} if the system default encoding + is used. The result value depends on the operating system: + \begin{itemize} + \item On Windows 9x, the encoding is ``mbcs''. + \item On Mac OS X, the encoding is ``utf-8''. + \item On Unix, the encoding is the user's preference + according to the result of nl_langinfo(CODESET), or None if + the nl_langinfo(CODESET) failed. + \item On Windows NT+, file names are Unicode natively, so no conversion + is performed. + \end{itemize} + \versionadded{2.3} + \end{funcdesc} + \begin{funcdesc}{getrefcount}{object} Return the reference count of the \var{object}. The count returned From loewis@users.sourceforge.net Wed Mar 5 15:14:16 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 05 Mar 2003 07:14:16 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.688,1.689 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv18533/Misc Modified Files: NEWS Log Message: Always initialize Py_FileSystemDefaultEncoding on Unix in Py_Initialize, and not as a side effect of setlocale. Expose it as sys.getfilesystemencoding. Adjust test case. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.688 retrieving revision 1.689 diff -C2 -d -r1.688 -r1.689 *** NEWS 3 Mar 2003 21:16:38 -0000 1.688 --- NEWS 5 Mar 2003 15:13:42 -0000 1.689 *************** *** 13,16 **** --- 13,18 ---- ----------------- + - sys.getfilesystemencoding() was added to expose + Py_FileSystemDefaultEncoding. - New function sys.exc_clear() clears the current exception. This is From loewis@users.sourceforge.net Wed Mar 5 15:14:18 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 05 Mar 2003 07:14:18 -0800 Subject: [Python-checkins] python/dist/src/Modules _localemodule.c,2.38,2.39 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv18533/Modules Modified Files: _localemodule.c Log Message: Always initialize Py_FileSystemDefaultEncoding on Unix in Py_Initialize, and not as a side effect of setlocale. Expose it as sys.getfilesystemencoding. Adjust test case. Index: _localemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_localemodule.c,v retrieving revision 2.38 retrieving revision 2.39 diff -C2 -d -r2.38 -r2.39 *** _localemodule.c 21 Dec 2002 18:34:06 -0000 2.38 --- _localemodule.c 5 Mar 2003 15:13:45 -0000 2.39 *************** *** 162,169 **** } - #if defined(HAVE_LANGINFO_H) && defined(CODESET) - static int fileencoding_uses_locale = 0; - #endif - static PyObject* PyLocale_setlocale(PyObject* self, PyObject* args) --- 162,165 ---- *************** *** 214,233 **** /* things that got wrong up to here are ignored */ PyErr_Clear(); - #if defined(HAVE_LANGINFO_H) && defined(CODESET) - if (Py_FileSystemDefaultEncoding == NULL) - fileencoding_uses_locale = 1; - if (fileencoding_uses_locale) { - char *codeset = nl_langinfo(CODESET); - PyObject *enc = NULL; - if (*codeset && (enc = PyCodec_Encoder(codeset))) { - /* Release previous file encoding */ - if (Py_FileSystemDefaultEncoding) - free((char *)Py_FileSystemDefaultEncoding); - Py_FileSystemDefaultEncoding = strdup(codeset); - Py_DECREF(enc); - } else - PyErr_Clear(); - } - #endif } else { /* get locale */ --- 210,213 ---- From loewis@users.sourceforge.net Wed Mar 5 15:14:21 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Wed, 05 Mar 2003 07:14:21 -0800 Subject: [Python-checkins] python/dist/src/Python pythonrun.c,2.179,2.180 sysmodule.c,2.115,2.116 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv18533/Python Modified Files: pythonrun.c sysmodule.c Log Message: Always initialize Py_FileSystemDefaultEncoding on Unix in Py_Initialize, and not as a side effect of setlocale. Expose it as sys.getfilesystemencoding. Adjust test case. Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.179 retrieving revision 2.180 diff -C2 -d -r2.179 -r2.180 *** pythonrun.c 25 Feb 2003 20:25:12 -0000 2.179 --- pythonrun.c 5 Mar 2003 15:13:46 -0000 2.180 *************** *** 18,21 **** --- 18,26 ---- #endif + #ifdef HAVE_LANGINFO_H + #include + #include + #endif + #ifdef MS_WINDOWS #undef BYTE *************** *** 182,185 **** --- 187,213 ---- PyModule_WarningsModule = PyImport_ImportModule("warnings"); + + #if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET) + /* On Unix, set the file system encoding according to the + user's preference, if the CODESET names a well-known + Python codec, and Py_FileSystemDefaultEncoding isn't + initialized by other means. */ + if (!Py_FileSystemDefaultEncoding) { + char *saved_locale = setlocale(LC_CTYPE, NULL); + char *codeset; + setlocale(LC_CTYPE, ""); + codeset = nl_langinfo(CODESET); + PyObject *enc = NULL; + if (*codeset) { + enc = PyCodec_Encoder(codeset); + if (enc) { + Py_FileSystemDefaultEncoding = strdup(codeset); + Py_DECREF(enc); + } else + PyErr_Clear(); + } + setlocale(LC_CTYPE, saved_locale); + } + #endif } Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.115 retrieving revision 2.116 diff -C2 -d -r2.115 -r2.116 *** sysmodule.c 1 Mar 2003 03:20:41 -0000 2.115 --- sysmodule.c 5 Mar 2003 15:13:47 -0000 2.116 *************** *** 237,240 **** --- 237,256 ---- ); + static PyObject * + sys_getfilesystemencoding(PyObject *self) + { + if (Py_FileSystemDefaultEncoding) + return PyString_FromString(Py_FileSystemDefaultEncoding); + Py_INCREF(Py_None); + return Py_None; + } + + PyDoc_STRVAR(getfilesystemencoding_doc, + "getfilesystemencoding() -> string\n\ + \n\ + Return the encoding used to convert Unicode filenames in\n\ + operating system filenames." + ); + #endif *************** *** 649,652 **** --- 665,672 ---- #ifdef DYNAMIC_EXECUTION_PROFILE {"getdxp", _Py_GetDXProfile, METH_VARARGS}, + #endif + #ifdef Py_USING_UNICODE + {"getfilesystemencoding", (PyCFunction)sys_getfilesystemencoding, + METH_NOARGS, getfilesystemencoding_doc}, #endif #ifdef Py_TRACE_REFS From jvr@users.sourceforge.net Wed Mar 5 15:46:59 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Wed, 05 Mar 2003 07:46:59 -0800 Subject: [Python-checkins] python/dist/src/Modules main.c,1.73,1.74 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv685/Modules Modified Files: main.c Log Message: removing one Mac hack and add another: - The applet logic has been replaced to bundlebuilder's bootstrap script - Due to Apple being extremely string about argv[0], we need a way to specify the actual executable name for use with sys.executable. See the comment embedded in the code. Index: main.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v retrieving revision 1.73 retrieving revision 1.74 diff -C2 -d -r1.73 -r1.74 *** main.c 5 Mar 2003 14:15:19 -0000 1.73 --- main.c 5 Mar 2003 15:46:54 -0000 1.74 *************** *** 13,20 **** #endif - #if defined(WITH_NEXT_FRAMEWORK) - #include "pymactoolbox.h" - #endif - #if (defined(PYOS_OS2) && !defined(PYCC_GCC)) || defined(MS_WINDOWS) #define PYTHONHOMEHELP "\\lib" --- 13,16 ---- *************** *** 155,179 **** PySys_ResetWarnOptions(); - #if defined(WITH_NEXT_FRAMEWORK) - /* If we are running from a framework it could be that we are actually - ** the main program for an applet. If so, the next call will return the - ** filename that we are supposed to run. - */ - filename = PyMac_GetAppletScriptFile(); - if (filename != NULL) { - if ((fp = fopen(filename, "r")) == NULL) { - fprintf(stderr, "%s: can't open file '%s'\n", - argv[0], filename); - #if defined(__VMS) - /* STS$M_INHIB_MSG + SS$_ABORT */ - exit(0x1000002c); - #else - exit(2); - #endif - } - } - /* Skip option-processing if we are an applet */ - if (filename == NULL) - #endif while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) { if (c == 'c') { --- 151,154 ---- *************** *** 302,306 **** unbuffered = 1; ! if (command == NULL && filename == NULL && _PyOS_optind < argc && strcmp(argv[_PyOS_optind], "-") != 0) { --- 277,281 ---- unbuffered = 1; ! if (command == NULL && _PyOS_optind < argc && strcmp(argv[_PyOS_optind], "-") != 0) { *************** *** 376,379 **** --- 351,369 ---- #endif /* __VMS */ + #ifdef __APPLE__ + /* On MacOS X, when the Python interpreter is embedded in an + application bundle, it gets executed by a bootstrapping script + that does os.execve() with an argv[0] that's different from the + actual Python executable. This is needed to keep the Finder happy, + or rather, to work around Apple's overly strict requirements of + the process name. However, we still need a usable sys.executable, + so the actual executable path is passed in an environment variable. + See Lib/plat-mac/bundlebuiler.py for details about the bootstrap + script. */ + if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0') + Py_SetProgramName(p); + else + Py_SetProgramName(argv[0]); + #else Py_SetProgramName(argv[0]); Py_Initialize(); From jackjansen@users.sourceforge.net Wed Mar 5 16:00:20 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Mar 2003 08:00:20 -0800 Subject: [Python-checkins] python/dist/src/Modules main.c,1.74,1.75 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv7785/Modules Modified Files: main.c Log Message: An #endif was missing in Just's patch. Added. Index: main.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -d -r1.74 -r1.75 *** main.c 5 Mar 2003 15:46:54 -0000 1.74 --- main.c 5 Mar 2003 16:00:15 -0000 1.75 *************** *** 367,370 **** --- 367,371 ---- #else Py_SetProgramName(argv[0]); + #endif Py_Initialize(); From jackjansen@users.sourceforge.net Wed Mar 5 16:13:23 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Mar 2003 08:13:23 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSXResources/app Info.plist,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app In directory sc8-pr-cvs1:/tmp/cvs-serv12325 Modified Files: Info.plist Log Message: Fix for bug #697546: don't auto-register the Python documentation by putting the help book in an array. Somehow the fact that Python.app (and, hence, pythonw) got an automatic help menu messed up Tkinter's handling of the help menu. Index: Info.plist =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/OSXResources/app/Info.plist,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Info.plist 28 Aug 2002 21:27:02 -0000 1.8 --- Info.plist 5 Mar 2003 16:13:19 -0000 1.9 *************** *** 31,35 **** CFBundleHelpBookFolder ! Documentation CFBundleHelpBookName Python Help --- 31,37 ---- CFBundleHelpBookFolder ! ! Documentation ! CFBundleHelpBookName Python Help From jvr@users.sourceforge.net Wed Mar 5 17:23:52 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Wed, 05 Mar 2003 09:23:52 -0800 Subject: [Python-checkins] python/dist/src/Lib modulefinder.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv19025/Lib Modified Files: modulefinder.py Log Message: Patch #698082 from Thomas Heller: Modulefinder didn't exclude modules in packages correctly. Index: modulefinder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/modulefinder.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** modulefinder.py 27 Feb 2003 20:14:35 -0000 1.5 --- modulefinder.py 5 Mar 2003 17:23:48 -0000 1.6 *************** *** 243,247 **** try: fp, pathname, stuff = self.find_module(partname, ! parent and parent.__path__) except ImportError: self.msgout(3, "import_module ->", None) --- 243,247 ---- try: fp, pathname, stuff = self.find_module(partname, ! parent and parent.__path__, parent) except ImportError: self.msgout(3, "import_module ->", None) *************** *** 386,392 **** return m ! def find_module(self, name, path): ! if path: ! fullname = '.'.join(path)+'.'+name else: fullname = name --- 386,392 ---- return m ! def find_module(self, name, path, parent=None): ! if parent is not None: ! fullname = parent.__name__+'.'+name else: fullname = name From fdrake@users.sourceforge.net Wed Mar 5 17:31:26 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Wed, 05 Mar 2003 09:31:26 -0800 Subject: [Python-checkins] python/dist/src/Python pythonrun.c,2.180,2.181 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv22516/Python Modified Files: pythonrun.c Log Message: Declare all variables at the start of their scope. Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.180 retrieving revision 2.181 diff -C2 -d -r2.180 -r2.181 *** pythonrun.c 5 Mar 2003 15:13:46 -0000 2.180 --- pythonrun.c 5 Mar 2003 17:31:21 -0000 2.181 *************** *** 196,202 **** char *saved_locale = setlocale(LC_CTYPE, NULL); char *codeset; setlocale(LC_CTYPE, ""); codeset = nl_langinfo(CODESET); - PyObject *enc = NULL; if (*codeset) { enc = PyCodec_Encoder(codeset); --- 196,202 ---- char *saved_locale = setlocale(LC_CTYPE, NULL); char *codeset; + PyObject *enc = NULL; setlocale(LC_CTYPE, ""); codeset = nl_langinfo(CODESET); if (*codeset) { enc = PyCodec_Encoder(codeset); From jackjansen@users.sourceforge.net Wed Mar 5 21:16:13 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 05 Mar 2003 13:16:13 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac aetools.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv22404 Modified Files: aetools.py Log Message: Two ancient and obscure bugs found and fixed by Donovan Preston (these could be responsible for various unexplained problems with Python/OSA interaction over the years): - Enum values were passed as their string counterparts. Most applications don't seem to mind this, but some do (InDesign). - Attributes have never worked (!), as they were incorrectly passed as parameters. Apparently nobody uses them much:-) Index: aetools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/aetools.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** aetools.py 26 Feb 2003 15:28:17 -0000 1.2 --- aetools.py 5 Mar 2003 21:16:06 -0000 1.3 *************** *** 93,97 **** packkey(ae, key, value) for key, value in attributes.items(): ! packkey(ae, key, value) # --- 93,97 ---- packkey(ae, key, value) for key, value in attributes.items(): ! ae.AEPutAttributeDesc(key, pack(value)) # *************** *** 117,121 **** ok = edict.values() if edict.has_key(v): ! arguments[key] = edict[v] elif not v in ok: raise TypeError, 'Unknown enumerator: %s'%v --- 117,121 ---- ok = edict.values() if edict.has_key(v): ! arguments[key] = Enum(edict[v]) elif not v in ok: raise TypeError, 'Unknown enumerator: %s'%v From gvanrossum@users.sourceforge.net Wed Mar 5 23:32:02 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 05 Mar 2003 15:32:02 -0800 Subject: [Python-checkins] python/dist/src/Lib timeit.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv18995 Added Files: timeit.py Log Message: A flexible utility to time the execution speed of a code snippet. Usable from the command line or from a program. --- NEW FILE: timeit.py --- """Framework for timing execution speed of small code snippets. This avoids a number of common traps for timing frameworks (see also Tim Peters' introduction to the timing chapter in the Python Cookbook). (To use this with older versions of Python, the dependency on the itertools module is easily removed; instead of itertools.repeat(None, count) you can use [None]*count; this is barely slower.) Command line usage: python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [statement] Options: -n/--number N: how many times to execute 'statement' (default varies) -r/--repeat N: how many times to repeat the timer (default 1) -s/--setup S: statements executed once before 'statement' (default 'pass') -t/--time: use time.time() (default on Unix) -c/--clock: use time.clock() (default on Windows) statement: statement to be timed (default 'pass') """ import sys import math import time import itertools __all__ = ["Timer"] default_number = 1000000 default_repeat = 10 if sys.platform == "win32": # On Windows, the best timer is time.clock() default_timer = time.clock else: # On most other platforms the best timer is time.time() default_timer = time.time template = """ def inner(number, timer): %(setup)s seq = itertools.repeat(None, number) t0 = timer() for i in seq: %(stmt)s t1 = timer() return t1-t0 """ def reindent(src, indent): return ("\n" + " "*indent).join(src.split("\n")) class Timer: def __init__(self, stmt="pass", setup="pass", timer=default_timer): self.timer = timer stmt = reindent(stmt, 8) setup = reindent(setup, 4) src = template % {'stmt': stmt, 'setup': setup} code = compile(src, "", "exec") ns = {} exec code in globals(), ns self.inner = ns["inner"] def timeit(self, number=default_number): return self.inner(number, self.timer) def repeat(self, repeat=default_repeat, number=default_number): r = [] for i in range(repeat): t = self.timeit(number) r.append(t) return r def main(args=None): if args is None: args = sys.argv[1:] import getopt try: opts, args = getopt.getopt(args, "n:s:r:tc", ["number=", "setup=", "repeat=", "time", "clock"]) except getopt.error, err: print err return 2 timer = default_timer stmt = "\n".join(args) or "pass" number = 0 # auto-determine setup = "pass" repeat = 1 for o, a in opts: if o in ("-n", "--number"): number = int(a) if o in ("-s", "--setup"): setup = a if o in ("-r", "--repeat"): repeat = int(a) if repeat <= 0: repeat = 1 if o in ("-t", "time"): timer = time.time if o in ("-c", "clock"): timer = time.clock t = Timer(stmt, setup, timer) if number == 0: # determine number so that 0.2 <= total time < 2.0 for i in range(1, 10): number = 10**i x = t.timeit(number) if x >= 0.2: break r = t.repeat(repeat, number) best = min(r) print "%d loops," % number, usec = best * 1e6 / number if repeat > 1: print "best of %d: %.3f usec" % (repeat, usec) else: print "time: %.3f usec" % usec if __name__ == "__main__": sys.exit(main()) From gvanrossum@users.sourceforge.net Thu Mar 6 01:56:16 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 05 Mar 2003 17:56:16 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.689,1.690 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv1532 Modified Files: NEWS Log Message: Mention timeit.py. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.689 retrieving revision 1.690 diff -C2 -d -r1.689 -r1.690 *** NEWS 5 Mar 2003 15:13:42 -0000 1.689 --- NEWS 6 Mar 2003 01:56:12 -0000 1.690 *************** *** 41,44 **** --- 41,47 ---- ------- + - New module timeit provides a simple framework for timing the + execution speed of expressions and statements. + - sets.Set objects now support mixed-type __eq__ and __ne__, instead of raising TypeError. If x is a Set object and y is a non-Set object, From gvanrossum@users.sourceforge.net Thu Mar 6 02:32:21 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 05 Mar 2003 18:32:21 -0800 Subject: [Python-checkins] python/dist/src/Lib timeit.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv12260 Modified Files: timeit.py Log Message: Added more documentation. Index: timeit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/timeit.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** timeit.py 5 Mar 2003 23:31:58 -0000 1.1 --- timeit.py 6 Mar 2003 02:32:19 -0000 1.2 *************** *** 1,17 **** ! """Framework for timing execution speed of small code snippets. ! This avoids a number of common traps for timing frameworks (see also ! Tim Peters' introduction to the timing chapter in the Python ! Cookbook). ! (To use this with older versions of Python, the dependency on the ! itertools module is easily removed; instead of itertools.repeat(None, ! count) you can use [None]*count; this is barely slower.) Command line usage: ! python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [statement] Options: ! -n/--number N: how many times to execute 'statement' (default varies) -r/--repeat N: how many times to repeat the timer (default 1) -s/--setup S: statements executed once before 'statement' (default 'pass') --- 1,15 ---- ! """Framework for measuring execution time for small code snippets. ! This module avoids a number of common traps for measuring execution ! times. See also Tim Peters' introduction to the Algorithms chapter in ! the Python Cookbook, published by O'Reilly. ! Library usage: see the Timer class. Command line usage: ! python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [statement] Options: ! -n/--number N: how many times to execute 'statement' (default: see below) -r/--repeat N: how many times to repeat the timer (default 1) -s/--setup S: statements executed once before 'statement' (default 'pass') *************** *** 19,24 **** --- 17,43 ---- -c/--clock: use time.clock() (default on Windows) statement: statement to be timed (default 'pass') + + A multi-line statement may be given by specifying each line as a + separate argument; indented lines are possible by enclosing an + argument in quotes and using leading spaces. + + If -n is not given, a suitable number of loops is calculated by trying + successive powers of 10 until the total time is at least 0.2 seconds. + + The difference in default timer function is because on Windows, + clock() has microsecond granularity but time()'s granularity is 1/60th + of a second; on Unix, clock() has 1/100th of a second granularity and + time() is much more precise. On either platform, the default timer + functions measures wall clock time, not the CPU time. This means that + other processes running on the same computer may interfere with the + timing. The best thing to do when accurate timing is necessary is to + repeat the timing a few times and use the best time; the -r option is + good for this. On Unix, you can use clock() to measure CPU time. """ + # To use this module with older versions of Python, the dependency on + # the itertools module is easily removed; in the template, instead of + # itertools.repeat(None, count), use [None]*count. It's barely slower. + import sys import math *************** *** 38,41 **** --- 57,63 ---- default_timer = time.time + # Don't change the indentation of the template; the reindent() calls + # in Timer.__init__() depend on setup being indented 4 spaces and stmt + # being indented 8 spaces. template = """ def inner(number, timer): *************** *** 50,58 **** --- 72,96 ---- def reindent(src, indent): + """Helper to reindent a multi-line statement.""" return ("\n" + " "*indent).join(src.split("\n")) class Timer: + """Class for timing execution speed of small code snippets. + + The constructor takes a statement to be timed, an additional + statement used for setup, and a timer function. Both statements + default to 'pass'; the timer function is platform-dependent (see + module doc string). + + To measure the execution time of the first statement, use the + timeit() method. The repeat() method is a convenience to call + timeit() multiple times and return a list of results. + + The statements may contain newlines, as long as they don't contain + multi-line string literals. + """ def __init__(self, stmt="pass", setup="pass", timer=default_timer): + """Constructor. See class doc string.""" self.timer = timer stmt = reindent(stmt, 8) *************** *** 65,71 **** --- 103,126 ---- def timeit(self, number=default_number): + """Time 'number' executions of the main statement. + + To be precise, this executes the setup statement once, and + then returns the time it takes to execute the main statement + a number of times, as a float measured in seconds. The + argument is the number of times through the loop, defaulting + to one million. The main statement, the setup statement and + the timer function to be used are passed to the constructor. + """ return self.inner(number, self.timer) def repeat(self, repeat=default_repeat, number=default_number): + """Call timer() a few times. + + This is a convenience function that calls the timer() + repeatedly, returning a list of results. The first argument + specifies how many times to call timer(), defaulting to 10; + the second argument specifies the timer argument, defaulting + to one million. + """ r = [] for i in range(repeat): *************** *** 75,78 **** --- 130,141 ---- def main(args=None): + """Main program, used when run as a script. + + The optional argument specifies the command line to be parsed, + defaulting to sys.argv[1:]. + + The return value is an exit code to be passed to sys.exit(); it + may be None to indicate success. + """ if args is None: args = sys.argv[1:] *************** *** 119,122 **** --- 182,186 ---- else: print "time: %.3f usec" % usec + return None if __name__ == "__main__": From gvanrossum@users.sourceforge.net Thu Mar 6 03:02:14 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Wed, 05 Mar 2003 19:02:14 -0800 Subject: [Python-checkins] python/dist/src/Lib timeit.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv20902 Modified Files: timeit.py Log Message: Add notes about baseline overhead, and about different Python versions. Add -h/--help option to print doc string. Index: timeit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/timeit.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** timeit.py 6 Mar 2003 02:32:19 -0000 1.2 --- timeit.py 6 Mar 2003 03:02:10 -0000 1.3 *************** *** 8,12 **** Command line usage: ! python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [statement] Options: --- 8,12 ---- Command line usage: ! python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [-h] [statement] Options: *************** *** 16,19 **** --- 16,20 ---- -t/--time: use time.time() (default on Unix) -c/--clock: use time.clock() (default on Windows) + -h/--help: print this usage message and exit statement: statement to be timed (default 'pass') *************** *** 34,42 **** repeat the timing a few times and use the best time; the -r option is good for this. On Unix, you can use clock() to measure CPU time. """ # To use this module with older versions of Python, the dependency on # the itertools module is easily removed; in the template, instead of ! # itertools.repeat(None, count), use [None]*count. It's barely slower. import sys --- 35,54 ---- repeat the timing a few times and use the best time; the -r option is good for this. On Unix, you can use clock() to measure CPU time. + + Note: there is a certain baseline overhead associated with executing a + pass statement. The code here doesn't try to hide it, but you should + be aware of it (especially when comparing different versions of + Python). The baseline overhead is measured by invoking the program + without arguments. """ # To use this module with older versions of Python, the dependency on # the itertools module is easily removed; in the template, instead of ! # itertools.repeat(None, number), use [None]*number. It's barely ! # slower. Note: the baseline overhead, measured by the default ! # invocation, differs for older Python versions! Also, to fairly ! # compare older Python versions to Python 2.3, you may want to use ! # python -O for the older versions to avoid timing SET_LINENO ! # instructions. import sys *************** *** 142,150 **** import getopt try: ! opts, args = getopt.getopt(args, "n:s:r:tc", ["number=", "setup=", "repeat=", ! "time", "clock"]) except getopt.error, err: print err return 2 timer = default_timer --- 154,163 ---- import getopt try: ! opts, args = getopt.getopt(args, "n:s:r:tch", ["number=", "setup=", "repeat=", ! "time", "clock", "help"]) except getopt.error, err: print err + print "use -h/--help for command line help" return 2 timer = default_timer *************** *** 162,169 **** if repeat <= 0: repeat = 1 ! if o in ("-t", "time"): timer = time.time ! if o in ("-c", "clock"): timer = time.clock t = Timer(stmt, setup, timer) if number == 0: --- 175,185 ---- if repeat <= 0: repeat = 1 ! if o in ("-t", "--time"): timer = time.time ! if o in ("-c", "--clock"): timer = time.clock + if o in ("-h", "--help"): + print __doc__, + return 0 t = Timer(stmt, setup, timer) if number == 0: From bwarsaw@users.sourceforge.net Thu Mar 6 05:14:22 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Wed, 05 Mar 2003 21:14:22 -0800 Subject: [Python-checkins] python/dist/src/Lib/email quopriMIME.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv31474 Modified Files: quopriMIME.py Log Message: Merge of the folding-reimpl-branch. Specific changes, _max_append(): Change the comparison so that the new string is concatenated if it's less than or equal to the max length. header_encode(): Allow for maxlinelen == None to mean, don't do any line splitting. This is because this module is mostly used by higher level abstractions (Header.py) which already ensures line lengths. We do this in a cheapo way by setting the max_encoding to some insanely <100k wink> large number. Index: quopriMIME.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/quopriMIME.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** quopriMIME.py 28 Sep 2002 21:02:51 -0000 1.4 --- quopriMIME.py 6 Mar 2003 05:14:20 -0000 1.5 *************** *** 83,87 **** if not L: L.append(s.lstrip()) ! elif len(L[-1]) + len(s) < maxlen: L[-1] += extra + s else: --- 83,87 ---- if not L: L.append(s.lstrip()) ! elif len(L[-1]) + len(s) <= maxlen: L[-1] += extra + s else: *************** *** 117,121 **** with each line wrapped safely at, at most, maxlinelen characters (defaults ! to 76 characters). End-of-line characters (\\r, \\n, \\r\\n) will be automatically converted --- 117,122 ---- with each line wrapped safely at, at most, maxlinelen characters (defaults ! to 76 characters). If maxlinelen is None, the entire string is encoded in ! one chunk with no splitting. End-of-line characters (\\r, \\n, \\r\\n) will be automatically converted *************** *** 135,141 **** # Quopri encode each line, in encoded chunks no greater than maxlinelen in ! # lenght, after the RFC chrome is added in. quoted = [] ! max_encoded = maxlinelen - len(charset) - MISC_LEN for c in header: --- 136,146 ---- # Quopri encode each line, in encoded chunks no greater than maxlinelen in ! # length, after the RFC chrome is added in. quoted = [] ! if maxlinelen is None: ! # An obnoxiously large number that's good enough ! max_encoded = 100000 ! else: ! max_encoded = maxlinelen - len(charset) - MISC_LEN - 1 for c in header: From bwarsaw@users.sourceforge.net Thu Mar 6 05:16:31 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Wed, 05 Mar 2003 21:16:31 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Charset.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv31943 Modified Files: Charset.py Log Message: Merge of the folding-reimpl-branch. Specific changes, Charset: Alias __repr__ to __str__ for debugging. header_encode(): When calling quopriMIME.header_encode(), set maxlinelen=None so that the lower level function doesn't (also) try to wrap/fold the line. Index: Charset.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Charset.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Charset.py 7 Jan 2003 00:29:07 -0000 1.12 --- Charset.py 6 Mar 2003 05:16:29 -0000 1.13 *************** *** 235,238 **** --- 235,240 ---- return self.input_charset.lower() + __repr__ = __str__ + def __eq__(self, other): return str(self) == str(other).lower() *************** *** 359,363 **** return email.base64MIME.header_encode(s, cset) elif self.header_encoding == QP: ! return email.quopriMIME.header_encode(s, cset) elif self.header_encoding == SHORTEST: lenb64 = email.base64MIME.base64_len(s) --- 361,365 ---- return email.base64MIME.header_encode(s, cset) elif self.header_encoding == QP: ! return email.quopriMIME.header_encode(s, cset, maxlinelen=None) elif self.header_encoding == SHORTEST: lenb64 = email.base64MIME.base64_len(s) *************** *** 366,370 **** return email.base64MIME.header_encode(s, cset) else: ! return email.quopriMIME.header_encode(s, cset) else: return s --- 368,372 ---- return email.base64MIME.header_encode(s, cset) else: ! return email.quopriMIME.header_encode(s, cset, maxlinelen=None) else: return s From bwarsaw@users.sourceforge.net Thu Mar 6 05:22:05 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Wed, 05 Mar 2003 21:22:05 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Generator.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv933 Modified Files: Generator.py Log Message: Merge of the folding-reimpl-branch. Specific changes, _handle_multipart(): Ensure that if the preamble exists but does not end in a newline, a newline is still added. Without this, the boundary separator will end up on the preamble line, breaking the MIME structure. _make_boundary(): Handle differences in the decimal point character based on the locale. Index: Generator.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Generator.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** Generator.py 14 Oct 2002 15:09:30 -0000 1.17 --- Generator.py 6 Mar 2003 05:22:02 -0000 1.18 *************** *** 5,10 **** """ - import time import re import random --- 5,11 ---- """ import re + import time + import locale import random *************** *** 13,16 **** --- 14,18 ---- from email.Header import Header + from email.Parser import NLCRE try: *************** *** 259,262 **** --- 261,272 ---- if msg.preamble is not None: self._fp.write(msg.preamble) + # If preamble is the empty string, the length of the split will be + # 1, but the last element will be the empty string. If it's + # anything else but does not end in a line separator, the length + # will be > 1 and not end in an empty string. We need to + # guarantee a newline after the preamble, but don't add too many. + plines = NLCRE.split(msg.preamble) + if plines <> [''] and plines[-1] <> '': + self._fp.write('\n') # First boundary is a bit different; it doesn't have a leading extra # newline. *************** *** 365,369 **** # Craft a random boundary. If text is given, ensure that the chosen # boundary doesn't appear in the text. ! boundary = ('=' * 15) + repr(random.random()).split('.')[1] + '==' if text is None: return boundary --- 375,380 ---- # Craft a random boundary. If text is given, ensure that the chosen # boundary doesn't appear in the text. ! dp = locale.localeconv().get('decimal_point', '.') ! boundary = ('=' * 15) + repr(random.random()).split(dp)[1] + '==' if text is None: return boundary From bwarsaw@users.sourceforge.net Thu Mar 6 05:25:04 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Wed, 05 Mar 2003 21:25:04 -0800 Subject: [Python-checkins] python/dist/src/Lib/email base64MIME.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv1659 Modified Files: base64MIME.py Log Message: Merge of the folding-reimpl-branch. Specific changes, Remove a senseless comment. Index: base64MIME.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/base64MIME.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** base64MIME.py 28 Sep 2002 20:59:12 -0000 1.5 --- base64MIME.py 6 Mar 2003 05:25:00 -0000 1.6 *************** *** 103,109 **** max_unencoded = _floordiv(max_encoded * 3, 4) - # BAW: Ben's original code used a step of max_unencoded, but I think it - # ought to be max_encoded. Otherwise, where's max_encoded used? I'm - # still not sure what the for i in range(0, len(header), max_unencoded): base64ed.append(b2a_base64(header[i:i+max_unencoded])) --- 103,106 ---- From bwarsaw@users.sourceforge.net Thu Mar 6 05:25:37 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Wed, 05 Mar 2003 21:25:37 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Parser.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv1848 Modified Files: Parser.py Log Message: Merge of the folding-reimpl-branch. Specific changes, Rename a constant. Index: Parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Parser.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** Parser.py 5 Nov 2002 21:44:06 -0000 1.19 --- Parser.py 6 Mar 2003 05:25:35 -0000 1.20 *************** *** 21,25 **** False = 0 ! nlcre = re.compile('\r\n|\r|\n') --- 21,25 ---- False = 0 ! NLCRE = re.compile('\r\n|\r|\n') *************** *** 177,181 **** # Find out what kind of line endings we're using start += len(mo.group('sep')) + len(mo.group('ws')) ! mo = nlcre.search(payload, start) if mo: start += len(mo.group(0)) --- 177,181 ---- # Find out what kind of line endings we're using start += len(mo.group('sep')) + len(mo.group('ws')) ! mo = NLCRE.search(payload, start) if mo: start += len(mo.group(0)) From bwarsaw@users.sourceforge.net Thu Mar 6 05:39:48 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Wed, 05 Mar 2003 21:39:48 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Header.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv5699 Modified Files: Header.py Log Message: Merge of the folding-reimpl-branch. Specific changes, _split(): New implementation of ASCII line splitting which should do a better job and not be subject to the various weird artifacts (bugs) reported. This should also do a better job of higher-level syntactic splits by trying first to split on semis, then commas, then whitespace. Use a Timbot-ly binary search for optimal non-ASCII split points for better packing of header lines. This also lets us remove one recursion call. Don't pass in firstline, but instead pass in the actual line length we're shooting for. Also pass in the list of split characters. encode(): Pass in the list of split characters so applications can have some control over what "higher level syntactic breaks" are. Also, decode_header(): Transform binascii.Errors which can occur when decoding a base64 RFC 2047 header with bogus data, into an email.Errors.HeaderParseError. Closes SF bug #696712. Index: Header.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Header.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** Header.py 30 Dec 2002 19:13:00 -0000 1.17 --- Header.py 6 Mar 2003 05:39:46 -0000 1.18 *************** *** 5,12 **** --- 5,14 ---- import re + import binascii from types import StringType, UnicodeType import email.quopriMIME import email.base64MIME + from email.Errors import HeaderParseError from email.Charset import Charset *************** *** 26,29 **** --- 28,32 ---- CRLF = '\r\n' NL = '\n' + SPACE = ' ' SPACE8 = ' ' * 8 EMPTYSTRING = '' *************** *** 48,51 **** --- 51,61 ---- ''', re.VERBOSE | re.IGNORECASE) + pcre = re.compile('([,;])') + + # Field name regexp, including trailing colon, but not separating whitespace, + # according to RFC 2822. Character range is from tilde to exclamation mark. + # For use with .match() + fcre = re.compile(r'[\041-\176]+:$') + *************** *** 62,65 **** --- 72,78 ---- header, otherwise a lower-case string containing the name of the character set specified in the encoded string. + + An email.Errors.HeaderParseError may be raised when certain decoding error + occurs (e.g. a base64 decoding exception). """ # If no encoding, just return the header *************** *** 86,95 **** charset, encoding = [s.lower() for s in parts[0:2]] encoded = parts[2] ! dec = '' if encoding == 'q': dec = email.quopriMIME.header_decode(encoded) elif encoding == 'b': ! dec = email.base64MIME.decode(encoded) ! else: dec = encoded --- 99,114 ---- charset, encoding = [s.lower() for s in parts[0:2]] encoded = parts[2] ! dec = None if encoding == 'q': dec = email.quopriMIME.header_decode(encoded) elif encoding == 'b': ! try: ! dec = email.base64MIME.decode(encoded) ! except binascii.Error: ! # Turn this into a higher level exception. BAW: Right ! # now we throw the lower level exception away but ! # when/if we get exception chaining, we'll preserve it. ! raise HeaderParseError ! if dec is None: dec = encoded *************** *** 127,131 **** class Header: ! def __init__(self, s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict'): """Create a MIME-compliant header that can contain many character sets. --- 146,151 ---- class Header: ! def __init__(self, s=None, charset=None, ! maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict'): """Create a MIME-compliant header that can contain many character sets. *************** *** 254,264 **** self._chunks.append((s, charset)) ! def _split(self, s, charset, firstline=False): # Split up a header safely for use with encode_chunks. splittable = charset.to_splittable(s) ! encoded = charset.from_splittable(splittable) elen = charset.encoded_header_len(encoded) ! ! if elen <= self._maxlinelen: return [(encoded, charset)] # If we have undetermined raw 8bit characters sitting in a byte --- 274,284 ---- self._chunks.append((s, charset)) ! def _split(self, s, charset, maxlinelen, splitchars): # Split up a header safely for use with encode_chunks. splittable = charset.to_splittable(s) ! encoded = charset.from_splittable(splittable, True) elen = charset.encoded_header_len(encoded) ! # If the line's encoded length first, just return it ! if elen <= maxlinelen: return [(encoded, charset)] # If we have undetermined raw 8bit characters sitting in a byte *************** *** 268,272 **** # be to not split the header at all, but that means they could go out # longer than maxlinelen. ! elif charset == '8bit': return [(s, charset)] # BAW: I'm not sure what the right test here is. What we're trying to --- 288,292 ---- # be to not split the header at all, but that means they could go out # longer than maxlinelen. ! if charset == '8bit': return [(s, charset)] # BAW: I'm not sure what the right test here is. What we're trying to *************** *** 281,377 **** # although it's possible that other charsets may also benefit from the # higher-level syntactic breaks. - # elif charset == 'us-ascii': ! return self._ascii_split(s, charset, firstline) # BAW: should we use encoded? elif elen == len(s): # We can split on _maxlinelen boundaries because we know that the # encoding won't change the size of the string ! splitpnt = self._maxlinelen first = charset.from_splittable(splittable[:splitpnt], False) last = charset.from_splittable(splittable[splitpnt:], False) else: ! # Divide and conquer. ! halfway = _floordiv(len(splittable), 2) ! first = charset.from_splittable(splittable[:halfway], False) ! last = charset.from_splittable(splittable[halfway:], False) ! # Do the split ! return self._split(first, charset, firstline) + \ ! self._split(last, charset) ! def _ascii_split(self, s, charset, firstline): ! # Attempt to split the line at the highest-level syntactic break ! # possible. Note that we don't have a lot of smarts about field ! # syntax; we just try to break on semi-colons, then whitespace. ! rtn = [] ! lines = s.splitlines() ! while lines: ! line = lines.pop(0) ! if firstline: ! maxlinelen = self._firstlinelen ! firstline = False ! else: ! #line = line.lstrip() ! maxlinelen = self._maxlinelen ! # Short lines can remain unchanged ! if len(line.replace('\t', SPACE8)) <= maxlinelen: ! rtn.append(line) ! else: ! oldlen = len(line) ! # Try to break the line on semicolons, but if that doesn't ! # work, try to split on folding whitespace. ! while len(line) > maxlinelen: ! i = line.rfind(';', 0, maxlinelen) ! if i < 0: ! break ! rtn.append(line[:i] + ';') ! line = line[i+1:] ! # Is the remaining stuff still longer than maxlinelen? ! if len(line) <= maxlinelen: ! # Splitting on semis worked ! rtn.append(line) ! continue ! # Splitting on semis didn't finish the job. If it did any ! # work at all, stick the remaining junk on the front of the ! # `lines' sequence and let the next pass do its thing. ! if len(line) <> oldlen: ! lines.insert(0, line) ! continue ! # Otherwise, splitting on semis didn't help at all. ! parts = re.split(r'(\s+)', line) ! if len(parts) == 1 or (len(parts) == 3 and ! parts[0].endswith(':')): ! # This line can't be split on whitespace. There's now ! # little we can do to get this into maxlinelen. BAW: ! # We're still potentially breaking the RFC by possibly ! # allowing lines longer than the absolute maximum of 998 ! # characters. For now, let it slide. ! # ! # len(parts) will be 1 if this line has no `Field: ' ! # prefix, otherwise it will be len(3). ! rtn.append(line) ! continue ! # There is whitespace we can split on. ! first = parts.pop(0) ! sublines = [first] ! acc = len(first) ! while parts: ! len0 = len(parts[0]) ! len1 = len(parts[1]) ! if acc + len0 + len1 <= maxlinelen: ! 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 ! if first <> '': ! rtn.append(EMPTYSTRING.join(sublines)) ! del parts[0] ! first = parts.pop(0) ! sublines = [first] ! acc = len(first) ! rtn.append(EMPTYSTRING.join(sublines)) ! return [(chunk, charset) for chunk in rtn] def _encode_chunks(self, newchunks): --- 301,328 ---- # although it's possible that other charsets may also benefit from the # higher-level syntactic breaks. elif charset == 'us-ascii': ! return self._split_ascii(s, charset, maxlinelen, splitchars) # BAW: should we use encoded? elif elen == len(s): # We can split on _maxlinelen boundaries because we know that the # encoding won't change the size of the string ! splitpnt = maxlinelen first = charset.from_splittable(splittable[:splitpnt], False) last = charset.from_splittable(splittable[splitpnt:], False) else: ! # Binary search for split point ! first, last = _binsplit(splittable, charset, maxlinelen) ! # first is of the proper length so just wrap it in the appropriate ! # chrome. last must be recursively split. ! fsplittable = charset.to_splittable(first) ! fencoded = charset.from_splittable(fsplittable, True) ! chunk = [(fencoded, charset)] ! return chunk + self._split(last, charset, self._maxlinelen, splitchars) ! def _split_ascii(self, s, charset, firstlen, splitchars): ! line = _split_ascii(s, firstlen, self._maxlinelen, ! self._continuation_ws, splitchars) ! lines = line.splitlines() ! return zip(lines, [charset]*len(lines)) def _encode_chunks(self, newchunks): *************** *** 397,409 **** for header, charset in newchunks: if charset is None or charset.header_encoding is None: ! # There's no encoding for this chunk's charsets ! _max_append(chunks, header, self._maxlinelen) else: ! _max_append(chunks, charset.header_encode(header), ! self._maxlinelen, ' ') joiner = NL + self._continuation_ws return joiner.join(chunks) ! def encode(self): """Encode a message header into an RFC-compliant format. --- 348,359 ---- for header, charset in newchunks: if charset is None or charset.header_encoding is None: ! s = header else: ! s = charset.header_encode(header) ! _max_append(chunks, s, self._maxlinelen, ' ') joiner = NL + self._continuation_ws return joiner.join(chunks) ! def encode(self, splitchars=';, '): """Encode a message header into an RFC-compliant format. *************** *** 422,428 **** If the given charset is not known or an error occurs during conversion, this function will return the header untouched. """ newchunks = [] for s, charset in self._chunks: ! newchunks += self._split(s, charset, True) return self._encode_chunks(newchunks) --- 372,482 ---- If the given charset is not known or an error occurs during conversion, this function will return the header untouched. + + Optional splitchars is a string containing characters to split long + ASCII lines on, in rough support of RFC 2822's `highest level + syntactic breaks'. This doesn't affect RFC 2047 encoded lines. """ newchunks = [] + maxlinelen = self._firstlinelen + lastlen = 0 for s, charset in self._chunks: ! # The first bit of the next chunk should be just long enough to ! # fill the next line. Don't forget the space separating the ! # encoded words. ! targetlen = maxlinelen - lastlen - 1 ! if targetlen < charset.encoded_header_len(''): ! # Stick it on the next line ! targetlen = maxlinelen ! newchunks += self._split(s, charset, targetlen, splitchars) ! lastchunk, lastcharset = newchunks[-1] ! lastlen = lastcharset.encoded_header_len(lastchunk) return self._encode_chunks(newchunks) + + + + def _split_ascii(s, firstlen, restlen, continuation_ws, splitchars): + lines = [] + maxlen = firstlen + for line in s.splitlines(): + if len(line) < maxlen: + lines.append(line) + maxlen = restlen + continue + # Attempt to split the line at the highest-level syntactic break + # possible. Note that we don't have a lot of smarts about field + # syntax; we just try to break on semi-colons, then commas, then + # whitespace. + for ch in splitchars: + if line.find(ch) >= 0: + break + else: + # There's nothing useful to split the line on, not even spaces, so + # just append this line unchanged + lines.append(line) + maxlen = restlen + continue + # Now split the line on the character plus trailing whitespace + cre = re.compile(r'%s\s*' % ch) + if ch in ';,': + eol = ch + else: + eol = '' + joiner = eol + ' ' + joinlen = len(joiner) + wslen = len(continuation_ws.replace('\t', SPACE8)) + this = [] + linelen = 0 + for part in cre.split(line): + curlen = linelen + max(0, len(this)-1) * joinlen + partlen = len(part) + onfirstline = not lines + # We don't want to split after the field name, if we're on the + # first line and the field name is present in the header string. + if ch == ' ' and onfirstline and \ + len(this) == 1 and fcre.match(this[0]): + this.append(part) + linelen += partlen + elif curlen + partlen > maxlen: + if this: + lines.append(joiner.join(this) + eol) + this = [part] + linelen = wslen + partlen + maxlen = restlen + else: + this.append(part) + linelen += partlen + # Put any left over parts on a line by themselves + if this: + lines.append(joiner.join(this)) + linejoiner = '\n' + continuation_ws + return linejoiner.join(lines) + + + + def _binsplit(splittable, charset, maxlinelen): + i = 0 + j = len(splittable) + while i < j: + # Invariants: + # 1. splittable[:k] fits for all k <= i (note that we *assume*, + # at the start, that splittable[:0] fits). + # 2. splittable[:k] does not fit for any k > j (at the start, + # this means we shouldn't look at any k > len(splittable)). + # 3. We don't know about splittable[:k] for k in i+1..j. + # 4. We want to set i to the largest k that fits, with i <= k <= j. + # + m = (i+j+1) >> 1 # ceiling((i+j)/2); i < m <= j + chunk = charset.from_splittable(splittable[:m], True) + chunklen = charset.encoded_header_len(chunk) + if chunklen <= maxlinelen: + # m is acceptable, so is a new lower bound. + i = m + else: + # m is not acceptable, so final i must be < j. + j = m - 1 + # i == j. Invariant #1 implies that splittable[:i] fits, and + # invariant #2 implies that splittable[:i+1] does not fit, so i + # is what we're looking for. + first = charset.from_splittable(splittable[:i], False) + last = charset.from_splittable(splittable[i:], False) + return first, last From bwarsaw@users.sourceforge.net Thu Mar 6 05:40:48 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Wed, 05 Mar 2003 21:40:48 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv5915 Modified Files: test_email.py Log Message: Merge of the folding-reimpl-branch. Specific changes, Update tests for email 2.5. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** test_email.py 2 Jan 2003 22:48:36 -0000 1.29 --- test_email.py 6 Mar 2003 05:40:45 -0000 1.30 *************** *** 2,14 **** # email package unit tests - import sys import os import time - import unittest import base64 import difflib from cStringIO import StringIO from types import StringType, ListType - import warnings import email --- 2,14 ---- # email package unit tests import os + import sys import time import base64 import difflib + import unittest + import warnings from cStringIO import StringIO from types import StringType, ListType import email *************** *** 567,571 **** cz_head = "Finan\xe8ni metropole se hroutily pod tlakem jejich d\xf9vtipu.. " utf8_head = u"\u6b63\u78ba\u306b\u8a00\u3046\u3068\u7ffb\u8a33\u306f\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u4e00\u90e8\u306f\u30c9\u30a4\u30c4\u8a9e\u3067\u3059\u304c\u3001\u3042\u3068\u306f\u3067\u305f\u3089\u3081\u3067\u3059\u3002\u5b9f\u969b\u306b\u306f\u300cWenn ist das Nunstuck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput.\u300d\u3068\u8a00\u3063\u3066\u3044\u307e\u3059\u3002".encode("utf-8") ! h = Header(g_head, g) h.append(cz_head, cz) h.append(utf8_head, utf8) --- 567,571 ---- cz_head = "Finan\xe8ni metropole se hroutily pod tlakem jejich d\xf9vtipu.. " utf8_head = u"\u6b63\u78ba\u306b\u8a00\u3046\u3068\u7ffb\u8a33\u306f\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u4e00\u90e8\u306f\u30c9\u30a4\u30c4\u8a9e\u3067\u3059\u304c\u3001\u3042\u3068\u306f\u3067\u305f\u3089\u3081\u3067\u3059\u3002\u5b9f\u969b\u306b\u306f\u300cWenn ist das Nunstuck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput.\u300d\u3068\u8a00\u3063\u3066\u3044\u307e\u3059\u3002".encode("utf-8") ! h = Header(g_head, g, header_name='Subject') h.append(cz_head, cz) h.append(utf8_head, utf8) *************** *** 575,612 **** g = Generator(sfp) g.flatten(msg) ! eq(sfp.getvalue(), '''\ ! Subject: =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_eine?= ! =?iso-8859-1?q?m_Foerderband_komfortabel_den_Korridor_ent?= ! =?iso-8859-1?q?lang=2C_an_s=FCdl=FCndischen_Wandgem=E4lden_vorbei?= ! =?iso-8859-1?q?=2C_gegen_die_rotierenden_Klingen_bef=F6rdert=2E_?= ! =?iso-8859-2?q?Finan=E8ni_metropole_se_hroutil?= ! =?iso-8859-2?q?y_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= ! =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv?= ! =?utf-8?b?44GV44KM44Gm44GE44G+44Gb44KT44CC5LiA?= ! =?utf-8?b?6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM?= ! =?utf-8?b?44CB44GC44Go44Gv44Gn44Gf44KJ44KB44Gn?= ! =?utf-8?b?44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBpc3QgZGE=?= ! =?utf-8?q?s_Nunstuck_git_und?= ! =?utf-8?q?_Slotermeyer=3F_Ja!_Beiherhund_das_Ode?= ! =?utf-8?q?r_die_Flipperwaldt?= ! =?utf-8?b?IGdlcnNwdXQu44CN44Go6KiA44Gj44Gm44GE44G+44GZ44CC?= ! ''') ! eq(h.encode(), '''\ ! =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_eine?= ! =?iso-8859-1?q?m_Foerderband_komfortabel_den_Korridor_ent?= ! =?iso-8859-1?q?lang=2C_an_s=FCdl=FCndischen_Wandgem=E4lden_vorbei?= ! =?iso-8859-1?q?=2C_gegen_die_rotierenden_Klingen_bef=F6rdert=2E_?= ! =?iso-8859-2?q?Finan=E8ni_metropole_se_hroutil?= ! =?iso-8859-2?q?y_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= ! =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv?= ! =?utf-8?b?44GV44KM44Gm44GE44G+44Gb44KT44CC5LiA?= ! =?utf-8?b?6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM?= ! =?utf-8?b?44CB44GC44Go44Gv44Gn44Gf44KJ44KB44Gn?= ! =?utf-8?b?44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBpc3QgZGE=?= ! =?utf-8?q?s_Nunstuck_git_und?= ! =?utf-8?q?_Slotermeyer=3F_Ja!_Beiherhund_das_Ode?= ! =?utf-8?q?r_die_Flipperwaldt?= ! =?utf-8?b?IGdlcnNwdXQu44CN44Go6KiA44Gj44Gm44GE44G+44GZ44CC?=''') def test_long_header_encode(self): --- 575,604 ---- g = Generator(sfp) g.flatten(msg) ! eq(sfp.getvalue(), """\ ! Subject: =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?= ! =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndi?= ! =?iso-8859-1?q?schen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kling?= ! =?iso-8859-1?q?en_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_met?= ! =?iso-8859-2?q?ropole_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= ! =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE?= ! =?utf-8?b?44G+44Gb44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB?= ! =?utf-8?b?44GC44Go44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CM?= ! =?utf-8?q?Wenn_ist_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das?= ! =?utf-8?b?IE9kZXIgZGllIEZsaXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBow==?= ! =?utf-8?b?44Gm44GE44G+44GZ44CC?= ! """) ! eq(h.encode(), """\ ! =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?= ! =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndi?= ! =?iso-8859-1?q?schen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kling?= ! =?iso-8859-1?q?en_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_met?= ! =?iso-8859-2?q?ropole_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= ! =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE?= ! =?utf-8?b?44G+44Gb44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB?= ! =?utf-8?b?44GC44Go44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CM?= ! =?utf-8?q?Wenn_ist_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das?= ! =?utf-8?b?IE9kZXIgZGllIEZsaXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBow==?= ! =?utf-8?b?44Gm44GE44G+44GZ44CC?=""") def test_long_header_encode(self): *************** *** 713,722 **** eq = self.ndiffAssertEqual msg = Message() ! h = Header('Britische Regierung gibt', 'iso-8859-1') h.append('gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte') msg['Subject'] = h eq(msg.as_string(), """\ ! Subject: =?iso-8859-1?q?Britische_Regierung_gibt?= ! =?iso-8859-1?q?gr=FCnes_Licht_f=FCr_Offshore-Windkraftprojekte?= """) --- 705,715 ---- eq = self.ndiffAssertEqual msg = Message() ! h = Header('Britische Regierung gibt', 'iso-8859-1', ! header_name='Subject') h.append('gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte') msg['Subject'] = h eq(msg.as_string(), """\ ! Subject: =?iso-8859-1?q?Britische_Regierung_gibt?= =?iso-8859-1?q?gr=FCnes?= ! =?iso-8859-1?q?_Licht_f=FCr_Offshore-Windkraftprojekte?= """) *************** *** 731,734 **** --- 724,769 ---- """) + def test_long_to_header(self): + eq = self.ndiffAssertEqual + to = '"Someone Test #A" ,,"Someone Test #B" , "Someone Test #C" , "Someone Test #D" ' + msg = Message() + msg['To'] = to + eq(msg.as_string(0), '''\ + To: "Someone Test #A" , , + \t"Someone Test #B" , + \t"Someone Test #C" , + \t"Someone Test #D" + + ''') + + def test_long_line_after_append(self): + eq = self.ndiffAssertEqual + s = 'This is an example of string which has almost the limit of header length.' + h = Header(s) + h.append('Add another line.') + eq(h.encode(), """\ + This is an example of string which has almost the limit of header length. + Add another line.""") + + def test_shorter_line_with_append(self): + eq = self.ndiffAssertEqual + s = 'This is a shorter line.' + h = Header(s) + h.append('Add another sentence. (Surprise?)') + eq(h.encode(), + 'This is a shorter line. Add another sentence. (Surprise?)') + + def test_long_field_name(self): + eq = self.ndiffAssertEqual + fn = 'X-Very-Very-Very-Long-Header-Name' + gs = "Die Mieter treten hier ein werden mit einem Foerderband komfortabel den Korridor entlang, an s\xfcdl\xfcndischen Wandgem\xe4lden vorbei, gegen die rotierenden Klingen bef\xf6rdert. " + h = Header(gs, 'iso-8859-1', header_name=fn) + # BAW: this seems broken because the first line is too long + eq(h.encode(), """\ + =?iso-8859-1?q?Die_Mieter_treten_hier_?= + =?iso-8859-1?q?ein_werden_mit_einem_Foerderband_komfortabel_den_Korridor_?= + =?iso-8859-1?q?entlang=2C_an_s=FCdl=FCndischen_Wandgem=E4lden_vorbei=2C_g?= + =?iso-8859-1?q?egen_die_rotierenden_Klingen_bef=F6rdert=2E_?=""") + *************** *** 1310,1313 **** --- 1345,1385 ---- self.assertEqual(sfp.getvalue(), text) + def test_no_nl_preamble(self): + eq = self.ndiffAssertEqual + msg = Message() + msg['From'] = 'aperson@dom.ain' + msg['To'] = 'bperson@dom.ain' + msg['Subject'] = 'Test' + msg.preamble = 'MIME message' + msg.epilogue = '' + msg1 = MIMEText('One') + msg2 = MIMEText('Two') + msg.add_header('Content-Type', 'multipart/mixed', boundary='BOUNDARY') + msg.attach(msg1) + msg.attach(msg2) + eq(msg.as_string(), """\ + 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-- + """) + def test_default_type(self): eq = self.assertEqual *************** *** 2182,2186 **** eq(h.encode(), 'Hello World!') h.append(' Goodbye World!') ! eq(h.encode(), 'Hello World! Goodbye World!') def test_simple_surprise(self): --- 2254,2258 ---- eq(h.encode(), 'Hello World!') h.append(' Goodbye World!') ! eq(h.encode(), 'Hello World! Goodbye World!') def test_simple_surprise(self): *************** *** 2189,2193 **** eq(h.encode(), 'Hello World!') h.append('Goodbye World!') ! eq(h.encode(), 'Hello World!Goodbye World!') def test_header_needs_no_decoding(self): --- 2261,2265 ---- eq(h.encode(), 'Hello World!') h.append('Goodbye World!') ! eq(h.encode(), 'Hello World! Goodbye World!') def test_header_needs_no_decoding(self): *************** *** 2198,2202 **** h = Header("I am the very model of a modern Major-General; I've information vegetable, animal, and mineral; I know the kings of England, and I quote the fights historical from Marathon to Waterloo, in order categorical; I'm very well acquainted, too, with matters mathematical; I understand equations, both the simple and quadratical; about binomial theorem I'm teeming with a lot o' news, with many cheerful facts about the square of the hypotenuse.", maxlinelen=76) ! for l in h.encode().split('\n '): self.failUnless(len(l) <= 76) --- 2270,2274 ---- h = Header("I am the very model of a modern Major-General; I've information vegetable, animal, and mineral; I know the kings of England, and I quote the fights historical from Marathon to Waterloo, in order categorical; I'm very well acquainted, too, with matters mathematical; I understand equations, both the simple and quadratical; about binomial theorem I'm teeming with a lot o' news, with many cheerful facts about the square of the hypotenuse.", maxlinelen=76) ! for l in h.encode(splitchars=' ').split('\n '): self.failUnless(len(l) <= 76) *************** *** 2213,2231 **** h.append(utf8_head, utf8) enc = h.encode() ! eq(enc, """=?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_eine?= ! =?iso-8859-1?q?m_Foerderband_komfortabel_den_Korridor_ent?= ! =?iso-8859-1?q?lang=2C_an_s=FCdl=FCndischen_Wandgem=E4lden_vorbei?= ! =?iso-8859-1?q?=2C_gegen_die_rotierenden_Klingen_bef=F6rdert=2E_?= ! =?iso-8859-2?q?Finan=E8ni_metropole_se_hroutil?= ! =?iso-8859-2?q?y_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= ! =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv?= ! =?utf-8?b?44GV44KM44Gm44GE44G+44Gb44KT44CC5LiA?= ! =?utf-8?b?6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM?= ! =?utf-8?b?44CB44GC44Go44Gv44Gn44Gf44KJ44KB44Gn?= ! =?utf-8?b?44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBpc3QgZGE=?= ! =?utf-8?q?s_Nunstuck_git_und?= ! =?utf-8?q?_Slotermeyer=3F_Ja!_Beiherhund_das_Ode?= ! =?utf-8?q?r_die_Flipperwaldt?= ! =?utf-8?b?IGdlcnNwdXQu44CN44Go6KiA44Gj44Gm44GE44G+44GZ44CC?=""") eq(decode_header(enc), [(g_head, "iso-8859-1"), (cz_head, "iso-8859-2"), --- 2285,2300 ---- h.append(utf8_head, utf8) enc = h.encode() ! eq(enc, """\ ! =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerderband_ko?= ! =?iso-8859-1?q?mfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndischen_Wan?= ! =?iso-8859-1?q?dgem=E4lden_vorbei=2C_gegen_die_rotierenden_Klingen_bef=F6?= ! =?iso-8859-1?q?rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_metropole_se_hroutily?= ! =?iso-8859-2?q?_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= =?utf-8?b?5q2j56K6?= ! =?utf-8?b?44Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE44G+44Gb44KT44CC?= ! =?utf-8?b?5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB44GC44Go44Gv44Gn?= ! =?utf-8?b?44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBpc3QgZGFz?= ! =?utf-8?q?_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das_Oder_die_Fl?= ! =?utf-8?b?aXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBo+OBpuOBhOOBvuOBmQ==?= ! =?utf-8?b?44CC?=""") eq(decode_header(enc), [(g_head, "iso-8859-1"), (cz_head, "iso-8859-2"), *************** *** 2318,2321 **** --- 2387,2414 ---- h.append(x, errors='replace') eq(str(h), x) + + def test_encoded_adjacent_nonencoded(self): + eq = self.assertEqual + h = Header() + h.append('hello', 'iso-8859-1') + h.append('world') + s = h.encode() + eq(s, '=?iso-8859-1?q?hello?= world') + h = make_header(decode_header(s)) + eq(h.encode(), s) + + def test_whitespace_eater(self): + eq = self.assertEqual + s = 'Subject: =?koi8-r?b?8NLP18XSy8EgzsEgxsnOwczYztk=?= =?koi8-r?q?=CA?= zz.' + parts = decode_header(s) + eq(parts, [('Subject:', None), ('\xf0\xd2\xcf\xd7\xc5\xd2\xcb\xc1 \xce\xc1 \xc6\xc9\xce\xc1\xcc\xd8\xce\xd9\xca', 'koi8-r'), ('zz.', None)]) + hdr = make_header(parts) + eq(hdr.encode(), + 'Subject: =?koi8-r?b?8NLP18XSy8EgzsEgxsnOwczYztnK?= zz.') + + def test_broken_base64_header(self): + raises = self.assertRaises + s = 'Subject: =?EUC-KR?B?CSixpLDtKSC/7Liuvsax4iC6uLmwMcijIKHaILzSwd/H0SC8+LCjwLsgv7W/+Mj3IQ?=' + raises(Errors.HeaderParseError, decode_header, s) From bwarsaw@users.sourceforge.net Thu Mar 6 05:41:09 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Wed, 05 Mar 2003 21:41:09 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email_codecs.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv6041 Modified Files: test_email_codecs.py Log Message: Merge of the folding-reimpl-branch. Specific changes, Update tests for email 2.5. Index: test_email_codecs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email_codecs.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_email_codecs.py 23 Jul 2002 19:03:42 -0000 1.3 --- test_email_codecs.py 6 Mar 2003 05:41:07 -0000 1.4 *************** *** 27,31 **** h.append(jhello, j) h.append(ghello, g) ! eq(h.encode(), 'Hello World! =?iso-2022-jp?b?GyRCJU8lbSE8JW8hPCVrJUkhKhsoQg==?=\n =?iso-8859-1?q?Gr=FC=DF_Gott!?=') eq(decode_header(h.encode()), [('Hello World!', None), --- 27,38 ---- h.append(jhello, j) h.append(ghello, g) ! # BAW: This used to -- and maybe should -- fold the two iso-8859-1 ! # chunks into a single encoded word. However it doesn't violate the ! # standard to have them as two encoded chunks and maybe it's ! # reasonable for each .append() call to result in a separate ! # encoded word. ! eq(h.encode(), """\ ! Hello World! =?iso-2022-jp?b?GyRCJU8lbSE8JW8hPCVrJUkhKhsoQg==?= ! =?iso-8859-1?q?Gr=FC=DF?= =?iso-8859-1?q?_Gott!?=""") eq(decode_header(h.encode()), [('Hello World!', None), *************** *** 36,56 **** # test a very long header enc = h.encode() ! # BAW: The following used to pass. Sadly, the test afterwards is what ! # happens now. I've no idea which is right. Please, any Japanese and ! # RFC 2047 experts, please verify! ! ## eq(enc, '''\ ! ##=?iso-2022-jp?b?dGVzdC1qYSAbJEIkWEVqOUYkNSRsJD8lYRsoQg==?= ! ## =?iso-2022-jp?b?GyRCITwlayRPO0oycTxUJE4+NRsoQg==?= ! ## =?iso-2022-jp?b?GyRCRyckckJUJEMkRiQkJF4kORsoQg==?=''') ! eq(enc, """\ ! =?iso-2022-jp?b?dGVzdC1qYSAbJEIkWEVqOUYkNSRsJD8lYRsoQg==?= ! =?iso-2022-jp?b?GyRCITwlayRPO0oycTxUJE4+NUcnJHJCVCRDJEYkJCReJDkbKEI=?=""") ! # BAW: same deal here. :( ! ## self.assertEqual( ! ## decode_header(enc), ! ## [("test-ja \x1b$B$XEj9F$5$l$?%a\x1b(B\x1b$B!<%k$O;J2q5\x1b(B\x1b$BG'$rBT$C$F$$$^$9\x1b(B", 'iso-2022-jp')]) ! self.assertEqual( ! decode_header(enc), ! [("test-ja \x1b$B$XEj9F$5$l$?%a\x1b(B\x1b$B!<%k$O;J2q5G'$rBT$C$F$$$^$9\x1b(B", 'iso-2022-jp')]) --- 43,52 ---- # test a very long header enc = h.encode() ! # TK: splitting point may differ by codec design and/or Header encoding ! eq(enc , """\ ! =?iso-2022-jp?b?dGVzdC1qYSAbJEIkWEVqOUYkNSRsJD8lYSE8JWskTztKGyhC?= ! =?iso-2022-jp?b?GyRCMnE8VCROPjVHJyRyQlQkQyRGJCQkXiQ5GyhC?=""") ! # TK: full decode comparison ! eq(h.__unicode__().encode('euc-jp'), long) From bwarsaw@users.sourceforge.net Thu Mar 6 06:06:56 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Wed, 05 Mar 2003 22:06:56 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib emailheaders.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv12065 Modified Files: emailheaders.tex Log Message: Describe the new Header.encode() argument "splitchars". Index: emailheaders.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailheaders.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** emailheaders.tex 30 Dec 2002 19:17:37 -0000 1.3 --- emailheaders.tex 6 Mar 2003 06:06:54 -0000 1.4 *************** *** 110,117 **** \end{methoddesc} ! \begin{methoddesc}[Header]{encode}{} Encode a message header into an RFC-compliant format, possibly wrapping long lines and encapsulating non-\ASCII{} parts in base64 or ! quoted-printable encodings. \end{methoddesc} --- 110,120 ---- \end{methoddesc} ! \begin{methoddesc}[Header]{encode}{\optional{splitchars}} Encode a message header into an RFC-compliant format, possibly wrapping long lines and encapsulating non-\ASCII{} parts in base64 or ! quoted-printable encodings. Optional \var{splitchars} is a string ! containing characters to split long ASCII lines on, in rough support ! of \rfc{2822}'s \emph{highest level syntactic breaks}. This doesn't ! affect \rfc{2047} encoded lines. \end{methoddesc} From bwarsaw@users.sourceforge.net Thu Mar 6 06:07:37 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Wed, 05 Mar 2003 22:07:37 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib emailcharsets.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv12253 Modified Files: emailcharsets.tex Log Message: Describe Charset.__repr__(). Index: emailcharsets.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailcharsets.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** emailcharsets.tex 10 Oct 2002 15:23:38 -0000 1.2 --- emailcharsets.tex 6 Mar 2003 06:07:34 -0000 1.3 *************** *** 178,181 **** --- 178,182 ---- \begin{methoddesc}[Charset]{__str__}{} Returns \var{input_charset} as a string coerced to lower case. + \method{__repr__()} is an alias for \method{__str__()}. \end{methoddesc} From bwarsaw@users.sourceforge.net Thu Mar 6 06:37:44 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Wed, 05 Mar 2003 22:37:44 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Header.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv20207 Modified Files: Header.py Log Message: decode_header(): Typo when appending an unencoded chunk to the previous unencoded chunk (e.g. when they appear on separate lines). Closes the 2nd bug in SF #640110 (the first one's already been fixed). Index: Header.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Header.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** Header.py 6 Mar 2003 05:39:46 -0000 1.18 --- Header.py 6 Mar 2003 06:37:42 -0000 1.19 *************** *** 93,97 **** # Should we continue a long line? if decoded and decoded[-1][1] is None: ! decoded[-1] = (decoded[-1][0] + dec, None) else: decoded.append((unenc, None)) --- 93,97 ---- # Should we continue a long line? if decoded and decoded[-1][1] is None: ! decoded[-1] = (decoded[-1][0] + SPACE + unenc, None) else: decoded.append((unenc, None)) From bwarsaw@users.sourceforge.net Thu Mar 6 06:38:31 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Wed, 05 Mar 2003 22:38:31 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv20434 Modified Files: test_email.py Log Message: test_rfc2047_multiline(): Test case for SF bug #640110. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** test_email.py 6 Mar 2003 05:40:45 -0000 1.30 --- test_email.py 6 Mar 2003 06:38:29 -0000 1.31 *************** *** 1194,1197 **** --- 1194,1211 ---- '=?iso-8859-2?b?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=') + def test_rfc2047_multiline(self): + eq = self.assertEqual + s = """Re: =?mac-iceland?q?r=8Aksm=9Arg=8Cs?= baz + foo bar =?mac-iceland?q?r=8Aksm=9Arg=8Cs?=""" + dh = decode_header(s) + eq(dh, [ + ('Re:', None), + ('r\x8aksm\x9arg\x8cs', 'mac-iceland'), + ('baz foo bar', None), + ('r\x8aksm\x9arg\x8cs', 'mac-iceland')]) + eq(str(make_header(dh)), + """Re: =?mac-iceland?q?r=8Aksm=9Arg=8Cs?= baz foo bar + =?mac-iceland?q?r=8Aksm=9Arg=8Cs?=""") + From python@rcn.com Thu Mar 6 10:05:01 2003 From: python@rcn.com (Raymond Hettinger) Date: Thu, 6 Mar 2003 05:05:01 -0500 Subject: [Python-checkins] python/dist/src/Lib timeit.py,NONE,1.1 References: Message-ID: <000b01c2e3c7$da614500$125ffea9@oemcomputer> > def reindent(src, indent): > return ("\n" + " "*indent).join(src.split("\n")) Can this be simplified to: return src.replace("\n", "\n" + " "*indent) Raymond Hettinger From sjoerd@users.sourceforge.net Thu Mar 6 12:53:09 2003 From: sjoerd@users.sourceforge.net (sjoerd@users.sourceforge.net) Date: Thu, 06 Mar 2003 04:53:09 -0800 Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c,2.182,2.183 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv31032 Modified Files: unicodeobject.c Log Message: Removed superfluous \r. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.182 retrieving revision 2.183 diff -C2 -d -r2.182 -r2.183 *** unicodeobject.c 11 Feb 2003 23:05:37 -0000 2.182 --- unicodeobject.c 6 Mar 2003 12:53:07 -0000 2.183 *************** *** 3257,3261 **** goto onError; } ! Py_XDECREF(x); if (x!=Py_None) /* it worked => adjust input pointer */ ++p; --- 3257,3261 ---- goto onError; } ! Py_XDECREF(x); if (x!=Py_None) /* it worked => adjust input pointer */ ++p; From gvanrossum@users.sourceforge.net Thu Mar 6 13:09:13 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 06 Mar 2003 05:09:13 -0800 Subject: [Python-checkins] python/dist/src/Lib timeit.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv4502 Modified Files: timeit.py Log Message: Simpler way to write reindent(), suggested by Raymond H. Index: timeit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/timeit.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** timeit.py 6 Mar 2003 03:02:10 -0000 1.3 --- timeit.py 6 Mar 2003 13:09:09 -0000 1.4 *************** *** 85,89 **** def reindent(src, indent): """Helper to reindent a multi-line statement.""" ! return ("\n" + " "*indent).join(src.split("\n")) class Timer: --- 85,89 ---- def reindent(src, indent): """Helper to reindent a multi-line statement.""" ! return src.replace("\n", "\n" + " "*indent) class Timer: From webmaster@pferdemarkt.ws Thu Mar 6 14:13:06 2003 From: webmaster@pferdemarkt.ws (webmaster@pferdemarkt.ws) Date: Thu, 6 Mar 2003 06:13:06 -0800 Subject: [Python-checkins] Pferdemarkt.ws informiert! Newsletter 03/2003 http://www.pferdemarkt.ws Message-ID: <200303061413.GAA26288@eagle.he.net> http://www.pferdemarkt.ws Wir sind in 2003 erfolgreich in des neue \"Pferdejahr 2003 gestartet. Für den schnellen Erfolg unseres Marktes möchten wir uns bei Ihnen bedanken. Heute am 06.03.2003 sind wir gut 2 Monate Online! Täglich wächst unsere Datenbank um 30 Neue Angebote. Stellen auch Sie als Privatperson Ihre zu verkaufenden Pferde direkt und vollkommen kostenlos ins Internet. Zur besseren Sichtbarmachung Ihrer Angebote können Sie bis zu ein Bild zu Ihrer Pferdeanzeige kostenlos einstellen! Wollen Sie direkt auf die erste Seite, dann können wir Ihnen unser Bonussystem empfehlen. klicken Sie hier: http://www.pferdemarkt.ws/bestellung.html Ihr http://Pferdemarkt.ws Team Klicken Sie hier um sich direkt einzuloggen http://www.Pferdemarkt.ws Kostenlos Anbieten, Kostenlos Suchen! Direkt von Privat zu Privat! Haben Sie noch Fragen mailto: webmaster@pferdemarkt.ws From bwarsaw@users.sourceforge.net Thu Mar 6 16:10:34 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Thu, 06 Mar 2003 08:10:34 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Header.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv22423 Modified Files: Header.py Log Message: __unicode__(): When converting to a unicode string, we need to preserve spaces in the encoded/unencoded word boundaries. RFC 2047 is ambiguous here, but most people expect the space to be preserved. Really closes SF bug # 640110. Index: Header.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Header.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** Header.py 6 Mar 2003 06:37:42 -0000 1.19 --- Header.py 6 Mar 2003 16:10:30 -0000 1.20 *************** *** 29,34 **** --- 29,36 ---- NL = '\n' SPACE = ' ' + USPACE = u' ' SPACE8 = ' ' * 8 EMPTYSTRING = '' + UEMPTYSTRING = u'' MAXLINELEN = 76 *************** *** 205,211 **** def __unicode__(self): """Helper for the built-in unicode function.""" ! # charset item is a Charset instance so we need to stringify it. ! uchunks = [unicode(s, str(charset)) for s, charset in self._chunks] ! return u''.join(uchunks) # Rich comparison operators for equality only. BAW: does it make sense to --- 207,228 ---- def __unicode__(self): """Helper for the built-in unicode function.""" ! uchunks = [] ! lastcs = None ! for s, charset in self._chunks: ! # We must preserve spaces between encoded and non-encoded word ! # boundaries, which means for us we need to add a space when we go ! # from a charset to None/us-ascii, or from None/us-ascii to a ! # charset. Only do this for the second and subsequent chunks. ! nextcs = charset ! if uchunks: ! if lastcs is not None: ! if nextcs is None or nextcs == 'us-ascii': ! uchunks.append(USPACE) ! nextcs = None ! elif nextcs is not None and nextcs <> 'us-ascii': ! uchunks.append(USPACE) ! lastcs = nextcs ! uchunks.append(unicode(s, str(charset))) ! return UEMPTYSTRING.join(uchunks) # Rich comparison operators for equality only. BAW: does it make sense to From bwarsaw@users.sourceforge.net Thu Mar 6 16:11:18 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Thu, 06 Mar 2003 08:11:18 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv22851 Modified Files: test_email.py Log Message: test_whitespace_eater_unicode(): Test of the last outstanding bug in SF # 640110. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** test_email.py 6 Mar 2003 06:38:29 -0000 1.31 --- test_email.py 6 Mar 2003 16:11:14 -0000 1.32 *************** *** 1208,1211 **** --- 1208,1219 ---- =?mac-iceland?q?r=8Aksm=9Arg=8Cs?=""") + def test_whitespace_eater_unicode(self): + eq = self.assertEqual + s = '=?ISO-8859-1?Q?Andr=E9?= Pirard ' + dh = decode_header(s) + eq(dh, [('Andr\xe9', 'iso-8859-1'), ('Pirard ', None)]) + hu = unicode(make_header(dh)).encode('latin-1') + eq(hu, 'Andr\xe9 Pirard ') + From gvanrossum@users.sourceforge.net Thu Mar 6 16:11:19 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 06 Mar 2003 08:11:19 -0800 Subject: [Python-checkins] python/dist/src/Lib timeit.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv22880 Modified Files: timeit.py Log Message: Add a note explaining why you shouldn't try to compute mean and standard deviation. Also add an XXX comment wondering if we should refrain from using itertools.repeat(). Index: timeit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/timeit.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** timeit.py 6 Mar 2003 13:09:09 -0000 1.4 --- timeit.py 6 Mar 2003 16:11:17 -0000 1.5 *************** *** 52,55 **** --- 52,58 ---- # instructions. + # XXX Maybe for convenience of comparing with previous Python versions, + # itertools.repeat() should not be used at all? + import sys import math *************** *** 134,137 **** --- 137,151 ---- the second argument specifies the timer argument, defaulting to one million. + + Note: it's tempting to calculate mean and standard deviation + from the result vector and report these. However, this is not + very useful. In a typical case, the lowest value gives a + lower bound for how fast your machine can run the given code + snippet; higher values in the result vector are typically not + caused by variability in Python's speed, but by other + processes interfering with your timing accuracy. So the min() + of the result is probably the only number you should be + interested in. After that, you should look at the entire + vector and apply common sense rather than statistics. """ r = [] From fdrake@users.sourceforge.net Thu Mar 6 16:28:04 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Thu, 06 Mar 2003 08:28:04 -0800 Subject: [Python-checkins] python/dist/src/Modules pyexpat.c,2.57.6.5,2.57.6.6 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv1335 Modified Files: Tag: release22-maint pyexpat.c Log Message: Backport patch from revision 2.90: Fix memory leak: free memory storing the content model passed to the ElementDeclHandler by Expat. Fixes SF bug #676990. Index: pyexpat.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v retrieving revision 2.57.6.5 retrieving revision 2.57.6.6 diff -C2 -d -r2.57.6.5 -r2.57.6.6 *** pyexpat.c 19 Jan 2003 15:48:38 -0000 2.57.6.5 --- pyexpat.c 6 Mar 2003 16:27:58 -0000 2.57.6.6 *************** *** 648,680 **** } ! static PyObject * ! conv_content_model_utf8(XML_Content * const model) { ! return conv_content_model(model, conv_string_to_utf8); ! } ! #ifdef Py_USING_UNICODE ! static PyObject * ! conv_content_model_unicode(XML_Content * const model) ! { ! return conv_content_model(model, conv_string_to_unicode); ! } ! VOID_HANDLER(ElementDecl, ! (void *userData, ! const XML_Char *name, ! XML_Content *model), ! ("O&O&", ! STRING_CONV_FUNC,name, ! (self->returns_unicode ? conv_content_model_unicode ! : conv_content_model_utf8),model)) #else ! VOID_HANDLER(ElementDecl, ! (void *userData, ! const XML_Char *name, ! XML_Content *model), ! ("O&O&", ! STRING_CONV_FUNC,name, conv_content_model_utf8,model)) #endif VOID_HANDLER(AttlistDecl, --- 648,708 ---- } ! static void ! my_ElementDeclHandler(void *userData, ! const XML_Char *name, ! XML_Content *model) { ! xmlparseobject *self = (xmlparseobject *)userData; ! PyObject *args = NULL; ! if (self->handlers[ElementDecl] != NULL ! && self->handlers[ElementDecl] != Py_None) { ! PyObject *rv = NULL; ! PyObject *modelobj, *nameobj; ! #ifdef Py_USING_UNICODE ! modelobj = conv_content_model(model, ! (self->returns_unicode ! ? conv_string_to_unicode ! : conv_string_to_utf8)); #else ! modelobj = conv_content_model(model, conv_string_to_utf8); ! #endif ! if (modelobj == NULL) { ! flag_error(self); ! goto finally; ! } ! nameobj = PyString_FromString(name); ! if (nameobj == NULL) { ! Py_DECREF(modelobj); ! flag_error(self); ! goto finally; ! } ! args = Py_BuildValue("NN", nameobj, modelobj); ! if (args == NULL) { ! Py_DECREF(modelobj); ! flag_error(self); ! goto finally; ! } ! self->in_callback = 1; ! rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__), ! self->handlers[ElementDecl], args); ! self->in_callback = 0; ! if (rv == NULL) { ! flag_error(self); ! goto finally; ! } ! Py_DECREF(rv); ! } ! finally: ! Py_XDECREF(args); ! /* XML_FreeContentModel() was introduced in Expat 1.95.6. */ ! #if EXPAT_VERSION >= 0x015f06 ! XML_FreeContentModel(self->itself, model); ! #else ! free(model); #endif + return; + } VOID_HANDLER(AttlistDecl, From rhettinger@users.sourceforge.net Thu Mar 6 16:31:51 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 06 Mar 2003 08:31:51 -0800 Subject: [Python-checkins] python/dist/src/Lib httplib.py,1.72,1.73 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv2202 Modified Files: httplib.py Log Message: Reverted the previous change to read() and readline(). Kevin Jacobs found that the code simplification did not exactly match the semantics of the original. Regression test cases were requested. Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.72 retrieving revision 1.73 diff -C2 -d -r1.72 -r1.73 *** httplib.py 26 Feb 2003 22:45:18 -0000 1.72 --- httplib.py 6 Mar 2003 16:31:48 -0000 1.73 *************** *** 865,894 **** def read(self, size=None): L = [self._buf] if size is None: self._buf = '' ! for s in iter(self._read, ""): ! L.append(s) ! return "".join(L) else: ! avail = len(self._buf) ! for s in iter(self._read, ""): ! L.append(s) ! avail += len(s) ! if avail >= size: ! all = "".join(L) ! self._buf = all[size:] ! return all[:size] def readline(self): L = [self._buf] self._buf = '' ! for s in iter(self._read, ""): ! L.append(s) ! if "\n" in s: ! i = s.find("\n") + 1 ! self._buf = s[i:] ! L[-1] = s[:i] break ! return "".join(L) class FakeSocket(SharedSocketClient): --- 865,904 ---- def read(self, size=None): L = [self._buf] + avail = len(self._buf) + while size is None or avail < size: + s = self._read() + if s == '': + break + L.append(s) + avail += len(s) + all = "".join(L) if size is None: self._buf = '' ! return all else: ! self._buf = all[size:] ! return all[:size] def readline(self): L = [self._buf] self._buf = '' ! while 1: ! i = L[-1].find("\n") ! if i >= 0: break ! s = self._read() ! if s == '': ! break ! L.append(s) ! if i == -1: ! # loop exited because there is no more data ! return "".join(L) ! else: ! all = "".join(L) ! # XXX could do enough bookkeeping not to do a 2nd search ! i = all.find("\n") + 1 ! line = all[:i] ! self._buf = all[i:] ! return line class FakeSocket(SharedSocketClient): From bwarsaw@users.sourceforge.net Thu Mar 6 20:31:07 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Thu, 06 Mar 2003 12:31:07 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv21234 Modified Files: test_email.py Log Message: test_long_received_header(): Another test case for folding long Received headers (first on semis then on whitespace), given by Jason Mastaler. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** test_email.py 6 Mar 2003 16:11:14 -0000 1.32 --- test_email.py 6 Mar 2003 20:31:02 -0000 1.33 *************** *** 766,769 **** --- 766,784 ---- =?iso-8859-1?q?egen_die_rotierenden_Klingen_bef=F6rdert=2E_?=""") + def test_long_received_header(self): + h = 'from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by hrothgar.la.mastaler.com (tmda-ofmipd) with ESMTP; Wed, 05 Mar 2003 18:10:18 -0700' + msg = Message() + msg['Received-1'] = Header(h, continuation_ws='\t') + msg['Received-2'] = h + self.assertEqual(msg.as_string(), """\ + Received-1: from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by + hrothgar.la.mastaler.com (tmda-ofmipd) with ESMTP; + Wed, 05 Mar 2003 18:10:18 -0700 + Received-2: from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by + hrothgar.la.mastaler.com (tmda-ofmipd) with ESMTP; + Wed, 05 Mar 2003 18:10:18 -0700 + + """) + From bwarsaw@users.sourceforge.net Thu Mar 6 20:33:08 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Thu, 06 Mar 2003 12:33:08 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Header.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv22444 Modified Files: Header.py Log Message: _split_ascii(): In the clause where curlen + partlen > maxlen, if the part itself is longer than maxlen, and we aren't already splitting on whitespace, then we recursively split the part on whitespace and append that to the this list. Index: Header.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Header.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** Header.py 6 Mar 2003 16:10:30 -0000 1.20 --- Header.py 6 Mar 2003 20:33:04 -0000 1.21 *************** *** 457,461 **** if this: lines.append(joiner.join(this) + eol) ! this = [part] linelen = wslen + partlen maxlen = restlen --- 457,468 ---- if this: lines.append(joiner.join(this) + eol) ! # If this part is longer than maxlen and we aren't already ! # splitting on whitespace, try to recursively split this line ! # on whitespace. ! if partlen > maxlen and ch <> ' ': ! this = [_split_ascii(part, maxlen, restlen, ! continuation_ws, ' ')] ! else: ! this = [part] linelen = wslen + partlen maxlen = restlen From nnorwitz@users.sourceforge.net Thu Mar 6 22:04:28 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Thu, 06 Mar 2003 14:04:28 -0800 Subject: [Python-checkins] python/dist/src/Doc/api utilities.tex,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1:/tmp/cvs-serv32541/Doc/api Modified Files: utilities.tex Log Message: Fix SF bug #697256, PyMarshal_WriteShortToFile() documented, but not implemented Remove prototype and doc. Backport candidate. Index: utilities.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/utilities.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** utilities.tex 13 Nov 2002 15:13:38 -0000 1.7 --- utilities.tex 6 Mar 2003 22:04:24 -0000 1.8 *************** *** 290,299 **** \end{cfuncdesc} - \begin{cfuncdesc}{void}{PyMarshal_WriteShortToFile}{short value, FILE *file} - Marshal a \ctype{short} integer, \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}{void}{PyMarshal_WriteObjectToFile}{PyObject *value, FILE *file} --- 290,293 ---- From nnorwitz@users.sourceforge.net Thu Mar 6 22:04:56 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Thu, 06 Mar 2003 14:04:56 -0800 Subject: [Python-checkins] python/dist/src/Include marshal.h,2.12,2.13 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv32541/Include Modified Files: marshal.h Log Message: Fix SF bug #697256, PyMarshal_WriteShortToFile() documented, but not implemented Remove prototype and doc. Backport candidate. Index: marshal.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/marshal.h,v retrieving revision 2.12 retrieving revision 2.13 diff -C2 -d -r2.12 -r2.13 *** marshal.h 12 Aug 2002 07:21:57 -0000 2.12 --- marshal.h 6 Mar 2003 22:04:22 -0000 2.13 *************** *** 9,13 **** PyAPI_FUNC(void) PyMarshal_WriteLongToFile(long, FILE *); - PyAPI_FUNC(void) PyMarshal_WriteShortToFile(int, FILE *); PyAPI_FUNC(void) PyMarshal_WriteObjectToFile(PyObject *, FILE *); PyAPI_FUNC(PyObject *) PyMarshal_WriteObjectToString(PyObject *); --- 9,12 ---- From jackjansen@users.sourceforge.net Thu Mar 6 23:02:07 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 06 Mar 2003 15:02:07 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules OSATerminology.c,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv24186 Added Files: OSATerminology.c Log Message: Module to get OSA terminology description through the "official channels", in stead of manually getting the AETE/AEUT resource. Donated by Donovan Preston. This is his original code (but with the filename changed) checked in for reference only. --- NEW FILE: OSATerminology.c --- #include #include #include PyObject * PyOSA_GetAppTerminology(PyObject* self, PyObject* args) { AEDesc temp; FSSpec tempFSSpec; ComponentInstance defaultComponent; ScriptingComponentSelector theType; SInt16 defaultTerminology; Boolean didLaunch; OSAError err; PyObject * returnVal; if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &tempFSSpec)) return NULL; defaultComponent = OpenDefaultComponent (kOSAComponentType, 'ascr'); // kOSAGenericScriptingComponentSubtype); err = GetComponentInstanceError (defaultComponent); printf("OpenDefaultComponent: %d\n", err); err = OSAGetCurrentDialect(defaultComponent, &defaultTerminology); printf("getcurrentdialect: %d\n", err); err = OSAGetAppTerminology ( defaultComponent, kOSAModeNull, &tempFSSpec, defaultTerminology, &didLaunch, &temp ); /* err = ASGetAppTerminology ( defaultComponent, &tempFSSpec, defaultTerminology, &didLaunch, &temp );*/ printf("getappterminology: %d\n", err); returnVal = Py_BuildValue("O&i", AEDesc_New, &temp, didLaunch); return returnVal; } /* * List of methods defined in the module */ static struct PyMethodDef PyOSA_methods[] = { {"GetAppTerminology", (PyCFunction) PyOSA_GetAppTerminology, METH_VARARGS, "Get an applications terminology, as an AEDesc object."}, {NULL, (PyCFunction) NULL, 0, NULL} }; void initPyOSA(void) { Py_InitModule("PyOSA", PyOSA_methods); } From jackjansen@users.sourceforge.net Thu Mar 6 23:03:03 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 06 Mar 2003 15:03:03 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules OSATerminology.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv24758 Modified Files: OSATerminology.c Log Message: Various tweaks by Jack because of the different module name, adaptation to the Python style, etc. Index: OSATerminology.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/OSATerminology.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** OSATerminology.c 6 Mar 2003 23:02:04 -0000 1.1 --- OSATerminology.c 6 Mar 2003 23:02:59 -0000 1.2 *************** *** 1,51 **** ! #include #include ! #include ! PyObject * PyOSA_GetAppTerminology(PyObject* self, PyObject* args) { ! AEDesc temp; ! FSSpec tempFSSpec; ! ! ComponentInstance defaultComponent; ! ScriptingComponentSelector theType; ! SInt16 defaultTerminology; ! Boolean didLaunch; ! OSAError err; ! PyObject * returnVal; ! ! if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &tempFSSpec)) return NULL; ! defaultComponent = OpenDefaultComponent (kOSAComponentType, ! 'ascr'); ! // kOSAGenericScriptingComponentSubtype); ! ! err = GetComponentInstanceError (defaultComponent); ! printf("OpenDefaultComponent: %d\n", err); err = OSAGetCurrentDialect(defaultComponent, &defaultTerminology); ! printf("getcurrentdialect: %d\n", err); err = OSAGetAppTerminology ( defaultComponent, ! kOSAModeNull, ! &tempFSSpec, defaultTerminology, &didLaunch, ! &temp ); ! /* err = ASGetAppTerminology ( defaultComponent, ! &tempFSSpec, defaultTerminology, &didLaunch, ! &temp ! );*/ ! ! printf("getappterminology: %d\n", err); ! ! returnVal = Py_BuildValue("O&i", ! AEDesc_New, &temp, didLaunch); ! return returnVal; } --- 1,79 ---- ! /* ! ** This module is a one-trick pony: given an FSSpec it gets the aeut ! ** resources. It was written by Donovan Preston and slightly modified ! ** by Jack. ! ** ! ** It should be considered a placeholder, it will probably be replaced ! ** by a full interface to OpenScripting. ! */ ! #include "Python.h" ! #include "macglue.h" ! ! #ifdef WITHOUT_FRAMEWORKS ! #include ! #else #include ! #endif ! static PyObject * ! PyOSA_GetAppTerminology(PyObject* self, PyObject* args) ! { ! AEDesc theDesc = {0,0}; ! FSSpec fss; ! ComponentInstance defaultComponent = NULL; ! SInt16 defaultTerminology = 0; ! Boolean didLaunch = 0; OSAError err; + long modeFlags = 0; ! if (!PyArg_ParseTuple(args, "O&|i", PyMac_GetFSSpec, &fss, &modeFlags)) ! return NULL; ! defaultComponent = OpenDefaultComponent (kOSAComponentType, 'ascr'); ! err = GetComponentInstanceError (defaultComponent); ! if (err) return PyMac_Error(err); err = OSAGetCurrentDialect(defaultComponent, &defaultTerminology); ! if (err) return PyMac_Error(err); err = OSAGetAppTerminology ( defaultComponent, ! modeFlags, ! &fss, defaultTerminology, &didLaunch, ! &theDesc ); + if (err) return PyMac_Error(err); + return Py_BuildValue("O&i", AEDesc_New, &theDesc, didLaunch); + } ! static PyObject * ! PyOSA_GetSysTerminology(PyObject* self, PyObject* args) ! { ! AEDesc theDesc = {0,0}; ! FSSpec fss; ! ComponentInstance defaultComponent = NULL; ! SInt16 defaultTerminology = 0; ! Boolean didLaunch = 0; ! OSAError err; ! long modeFlags = 0; ! ! if (!PyArg_ParseTuple(args, "O&|i", PyMac_GetFSSpec, &fss, &modeFlags)) ! return NULL; ! ! defaultComponent = OpenDefaultComponent (kOSAComponentType, 'ascr'); ! err = GetComponentInstanceError (defaultComponent); ! if (err) return PyMac_Error(err); ! err = OSAGetCurrentDialect(defaultComponent, &defaultTerminology); ! if (err) return PyMac_Error(err); ! err = OSAGetAppTerminology ( defaultComponent, ! modeFlags, ! &fss, defaultTerminology, &didLaunch, ! &theDesc ! ); ! if (err) return PyMac_Error(err); ! return Py_BuildValue("O&i", AEDesc_New, &theDesc, didLaunch); } *************** *** 53,70 **** * List of methods defined in the module */ ! static struct PyMethodDef PyOSA_methods[] = { ! {"GetAppTerminology", ! (PyCFunction) PyOSA_GetAppTerminology, ! METH_VARARGS, ! "Get an applications terminology, as an AEDesc object."}, ! ! {NULL, (PyCFunction) NULL, 0, NULL} }; void ! initPyOSA(void) { ! Py_InitModule("PyOSA", PyOSA_methods); } --- 81,101 ---- * List of methods defined in the module */ ! static struct PyMethodDef OSATerminology_methods[] = { ! {"GetAppTerminology", ! (PyCFunction) PyOSA_GetAppTerminology, ! METH_VARARGS, ! "Get an applications terminology, as an AEDesc object."}, ! {"GetSysTerminology", ! (PyCFunction) PyOSA_GetSysTerminology, ! METH_VARARGS, ! "Get an applications system terminology, as an AEDesc object."}, ! {NULL, (PyCFunction) NULL, 0, NULL} }; void ! initOSATerminology(void) { ! Py_InitModule("OSATerminology", OSATerminology_methods); } From jackjansen@users.sourceforge.net Thu Mar 6 23:03:47 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 06 Mar 2003 15:03:47 -0800 Subject: [Python-checkins] python/dist/src setup.py,1.154,1.155 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv25227 Modified Files: setup.py Log Message: Build the OSATerminology module on MacOSX. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.154 retrieving revision 1.155 diff -C2 -d -r1.154 -r1.155 *** setup.py 2 Mar 2003 21:31:51 -0000 1.154 --- setup.py 6 Mar 2003 23:03:43 -0000 1.155 *************** *** 760,763 **** --- 760,765 ---- exts.append( Extension('MacOS', ['macosmodule.c'], extra_link_args=['-framework', 'Carbon']) ) + exts.append( Extension('OSATerminology', ['OSATerminology.c'], + extra_link_args=['-framework', 'Carbon']) ) exts.append( Extension('icglue', ['icgluemodule.c'], extra_link_args=['-framework', 'Carbon']) ) From jackjansen@users.sourceforge.net Thu Mar 6 23:04:41 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Thu, 06 Mar 2003 15:04:41 -0800 Subject: [Python-checkins] python/dist/src/Mac/scripts gensuitemodule.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv25439 Modified Files: gensuitemodule.py Log Message: First try to use the OSATerminology module to get the terminology resources before reverting to manually reading the resources. Unfortunately there is still a bug in here somewhere: it doesn't work for all applications. Index: gensuitemodule.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/gensuitemodule.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** gensuitemodule.py 26 Jan 2003 20:35:47 -0000 1.28 --- gensuitemodule.py 6 Mar 2003 23:04:38 -0000 1.29 *************** *** 16,24 **** import keyword import macresource ! from aetools import unpack ! from Carbon.Res import * ! DEFAULT_PACKAGEFOLDER=os.path.join(sys.prefix, 'Lib', 'plat-mac', 'lib-scriptpackages') def main(): --- 16,28 ---- import keyword import macresource ! import aetools ! import distutils.sysconfig ! import OSATerminology from Carbon.Res import * + import MacOS ! _MAC_LIB_FOLDER=os.path.dirname(aetools.__file__) ! DEFAULT_STANDARD_PACKAGEFOLDER=os.path.join(_MAC_LIB_FOLDER, 'lib-scriptpackages') ! DEFAULT_USER_PACKAGEFOLDER=distutils.sysconfig.get_python_lib() def main(): *************** *** 27,36 **** processfile(filename) else: ! filename = EasyDialogs.AskFileForOpen(message='Select file with aeut/aete resource:') if not filename: sys.exit(0) ! processfile(filename) ! def processfile(fullname): """Process all resources in a single file""" cur = CurResFile() --- 31,48 ---- processfile(filename) else: ! # The dialogOptionFlags below allows selection of .app bundles. ! filename = EasyDialogs.AskFileForOpen( ! message='Select scriptable application', ! dialogOptionFlags=0x1056) if not filename: sys.exit(0) ! try: ! processfile(filename) ! except MacOS.Error, arg: ! print "Error getting terminology:", arg ! print "Retry, manually parsing resources" ! processfile_fromresource(filename) ! def processfile_fromresource(fullname): """Process all resources in a single file""" cur = CurResFile() *************** *** 61,64 **** --- 73,92 ---- compileaetelist(aetelist, fullname) + def processfile(fullname): + """Ask an application for its terminology and process that""" + aedescobj, launched = OSATerminology.GetSysTerminology(fullname) + if launched: + print "Launched", fullname + raw = aetools.unpack(aedescobj) + if not raw: + print 'Unpack returned empty value:', raw + return + if not raw[0].data: + print 'Unpack returned value without data:', raw + return + aedata = raw[0] + aete = decode(aedata.data) + compileaete(aete, None, fullname) + def compileaetelist(aetelist, fullname): for aete, resinfo in aetelist: *************** *** 241,250 **** packagename = packagename[:27] pathname = EasyDialogs.AskFolder(message='Create and select package folder for %s'%packagename, ! defaultLocation=DEFAULT_PACKAGEFOLDER) if not pathname: return packagename = os.path.split(os.path.normpath(pathname))[1] basepkgname = EasyDialogs.AskFolder(message='Package folder for base suite (usually StdSuites)', ! defaultLocation=DEFAULT_PACKAGEFOLDER) if basepkgname: dirname, basepkgname = os.path.split(os.path.normpath(basepkgname)) --- 269,278 ---- packagename = packagename[:27] pathname = EasyDialogs.AskFolder(message='Create and select package folder for %s'%packagename, ! defaultLocation=DEFAULT_USER_PACKAGEFOLDER) if not pathname: return packagename = os.path.split(os.path.normpath(pathname))[1] basepkgname = EasyDialogs.AskFolder(message='Package folder for base suite (usually StdSuites)', ! defaultLocation=DEFAULT_STANDARD_PACKAGEFOLDER) if basepkgname: dirname, basepkgname = os.path.split(os.path.normpath(basepkgname)) *************** *** 908,910 **** main() sys.exit(1) - print identify('for') --- 936,937 ---- From tim_one@users.sourceforge.net Thu Mar 6 23:42:00 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 06 Mar 2003 15:42:00 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Header.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv7889/Lib/email Modified Files: Header.py Log Message: Repaired a misleading comment Barry inherited from me. Index: Header.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Header.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** Header.py 6 Mar 2003 20:33:04 -0000 1.21 --- Header.py 6 Mar 2003 23:41:58 -0000 1.22 *************** *** 497,501 **** i = m else: ! # m is not acceptable, so final i must be < j. j = m - 1 # i == j. Invariant #1 implies that splittable[:i] fits, and --- 497,501 ---- i = m else: ! # m is not acceptable, so final i must be < m. j = m - 1 # i == j. Invariant #1 implies that splittable[:i] fits, and From rhettinger@users.sourceforge.net Thu Mar 6 23:54:29 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 06 Mar 2003 15:54:29 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libstdtypes.tex,1.119,1.120 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv11840/Doc/lib Modified Files: libstdtypes.tex Log Message: SF patch #693753: fix for bug 639806: default for dict.pop (contributed by Michael Stone.) Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.119 retrieving revision 1.120 diff -C2 -d -r1.119 -r1.120 *** libstdtypes.tex 5 Mar 2003 14:42:09 -0000 1.119 --- libstdtypes.tex 6 Mar 2003 23:54:27 -0000 1.120 *************** *** 1105,1111 **** else \var{x} (also setting it)} {(5)} ! \lineiii{\var{a}.pop(\var{k})} ! {remove specified \var{key} and return corresponding \var{value}} ! {} \lineiii{\var{a}.popitem()} {remove and return an arbitrary (\var{key}, \var{value}) pair} --- 1105,1112 ---- else \var{x} (also setting it)} {(5)} ! \lineiii{\var{a}.pop(\var{k}\optional{, \var{x}})} ! {\code{\var{a}[\var{k}]} if \code{\var{k} in \var{a}}, ! else \var{x} (and remove k)} ! {(8)} \lineiii{\var{a}.popitem()} {remove and return an arbitrary (\var{key}, \var{value}) pair} *************** *** 1156,1159 **** --- 1157,1163 ---- \item[(7)] \function{fromkeys()} is a class method that returns a new dictionary. \var{value} defaults to \code{None}. \versionadded{2.3} + + \item[(8)] \function{pop()} raises a \exception{KeyError} when no default + value is given and the key is not found. \versionadded{2.3} \end{description} From rhettinger@users.sourceforge.net Thu Mar 6 23:54:29 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 06 Mar 2003 15:54:29 -0800 Subject: [Python-checkins] python/dist/src/Lib UserDict.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv11840/Lib Modified Files: UserDict.py Log Message: SF patch #693753: fix for bug 639806: default for dict.pop (contributed by Michael Stone.) Index: UserDict.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/UserDict.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** UserDict.py 31 Jan 2003 03:30:09 -0000 1.23 --- UserDict.py 6 Mar 2003 23:54:27 -0000 1.24 *************** *** 56,61 **** self[key] = failobj return self[key] ! def pop(self, key): ! return self.data.pop(key) def popitem(self): return self.data.popitem() --- 56,61 ---- self[key] = failobj return self[key] ! def pop(self, key, *args): ! return self.data.pop(key, *args) def popitem(self): return self.data.popitem() *************** *** 118,123 **** self[key] = default return default ! def pop(self, key): ! value = self[key] del self[key] return value --- 118,131 ---- self[key] = default return default ! def pop(self, key, *args): ! if len(args) > 1: ! raise TypeError, "pop expected at most 2 arguments, got "\ ! + repr(1 + len(args)) ! try: ! value = self[key] ! except KeyError: ! if args: ! return args[0] ! raise del self[key] return value From rhettinger@users.sourceforge.net Thu Mar 6 23:54:30 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 06 Mar 2003 15:54:30 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_types.py,1.46,1.47 test_userdict.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv11840/Lib/test Modified Files: test_types.py test_userdict.py Log Message: SF patch #693753: fix for bug 639806: default for dict.pop (contributed by Michael Stone.) Index: test_types.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_types.py,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -d -r1.46 -r1.47 *** test_types.py 23 Feb 2003 23:11:41 -0000 1.46 --- test_types.py 6 Mar 2003 23:54:27 -0000 1.47 *************** *** 644,650 **** x = 4503599627370496L y = 4503599627370496 ! h = {x: 'anything', y: 'something else'} if h[x] != h[y]: raise TestFailed, "long/int key should match" d[1] = 1 --- 644,654 ---- x = 4503599627370496L y = 4503599627370496 ! h = {x: 'anything', y: 'something else'} if h[x] != h[y]: raise TestFailed, "long/int key should match" + + if d.pop(k, v) != v: raise TestFailed, "{}.pop(k, v) doesn't return default value" + d[k] = v + if d.pop(k, 1) != v: raise TestFailed, "{}.pop(k, v) doesn't find known key/value pair" d[1] = 1 Index: test_userdict.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_userdict.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_userdict.py 19 Jan 2003 23:26:59 -0000 1.12 --- test_userdict.py 6 Mar 2003 23:54:27 -0000 1.13 *************** *** 140,143 **** --- 140,146 ---- self.assertEqual(t.pop("x"), 42) self.assertRaises(KeyError, t.pop, "x") + self.assertEqual(t.pop("x", 1), 1) + t["x"] = 42 + self.assertEqual(t.pop("x", 1), 42) # Test popitem *************** *** 243,246 **** --- 246,252 ---- self.assert_(10 not in s) s[10] = 'ten' + self.assertEqual(s.pop("x", 1), 1) + s["x"] = 42 + self.assertEqual(s.pop("x", 1), 42) # popitem From rhettinger@users.sourceforge.net Thu Mar 6 23:54:30 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 06 Mar 2003 15:54:30 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.690,1.691 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv11840/Misc Modified Files: NEWS Log Message: SF patch #693753: fix for bug 639806: default for dict.pop (contributed by Michael Stone.) Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.690 retrieving revision 1.691 diff -C2 -d -r1.690 -r1.691 *** NEWS 6 Mar 2003 01:56:12 -0000 1.690 --- NEWS 6 Mar 2003 23:54:27 -0000 1.691 *************** *** 13,16 **** --- 13,22 ---- ----------------- + - dict.pop now takes an optional argument specifying a default + value to return if the key is not in the dict. If a default is not + given and the key is not found, a KeyError will still be raised. + Parallel changes were made to UserDict.UserDict and UserDict.DictMixin. + [SF patch #693753] (contributed by Michael Stone.) + - sys.getfilesystemencoding() was added to expose Py_FileSystemDefaultEncoding. From rhettinger@users.sourceforge.net Thu Mar 6 23:54:31 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 06 Mar 2003 15:54:31 -0800 Subject: [Python-checkins] python/dist/src/Objects dictobject.c,2.140,2.141 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv11840/Objects Modified Files: dictobject.c Log Message: SF patch #693753: fix for bug 639806: default for dict.pop (contributed by Michael Stone.) Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.140 retrieving revision 2.141 diff -C2 -d -r2.140 -r2.141 *** dictobject.c 15 Feb 2003 14:45:12 -0000 2.140 --- dictobject.c 6 Mar 2003 23:54:28 -0000 2.141 *************** *** 1545,1555 **** static PyObject * ! dict_pop(dictobject *mp, PyObject *key) { long hash; dictentry *ep; PyObject *old_value, *old_key; if (mp->ma_used == 0) { PyErr_SetString(PyExc_KeyError, "pop(): dictionary is empty"); --- 1545,1562 ---- static PyObject * ! dict_pop(dictobject *mp, PyObject *args) { long hash; dictentry *ep; PyObject *old_value, *old_key; + PyObject *key, *deflt = NULL; + if(!PyArg_UnpackTuple(args, "pop", 1, 2, &key, &deflt)) + return NULL; if (mp->ma_used == 0) { + if (deflt) { + Py_INCREF(deflt); + return deflt; + } PyErr_SetString(PyExc_KeyError, "pop(): dictionary is empty"); *************** *** 1564,1567 **** --- 1571,1578 ---- ep = (mp->ma_lookup)(mp, key, hash); if (ep->me_value == NULL) { + if (deflt) { + Py_INCREF(deflt); + return deflt; + } PyErr_SetObject(PyExc_KeyError, key); return NULL; *************** *** 1720,1724 **** PyDoc_STRVAR(pop__doc__, ! "D.pop(k) -> v, remove specified key and return the corresponding value"); PyDoc_STRVAR(popitem__doc__, --- 1731,1736 ---- PyDoc_STRVAR(pop__doc__, ! "D.pop(k[,d]) -> v, remove specified key and return the corresponding value\n\ ! If key is not found, d is returned if given, otherwise KeyError is raised"); PyDoc_STRVAR(popitem__doc__, *************** *** 1764,1768 **** {"setdefault", (PyCFunction)dict_setdefault, METH_VARARGS, setdefault_doc__}, ! {"pop", (PyCFunction)dict_pop, METH_O, pop__doc__}, {"popitem", (PyCFunction)dict_popitem, METH_NOARGS, --- 1776,1780 ---- {"setdefault", (PyCFunction)dict_setdefault, METH_VARARGS, setdefault_doc__}, ! {"pop", (PyCFunction)dict_pop, METH_VARARGS, pop__doc__}, {"popitem", (PyCFunction)dict_popitem, METH_NOARGS, From rhettinger@users.sourceforge.net Fri Mar 7 00:21:45 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 06 Mar 2003 16:21:45 -0800 Subject: [Python-checkins] python/nondist/peps pep-0290.txt,1.8,1.9 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv21419 Modified Files: pep-0290.txt Log Message: Add advisory to replace apply(). Index: pep-0290.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0290.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** pep-0290.txt 25 Jan 2003 20:30:02 -0000 1.8 --- pep-0290.txt 7 Mar 2003 00:21:42 -0000 1.9 *************** *** 117,120 **** --- 117,133 ---- string1.find(string2) != -1 --> string2 in string1 + Replace apply() with a Direct Function Call + ''''''''''''''''''''''''''''''''''''''''''' + + In Python 2.3, apply() was marked for Pending Deprecation because it + was made obsolete by the Python 1.6's introduction of * and ** in + function calls. Using a direct function call was always a little + faster than apply() because it saved the lookup for the builtin. + Now, apply() is even slower due to its use of the warnings module. + + Pattern:: + + apply(f,args, kwds) --> f(*args, **kwds) + Python 2.2 or Later From montanaro@users.sourceforge.net Fri Mar 7 00:47:43 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 06 Mar 2003 16:47:43 -0800 Subject: [Python-checkins] python/dist/src/Tools/scripts pickle2db.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv29642 Modified Files: pickle2db.py Log Message: fix name of db2pickle Index: pickle2db.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/pickle2db.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pickle2db.py 3 Feb 2003 15:28:23 -0000 1.2 --- pickle2db.py 7 Mar 2003 00:47:40 -0000 1.3 *************** *** 12,16 **** Note that recno databases can only contain numeric keys, so you can't dump a ! hash or btree database using bsddb2pickle.py and reconstitute it to a recno database with %(prog)s. """ --- 12,16 ---- Note that recno databases can only contain numeric keys, so you can't dump a ! hash or btree database using db2pickle.py and reconstitute it to a recno database with %(prog)s. """ From gvanrossum@users.sourceforge.net Fri Mar 7 01:33:20 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Thu, 06 Mar 2003 17:33:20 -0800 Subject: [Python-checkins] python/dist/src/Lib timeit.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv13342 Modified Files: timeit.py Log Message: Broke down and made it work for Python 2.0 and up. (Older versions would have required refraining from using string methods -- too painful.) Changed the -s option so that multiple -s options are cumulative. Index: timeit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/timeit.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** timeit.py 6 Mar 2003 16:11:17 -0000 1.5 --- timeit.py 7 Mar 2003 01:33:18 -0000 1.6 *************** *** 1,3 **** ! """Framework for measuring execution time for small code snippets. This module avoids a number of common traps for measuring execution --- 1,3 ---- ! """Tool for measuring execution time of small code snippets. This module avoids a number of common traps for measuring execution *************** *** 13,17 **** -n/--number N: how many times to execute 'statement' (default: see below) -r/--repeat N: how many times to repeat the timer (default 1) ! -s/--setup S: statements executed once before 'statement' (default 'pass') -t/--time: use time.time() (default on Unix) -c/--clock: use time.clock() (default on Windows) --- 13,17 ---- -n/--number N: how many times to execute 'statement' (default: see below) -r/--repeat N: how many times to repeat the timer (default 1) ! -s/--setup S: statement to be executed once initially (default 'pass') -t/--time: use time.time() (default on Unix) -c/--clock: use time.clock() (default on Windows) *************** *** 21,25 **** A multi-line statement may be given by specifying each line as a separate argument; indented lines are possible by enclosing an ! argument in quotes and using leading spaces. If -n is not given, a suitable number of loops is calculated by trying --- 21,26 ---- A multi-line statement may be given by specifying each line as a separate argument; indented lines are possible by enclosing an ! argument in quotes and using leading spaces. Multiple -s options are ! treated similarly. If -n is not given, a suitable number of loops is calculated by trying *************** *** 38,62 **** Note: there is a certain baseline overhead associated with executing a pass statement. The code here doesn't try to hide it, but you should ! be aware of it (especially when comparing different versions of ! Python). The baseline overhead is measured by invoking the program ! without arguments. ! """ ! ! # To use this module with older versions of Python, the dependency on ! # the itertools module is easily removed; in the template, instead of ! # itertools.repeat(None, number), use [None]*number. It's barely ! # slower. Note: the baseline overhead, measured by the default ! # invocation, differs for older Python versions! Also, to fairly ! # compare older Python versions to Python 2.3, you may want to use ! # python -O for the older versions to avoid timing SET_LINENO ! # instructions. ! # XXX Maybe for convenience of comparing with previous Python versions, ! # itertools.repeat() should not be used at all? import sys import math import time ! import itertools __all__ = ["Timer"] --- 39,59 ---- Note: there is a certain baseline overhead associated with executing a pass statement. The code here doesn't try to hide it, but you should ! be aware of it. The baseline overhead can be measured by invoking the ! program without arguments. ! The baseline overhead differs between Python versions! Also, to ! fairly compare older Python versions to Python 2.3, you may want to ! use python -O for the older versions to avoid timing SET_LINENO ! instructions. ! """ import sys import math import time ! try: ! import itertools ! except ImportError: ! # Must be an older Python version (see timeit() below) ! itertools = None __all__ = ["Timer"] *************** *** 76,82 **** # being indented 8 spaces. template = """ ! def inner(number, timer): %(setup)s - seq = itertools.repeat(None, number) t0 = timer() for i in seq: --- 73,78 ---- # being indented 8 spaces. template = """ ! def inner(seq, timer): %(setup)s t0 = timer() for i in seq: *************** *** 127,131 **** the timer function to be used are passed to the constructor. """ ! return self.inner(number, self.timer) def repeat(self, repeat=default_repeat, number=default_number): --- 123,131 ---- the timer function to be used are passed to the constructor. """ ! if itertools: ! seq = itertools.repeat(None, number) ! else: ! seq = [None] * number ! return self.inner(seq, self.timer) def repeat(self, repeat=default_repeat, number=default_number): *************** *** 178,182 **** stmt = "\n".join(args) or "pass" number = 0 # auto-determine ! setup = "pass" repeat = 1 for o, a in opts: --- 178,182 ---- stmt = "\n".join(args) or "pass" number = 0 # auto-determine ! setup = [] repeat = 1 for o, a in opts: *************** *** 184,188 **** number = int(a) if o in ("-s", "--setup"): ! setup = a if o in ("-r", "--repeat"): repeat = int(a) --- 184,188 ---- number = int(a) if o in ("-s", "--setup"): ! setup.append(a) if o in ("-r", "--repeat"): repeat = int(a) *************** *** 196,199 **** --- 196,200 ---- print __doc__, return 0 + setup = "\n".join(setup) or "pass" t = Timer(stmt, setup, timer) if number == 0: From jackjansen@users.sourceforge.net Fri Mar 7 12:47:09 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 07 Mar 2003 04:47:09 -0800 Subject: [Python-checkins] python/dist/src/Lib tarfile.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv10715 Modified Files: tarfile.py Log Message: Test that os.utime and os.chmod actually exist before using them. Index: tarfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tarfile.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** tarfile.py 19 Feb 2003 12:51:34 -0000 1.3 --- tarfile.py 7 Mar 2003 12:47:06 -0000 1.4 *************** *** 1514,1525 **** """Set file permissions of targetpath according to tarinfo. """ ! try: ! os.chmod(targetpath, tarinfo.mode) ! except EnvironmentError, e: ! raise ExtractError, "could not change mode" def utime(self, tarinfo, targetpath): """Set modification time of targetpath according to tarinfo. """ if sys.platform == "win32" and tarinfo.isdir(): # According to msdn.microsoft.com, it is an error (EACCES) --- 1514,1528 ---- """Set file permissions of targetpath according to tarinfo. """ ! if hasattr(os, 'chmod'): ! try: ! os.chmod(targetpath, tarinfo.mode) ! except EnvironmentError, e: ! raise ExtractError, "could not change mode" def utime(self, tarinfo, targetpath): """Set modification time of targetpath according to tarinfo. """ + if not hasattr(os, 'utime'): + return if sys.platform == "win32" and tarinfo.isdir(): # According to msdn.microsoft.com, it is an error (EACCES) From jackjansen@users.sourceforge.net Fri Mar 7 12:50:48 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 07 Mar 2003 04:50:48 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_tarfile.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv12208 Modified Files: test_tarfile.py Log Message: Two fixes to make this test pass on MacOS9: - the test was sloppy about filenames: "0-REGTYPE-TEXT" was used where the archive held "/0-REGTYPE-TEXT". - tarfile extracts all files in binary mode, but the test expected to be able to read and compare text files in text mode. Use universal text mode. Index: test_tarfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_tarfile.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_tarfile.py 19 Feb 2003 02:41:43 -0000 1.4 --- test_tarfile.py 7 Mar 2003 12:50:45 -0000 1.5 *************** *** 75,79 **** if self.sep != "|": f1 = self.tar.extractfile("S-SPARSE") ! f2 = self.tar.extractfile("S-SPARSE-WITH-NULLS") self.assert_(f1.read() == f2.read(), "_FileObject failed on sparse file member") --- 75,79 ---- if self.sep != "|": f1 = self.tar.extractfile("S-SPARSE") ! f2 = self.tar.extractfile("/S-SPARSE-WITH-NULLS") self.assert_(f1.read() == f2.read(), "_FileObject failed on sparse file member") *************** *** 83,89 **** """ if self.sep != "|": ! filename = "0-REGTYPE-TEXT" self.tar.extract(filename, dirname()) ! lines1 = file(os.path.join(dirname(), filename), "r").readlines() lines2 = self.tar.extractfile(filename).readlines() self.assert_(lines1 == lines2, --- 83,89 ---- """ if self.sep != "|": ! filename = "/0-REGTYPE-TEXT" self.tar.extract(filename, dirname()) ! lines1 = file(os.path.join(dirname(), filename), "rU").readlines() lines2 = self.tar.extractfile(filename).readlines() self.assert_(lines1 == lines2, *************** *** 94,98 **** """ if self.sep != "|": ! filename = "0-REGTYPE" self.tar.extract(filename, dirname()) data = file(os.path.join(dirname(), filename), "rb").read() --- 94,98 ---- """ if self.sep != "|": ! filename = "/0-REGTYPE" self.tar.extract(filename, dirname()) data = file(os.path.join(dirname(), filename), "rb").read() From jackjansen@users.sourceforge.net Fri Mar 7 13:27:55 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 07 Mar 2003 05:27:55 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_tarfile.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv25149 Modified Files: test_tarfile.py Log Message: The filename fix of the previous checkin was complete bogus, the problem is elsewhere. Retracting. Index: test_tarfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_tarfile.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_tarfile.py 7 Mar 2003 12:50:45 -0000 1.5 --- test_tarfile.py 7 Mar 2003 13:27:53 -0000 1.6 *************** *** 75,79 **** if self.sep != "|": f1 = self.tar.extractfile("S-SPARSE") ! f2 = self.tar.extractfile("/S-SPARSE-WITH-NULLS") self.assert_(f1.read() == f2.read(), "_FileObject failed on sparse file member") --- 75,79 ---- if self.sep != "|": f1 = self.tar.extractfile("S-SPARSE") ! f2 = self.tar.extractfile("S-SPARSE-WITH-NULLS") self.assert_(f1.read() == f2.read(), "_FileObject failed on sparse file member") *************** *** 83,87 **** """ if self.sep != "|": ! filename = "/0-REGTYPE-TEXT" self.tar.extract(filename, dirname()) lines1 = file(os.path.join(dirname(), filename), "rU").readlines() --- 83,87 ---- """ if self.sep != "|": ! filename = "0-REGTYPE-TEXT" self.tar.extract(filename, dirname()) lines1 = file(os.path.join(dirname(), filename), "rU").readlines() *************** *** 94,98 **** """ if self.sep != "|": ! filename = "/0-REGTYPE" self.tar.extract(filename, dirname()) data = file(os.path.join(dirname(), filename), "rb").read() --- 94,98 ---- """ if self.sep != "|": ! filename = "0-REGTYPE" self.tar.extract(filename, dirname()) data = file(os.path.join(dirname(), filename), "rb").read() From jackjansen@users.sourceforge.net Fri Mar 7 13:37:34 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 07 Mar 2003 05:37:34 -0800 Subject: [Python-checkins] python/dist/src/Lib tarfile.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv28936 Modified Files: tarfile.py Log Message: Make tarfile raise ImportError on MacOS9. The pathname handling needs work, and I don't have time to fix it. I'll file a bug report. Index: tarfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tarfile.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** tarfile.py 7 Mar 2003 12:47:06 -0000 1.4 --- tarfile.py 7 Mar 2003 13:37:32 -0000 1.5 *************** *** 51,54 **** --- 51,61 ---- import struct + if sys.platform == 'mac': + # This module needs work for MacOS9, especially in the area of pathname + # handling. In many places it is assumed a simple substitution of / by the + # local os.path.sep is good enough to convert pathnames, but this does not + # work with the mac rooted:path:name versus :nonrooted:path:name syntax + raise ImportError, "tarfile does not work for platform==mac" + try: import grp, pwd From fdrake@users.sourceforge.net Fri Mar 7 15:02:09 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:02:09 -0800 Subject: [Python-checkins] python/dist/src/Doc/api newtypes.tex,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory sc8-pr-cvs1:/tmp/cvs-serv31561 Modified Files: newtypes.tex Log Message: Minor clarification about the ob_size field. Index: newtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/newtypes.tex,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** newtypes.tex 10 Feb 2003 19:18:21 -0000 1.21 --- newtypes.tex 7 Mar 2003 15:02:03 -0000 1.22 *************** *** 462,468 **** negative number, and N is \code{abs(\member{ob_size})} there. Also, the presence of an \member{ob_size} field in the instance layout ! doesn't mean that the type is variable-length (for example, the list ! type has fixed-length instances, yet those instances have a ! meaningful \member{ob_size} field). The basic size includes the fields in the instance declared by the --- 462,468 ---- negative number, and N is \code{abs(\member{ob_size})} there. Also, the presence of an \member{ob_size} field in the instance layout ! doesn't mean that the instance structure is variable-length (for ! example, the structure for the list type has fixed-length instances, ! yet those instances have a meaningful \member{ob_size} field). The basic size includes the fields in the instance declared by the From gvanrossum@users.sourceforge.net Fri Mar 7 15:13:49 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:13:49 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.691,1.692 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv3464/Misc Modified Files: NEWS Log Message: - The extended type structure used for heap types (new-style classes defined by Python code using a class statement) is now exported from object.h as PyHeapTypeObject. (SF patch #696193.) Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.691 retrieving revision 1.692 diff -C2 -d -r1.691 -r1.692 *** NEWS 6 Mar 2003 23:54:27 -0000 1.691 --- NEWS 7 Mar 2003 15:13:06 -0000 1.692 *************** *** 81,85 **** ----- ! TBD New platforms --- 81,87 ---- ----- ! - The extended type structure used for heap types (new-style ! classes defined by Python code using a class statement) is now ! exported from object.h as PyHeapTypeObject. (SF patch #696193.) New platforms From gvanrossum@users.sourceforge.net Fri Mar 7 15:13:50 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:13:50 -0800 Subject: [Python-checkins] python/dist/src/Include object.h,2.112,2.113 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv3464/Include Modified Files: object.h Log Message: - The extended type structure used for heap types (new-style classes defined by Python code using a class statement) is now exported from object.h as PyHeapTypeObject. (SF patch #696193.) Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.112 retrieving revision 2.113 diff -C2 -d -r2.112 -r2.113 *** object.h 17 Nov 2002 17:52:44 -0000 2.112 --- object.h 7 Mar 2003 15:13:16 -0000 2.113 *************** *** 328,331 **** --- 328,353 ---- + /* The *real* layout of a type object when allocated on the heap */ + typedef struct _heaptypeobject { + /* Note: there's a dependency on the order of these members + in slotptr() in typeobject.c . */ + PyTypeObject type; + PyNumberMethods as_number; + PyMappingMethods as_mapping; + PySequenceMethods as_sequence; /* as_sequence comes after as_mapping, + so that the mapping wins when both + the mapping and the sequence define + a given operator (e.g. __getitem__). + see add_operators() in typeobject.c . */ + PyBufferProcs as_buffer; + PyObject *name, *slots; + /* here are optional user slots, followed by the members. */ + } PyHeapTypeObject; + + /* access macro to the members which are floating "behind" the object */ + #define PyHeapType_GET_MEMBERS(etype) \ + ((PyMemberDef *)(((char *)etype) + (etype)->type.ob_type->tp_basicsize)) + + /* Generic type check */ PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *); From gvanrossum@users.sourceforge.net Fri Mar 7 15:13:52 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:13:52 -0800 Subject: [Python-checkins] python/dist/src/Objects typeobject.c,2.214,2.215 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv3464/Objects Modified Files: typeobject.c Log Message: - The extended type structure used for heap types (new-style classes defined by Python code using a class statement) is now exported from object.h as PyHeapTypeObject. (SF patch #696193.) Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.214 retrieving revision 2.215 diff -C2 -d -r2.214 -r2.215 *** typeobject.c 21 Feb 2003 22:02:54 -0000 2.214 --- typeobject.c 7 Mar 2003 15:13:17 -0000 2.215 *************** *** 6,27 **** #include - /* The *real* layout of a type object when allocated on the heap */ - /* XXX Should we publish this in a header file? */ - typedef struct { - /* Note: there's a dependency on the order of these members - in slotptr() below. */ - PyTypeObject type; - PyNumberMethods as_number; - PyMappingMethods as_mapping; - PySequenceMethods as_sequence; /* as_sequence comes after as_mapping, - so that the mapping wins when both - the mapping and the sequence define - a given operator (e.g. __getitem__). - see add_operators() below. */ - PyBufferProcs as_buffer; - PyObject *name, *slots; - PyMemberDef members[1]; - } etype; - static PyMemberDef type_members[] = { {"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY}, --- 6,9 ---- *************** *** 43,47 **** if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { ! etype* et = (etype*)type; Py_INCREF(et->name); --- 25,29 ---- if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { ! PyHeapTypeObject* et = (PyHeapTypeObject*)type; Py_INCREF(et->name); *************** *** 61,65 **** type_set_name(PyTypeObject *type, PyObject *value, void *context) { ! etype* et; if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { --- 43,47 ---- type_set_name(PyTypeObject *type, PyObject *value, void *context) { ! PyHeapTypeObject* et; if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { *************** *** 86,90 **** } ! et = (etype*)type; Py_INCREF(value); --- 68,72 ---- } ! et = (PyHeapTypeObject*)type; Py_INCREF(value); *************** *** 450,454 **** { PyObject *obj; ! const size_t size = _PyObject_VAR_SIZE(type, nitems); if (PyType_IS_GC(type)) --- 432,437 ---- { PyObject *obj; ! const size_t size = _PyObject_VAR_SIZE(type, nitems+1); ! /* note that we need to add one, for the sentinel */ if (PyType_IS_GC(type)) *************** *** 490,494 **** n = type->ob_size; ! mp = ((etype *)type)->members; for (i = 0; i < n; i++, mp++) { if (mp->type == T_OBJECT_EX) { --- 473,477 ---- n = type->ob_size; ! mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (i = 0; i < n; i++, mp++) { if (mp->type == T_OBJECT_EX) { *************** *** 555,559 **** n = type->ob_size; ! mp = ((etype *)type)->members; for (i = 0; i < n; i++, mp++) { if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) { --- 538,542 ---- n = type->ob_size; ! mp = PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (i = 0; i < n; i++, mp++) { if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) { *************** *** 1535,1539 **** PyObject *slots, *tmp, *newslots; PyTypeObject *type, *base, *tmptype, *winner; ! etype *et; PyMemberDef *mp; int i, nbases, nslots, slotoffset, add_dict, add_weak; --- 1518,1522 ---- PyObject *slots, *tmp, *newslots; PyTypeObject *type, *base, *tmptype, *winner; ! PyHeapTypeObject *et; PyMemberDef *mp; int i, nbases, nslots, slotoffset, add_dict, add_weak; *************** *** 1650,1654 **** /* Are slots allowed? */ nslots = PyTuple_GET_SIZE(slots); ! if (nslots > 0 && base->tp_itemsize != 0) { PyErr_Format(PyExc_TypeError, "nonempty __slots__ " --- 1633,1638 ---- /* Are slots allowed? */ nslots = PyTuple_GET_SIZE(slots); ! if (nslots > 0 && base->tp_itemsize != 0 && !PyType_Check(base)) { ! /* for the special case of meta types, allow slots */ PyErr_Format(PyExc_TypeError, "nonempty __slots__ " *************** *** 1771,1775 **** /* Keep name and slots alive in the extended type object */ ! et = (etype *)type; Py_INCREF(name); et->name = name; --- 1755,1759 ---- /* Keep name and slots alive in the extended type object */ ! et = (PyHeapTypeObject *)type; Py_INCREF(name); et->name = name; *************** *** 1851,1855 **** /* Add descriptors for custom slots from __slots__, or for __dict__ */ ! mp = et->members; slotoffset = base->tp_basicsize; if (slots != NULL) { --- 1835,1839 ---- /* Add descriptors for custom slots from __slots__, or for __dict__ */ ! mp = PyHeapType_GET_MEMBERS(et); slotoffset = base->tp_basicsize; if (slots != NULL) { *************** *** 1883,1887 **** type->tp_basicsize = slotoffset; type->tp_itemsize = base->tp_itemsize; ! type->tp_members = et->members; if (type->tp_weaklistoffset && type->tp_dictoffset) --- 1867,1871 ---- type->tp_basicsize = slotoffset; type->tp_itemsize = base->tp_itemsize; ! type->tp_members = PyHeapType_GET_MEMBERS(et); if (type->tp_weaklistoffset && type->tp_dictoffset) *************** *** 2053,2057 **** type_dealloc(PyTypeObject *type) { ! etype *et; /* Assert this is a heap-allocated type object */ --- 2037,2041 ---- type_dealloc(PyTypeObject *type) { ! PyHeapTypeObject *et; /* Assert this is a heap-allocated type object */ *************** *** 2059,2063 **** _PyObject_GC_UNTRACK(type); PyObject_ClearWeakRefs((PyObject *)type); ! et = (etype *)type; Py_XDECREF(type->tp_base); Py_XDECREF(type->tp_dict); --- 2043,2047 ---- _PyObject_GC_UNTRACK(type); PyObject_ClearWeakRefs((PyObject *)type); ! et = (PyHeapTypeObject *)type; Py_XDECREF(type->tp_base); Py_XDECREF(type->tp_dict); *************** *** 2135,2139 **** /* There's no need to visit type->tp_subclasses or ! ((etype *)type)->slots, because they can't be involved in cycles; tp_subclasses is a list of weak references, and slots is a tuple of strings. */ --- 2119,2123 ---- /* There's no need to visit type->tp_subclasses or ! ((PyHeapTypeObject *)type)->slots, because they can't be involved in cycles; tp_subclasses is a list of weak references, and slots is a tuple of strings. */ *************** *** 2181,2185 **** lists have their own tp_clear. ! slots (in etype): A tuple of strings can't be part of a cycle. */ --- 2165,2169 ---- lists have their own tp_clear. ! slots (in PyHeapTypeObject): A tuple of strings can't be part of a cycle. */ *************** *** 2202,2206 **** 0, /* ob_size */ "type", /* tp_name */ ! sizeof(etype), /* tp_basicsize */ sizeof(PyMemberDef), /* tp_itemsize */ (destructor)type_dealloc, /* tp_dealloc */ --- 2186,2190 ---- 0, /* ob_size */ "type", /* tp_name */ ! sizeof(PyHeapTypeObject), /* tp_basicsize */ sizeof(PyMemberDef), /* tp_itemsize */ (destructor)type_dealloc, /* tp_dealloc */ *************** *** 4687,4693 **** /* 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). The table is --- 4671,4678 ---- /* Table mapping __foo__ names to tp_foo offsets and slot_tp_foo wrapper ! functions. The offsets here are relative to the 'PyHeapTypeObject' ! 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). The table is *************** *** 4715,4719 **** PyDoc_STR(DOC), FLAGS} #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ! {NAME, offsetof(etype, SLOT), (void *)(FUNCTION), WRAPPER, \ PyDoc_STR(DOC)} #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ --- 4700,4704 ---- PyDoc_STR(DOC), FLAGS} #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ! {NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ PyDoc_STR(DOC)} #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ *************** *** 4929,4946 **** char *ptr; ! /* Note: this depends on the order of the members of etype! */ assert(offset >= 0); ! assert(offset < offsetof(etype, as_buffer)); ! if (offset >= offsetof(etype, as_sequence)) { ptr = (void *)type->tp_as_sequence; ! offset -= offsetof(etype, as_sequence); } ! else if (offset >= offsetof(etype, as_mapping)) { ptr = (void *)type->tp_as_mapping; ! offset -= offsetof(etype, as_mapping); } ! else if (offset >= offsetof(etype, as_number)) { ptr = (void *)type->tp_as_number; ! offset -= offsetof(etype, as_number); } else { --- 4914,4931 ---- char *ptr; ! /* Note: this depends on the order of the members of PyHeapTypeObject! */ assert(offset >= 0); ! assert(offset < offsetof(PyHeapTypeObject, as_buffer)); ! if (offset >= offsetof(PyHeapTypeObject, as_sequence)) { ptr = (void *)type->tp_as_sequence; ! offset -= offsetof(PyHeapTypeObject, as_sequence); } ! else if (offset >= offsetof(PyHeapTypeObject, as_mapping)) { ptr = (void *)type->tp_as_mapping; ! offset -= offsetof(PyHeapTypeObject, as_mapping); } ! else if (offset >= offsetof(PyHeapTypeObject, as_number)) { ptr = (void *)type->tp_as_number; ! offset -= offsetof(PyHeapTypeObject, as_number); } else { *************** *** 5217,5223 **** In the latter case, the first slotdef entry encoutered wins. Since ! slotdef entries are sorted by the offset of the slot in the etype ! struct, this gives us some control over disambiguating between ! competing slots: the members of struct etype are listed from most general to least general, so the most general slot is preferred. In particular, because as_mapping comes before as_sequence, for a type --- 5202,5208 ---- In the latter case, the first slotdef entry encoutered wins. Since ! slotdef entries are sorted by the offset of the slot in the ! PyHeapTypeObject, this gives us some control over disambiguating ! between competing slots: the members of PyHeapTypeObject are listed from most general to least general, so the most general slot is preferred. In particular, because as_mapping comes before as_sequence, for a type From bwarsaw@users.sourceforge.net Fri Mar 7 15:35:51 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:35:51 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv13009 Modified Files: test_email.py Log Message: test_string_headerinst_eq(): Another Jason test :) Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** test_email.py 6 Mar 2003 20:31:02 -0000 1.33 --- test_email.py 7 Mar 2003 15:35:47 -0000 1.34 *************** *** 781,784 **** --- 781,798 ---- """) + def test_string_headerinst_eq(self): + h = '<15975.17901.207240.414604@sgigritzmann1.mathematik.tu-muenchen.de> (David Bremner\'s message of "Thu, 6 Mar 2003 13:58:21 +0100")' + msg = Message() + msg['Received-1'] = Header(h, header_name='Received-1', + continuation_ws='\t') + msg['Received-2'] = h + self.assertEqual(msg.as_string(), """\ + Received-1: <15975.17901.207240.414604@sgigritzmann1.mathematik.tu-muenchen.de> + (David Bremner's message of "Thu, 6 Mar 2003 13:58:21 +0100") + Received-2: <15975.17901.207240.414604@sgigritzmann1.mathematik.tu-muenchen.de> + (David Bremner's message of "Thu, 6 Mar 2003 13:58:21 +0100") + + """) + From jackjansen@users.sourceforge.net Fri Mar 7 15:35:55 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:35:55 -0800 Subject: [Python-checkins] python/dist/src/Mac/Build PythonStandalone.mcp,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory sc8-pr-cvs1:/tmp/cvs-serv13004 Modified Files: PythonStandalone.mcp Log Message: Got PythonStandalone to work again, mainly for debugging purposes (it's much easier to debug GUSI errors in a static build). Index: PythonStandalone.mcp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonStandalone.mcp,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 Binary files /tmp/cvscDx7iL and /tmp/cvsQhFyAn differ From jackjansen@users.sourceforge.net Fri Mar 7 15:36:16 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:36:16 -0800 Subject: [Python-checkins] python/dist/src/Mac/mwerks mwerks_nscarbon_config.h,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/mwerks In directory sc8-pr-cvs1:/tmp/cvs-serv13278 Modified Files: mwerks_nscarbon_config.h Log Message: Got PythonStandalone to work again, mainly for debugging purposes (it's much easier to debug GUSI errors in a static build). Index: mwerks_nscarbon_config.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/mwerks/mwerks_nscarbon_config.h,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** mwerks_nscarbon_config.h 23 Jun 2002 22:09:45 -0000 1.9 --- mwerks_nscarbon_config.h 7 Mar 2003 15:36:13 -0000 1.10 *************** *** 11,24 **** #define USE_GUSI2 /* Stdio implemented with GUSI 2 */ #define USE_GUSI ! /* #define WITH_THREAD /* Use thread support (needs GUSI 2, not GUSI 1) */ #define USE_MSL /* Use Mw Standard Library (as opposed to Plaugher C libraries) */ #define USE_TOOLBOX /* Include toolbox modules in core Python */ #define USE_QT /* Include quicktime modules in core Python */ #define USE_WASTE /* Include waste module in core Python */ ! /* #define USE_MACSPEECH /* Include macspeech module in core Python */ ! #define USE_IMG /* Include img modules in core Python */ ! /* #define USE_MACCTB /* Include ctb module in core Python */ ! /* #define USE_TK /* Include _tkinter module in core Python */ ! /* #define MAC_TCL /* This *must* be on if USE_TK is on */ /* #define USE_MAC_SHARED_LIBRARY /* Enable code to add shared-library resources */ /* #define USE_MAC_APPLET_SUPPORT /* Enable code to run a PYC resource */ --- 11,20 ---- #define USE_GUSI2 /* Stdio implemented with GUSI 2 */ #define USE_GUSI ! #define WITH_THREAD /* Use thread support (needs GUSI 2, not GUSI 1) */ #define USE_MSL /* Use Mw Standard Library (as opposed to Plaugher C libraries) */ #define USE_TOOLBOX /* Include toolbox modules in core Python */ #define USE_QT /* Include quicktime modules in core Python */ #define USE_WASTE /* Include waste module in core Python */ ! /* #define USE_IMG /* Include img modules in core Python */ /* #define USE_MAC_SHARED_LIBRARY /* Enable code to add shared-library resources */ /* #define USE_MAC_APPLET_SUPPORT /* Enable code to run a PYC resource */ *************** *** 28,31 **** --- 24,31 ---- #define USE_IC /* Include Internet Config module */ #define USE_PYEXPAT /* Include Pyexpat module */ + #define XML_NS 1 + #define XML_DTD 1 + #define BYTEORDER 4321 + #define XML_CONTEXT_BYTES 1024 #define USE_MSL_MALLOC /* Disable private malloc. Also disables next two defines */ #ifndef USE_MSL_MALLOC From tim_one@users.sourceforge.net Fri Mar 7 15:36:47 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:36:47 -0800 Subject: [Python-checkins] python/dist/src/Lib tarfile.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv13161/python/Lib Modified Files: tarfile.py Log Message: Somebody must not have run the test before checking this in -- it had a fatal tab/space inconsistency under -tt. Index: tarfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tarfile.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** tarfile.py 7 Mar 2003 13:37:32 -0000 1.5 --- tarfile.py 7 Mar 2003 15:36:41 -0000 1.6 *************** *** 1531,1535 **** """ if not hasattr(os, 'utime'): ! return if sys.platform == "win32" and tarinfo.isdir(): # According to msdn.microsoft.com, it is an error (EACCES) --- 1531,1535 ---- """ if not hasattr(os, 'utime'): ! return if sys.platform == "win32" and tarinfo.isdir(): # According to msdn.microsoft.com, it is an error (EACCES) From jackjansen@users.sourceforge.net Fri Mar 7 15:36:56 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:36:56 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac macostools.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv13521 Modified Files: macostools.py Log Message: Filter out macfs warning. Index: macostools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/macostools.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** macostools.py 28 Jan 2003 23:53:40 -0000 1.2 --- macostools.py 7 Mar 2003 15:36:49 -0000 1.3 *************** *** 67,70 **** --- 67,72 ---- """Tell the finder a file has changed. No-op on MacOSX.""" if sys.platform != 'mac': return + import warnings + warnings.filterwarnings("ignore", "macfs.*", DeprecationWarning, __name__) import macfs file_fss = macfs.FSSpec(dst) From jackjansen@users.sourceforge.net Fri Mar 7 15:37:34 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:37:34 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules Nav.c,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv13860 Modified Files: Nav.c Log Message: Removed unused variable Index: Nav.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/Nav.c,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** Nav.c 17 Jan 2003 23:13:03 -0000 1.23 --- Nav.c 7 Mar 2003 15:37:31 -0000 1.24 *************** *** 114,118 **** PyObject *rv; Boolean c_rv = false; - PyObject theItemCopy; if (!dict) return false; --- 114,117 ---- From jackjansen@users.sourceforge.net Fri Mar 7 15:38:18 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:38:18 -0800 Subject: [Python-checkins] python/dist/src/Lib/test regrtest.py,1.133,1.134 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv14219 Modified Files: regrtest.py Log Message: Test_ioctl and test_tarfile are skipped on MacOS9. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.133 retrieving revision 1.134 diff -C2 -d -r1.133 -r1.134 *** regrtest.py 4 Mar 2003 00:26:38 -0000 1.133 --- regrtest.py 7 Mar 2003 15:38:11 -0000 1.134 *************** *** 631,634 **** --- 631,635 ---- test_grp test_iconv_codecs + test_ioctl test_imgfile test_largefile *************** *** 652,655 **** --- 653,657 ---- test_sunaudiodev test_sundry + test_tarfile test_timing test_unicode_file From bwarsaw@users.sourceforge.net Fri Mar 7 15:39:43 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:39:43 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Header.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv15067 Modified Files: Header.py Log Message: More internal refinements of the ascii splitting algorithm. _encode_chunks(): Pass maxlinelen in instead of always using self._maxlinelen, so we can adjust for shorter initial lines. Pass this value through to _max_append(). encode(): Weave maxlinelen through to the _encode_chunks() call. _split_ascii(): When recursively splitting a line on spaces (i.e. lower level syntactic split), don't append the whole returned string. Instead, split it on linejoiners and extend the lines up to the last line (for proper packing). Calculate the linelen based on the last element in the this list. Index: Header.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Header.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** Header.py 6 Mar 2003 23:41:58 -0000 1.22 --- Header.py 7 Mar 2003 15:39:37 -0000 1.23 *************** *** 343,347 **** return zip(lines, [charset]*len(lines)) ! def _encode_chunks(self, newchunks): # MIME-encode a header with many different charsets and/or encodings. # --- 343,347 ---- return zip(lines, [charset]*len(lines)) ! def _encode_chunks(self, newchunks, maxlinelen): # MIME-encode a header with many different charsets and/or encodings. # *************** *** 368,372 **** else: s = charset.header_encode(header) ! _max_append(chunks, s, self._maxlinelen, ' ') joiner = NL + self._continuation_ws return joiner.join(chunks) --- 368,372 ---- else: s = charset.header_encode(header) ! _max_append(chunks, s, maxlinelen, ' ') joiner = NL + self._continuation_ws return joiner.join(chunks) *************** *** 408,416 **** lastchunk, lastcharset = newchunks[-1] lastlen = lastcharset.encoded_header_len(lastchunk) ! return self._encode_chunks(newchunks) def _split_ascii(s, firstlen, restlen, continuation_ws, splitchars): lines = [] maxlen = firstlen --- 408,417 ---- lastchunk, lastcharset = newchunks[-1] lastlen = lastcharset.encoded_header_len(lastchunk) ! return self._encode_chunks(newchunks, maxlinelen) def _split_ascii(s, firstlen, restlen, continuation_ws, splitchars): + linejoiner = '\n' + continuation_ws lines = [] maxlen = firstlen *************** *** 461,469 **** # on whitespace. if partlen > maxlen and ch <> ' ': ! this = [_split_ascii(part, maxlen, restlen, ! continuation_ws, ' ')] else: this = [part] ! linelen = wslen + partlen maxlen = restlen else: --- 462,473 ---- # on whitespace. if partlen > maxlen and ch <> ' ': ! subs = _split_ascii(part, maxlen, restlen, ! continuation_ws, ' ') ! subl = re.split(linejoiner, subs) ! lines.extend(subl[:-1]) ! this = [subl[-1]] else: this = [part] ! linelen = wslen + len(this[-1]) maxlen = restlen else: *************** *** 473,477 **** if this: lines.append(joiner.join(this)) - linejoiner = '\n' + continuation_ws return linejoiner.join(lines) --- 477,480 ---- From bwarsaw@users.sourceforge.net Fri Mar 7 15:43:23 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:43:23 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Generator.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv17098 Modified Files: Generator.py Log Message: _write_headers(), _split_header(): All of the smarts for splitting long header lines is now (properly) in the Header class. So we no longer need _split_header() and we'll just defer to Header.encode() when we have a plain string. Index: Generator.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Generator.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** Generator.py 6 Mar 2003 05:22:02 -0000 1.18 --- Generator.py 7 Mar 2003 15:43:17 -0000 1.19 *************** *** 162,202 **** def _write_headers(self, msg): for h, v in msg.items(): ! # RFC 2822 says that lines SHOULD be no more than maxheaderlen ! # characters wide, so we're well within our rights to split long ! # headers. ! text = '%s: %s' % (h, v) ! if self.__maxheaderlen > 0 and len(text) > self.__maxheaderlen: ! text = self._split_header(text) ! print >> self._fp, text # A blank line always separates headers from body print >> self._fp - - def _split_header(self, text): - maxheaderlen = self.__maxheaderlen - # Find out whether any lines in the header are really longer than - # maxheaderlen characters wide. There could be continuation lines - # that actually shorten it. Also, replace hard tabs with 8 spaces. - lines = [s.replace('\t', SPACE8) for s in text.splitlines()] - for line in lines: - if len(line) > maxheaderlen: - break - else: - # No line was actually longer than maxheaderlen characters, so - # just return the original unchanged. - return text - # If we have raw 8bit data in a byte string, we have no idea what the - # encoding is. I think there is no safe way to split this string. If - # it's ascii-subset, then we could do a normal ascii split, but if - # it's multibyte then we could break the string. There's no way to - # know so the least harm seems to be to not split the string and risk - # it being too long. - if _is8bitstring(text): - return text - # The `text' argument already has the field name prepended, so don't - # provide it here or the first line will get folded too short. - h = Header(text, maxlinelen=maxheaderlen, - # For backwards compatibility, we use a hard tab here - continuation_ws='\t') - return h.encode() # --- 162,187 ---- def _write_headers(self, msg): for h, v in msg.items(): ! print >> self._fp, '%s:' % h, ! if self.__maxheaderlen == 0: ! # Explicit no-wrapping ! print >> self._fp, v ! elif isinstance(v, Header): ! # Header instances know what to do ! print >> self._fp, v.encode() ! elif _is8bitstring(v): ! # If we have raw 8bit data in a byte string, we have no idea ! # what the encoding is. There is no safe way to split this ! # string. If it's ascii-subset, then we could do a normal ! # ascii split, but if it's multibyte then we could break the ! # string. There's no way to know so the least harm seems to ! # be to not split the string and risk it being too long. ! print >> self._fp, v ! else: ! # Header's got lots of smarts, so use it. ! print >> self._fp, Header( ! v, maxlinelen=self.__maxheaderlen, ! header_name=h, continuation_ws='\t').encode() # A blank line always separates headers from body print >> self._fp # From montanaro@users.sourceforge.net Fri Mar 7 15:45:19 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:45:19 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.127,1.128 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv18019 Modified Files: whatsnew23.tex Log Message: Add a little more verbiage about the bsddb module/package change. It's clear from recent discussions on c.l.py that people are a bit confused about the differences between the old bsddb, the new bssdb, the bsddb3/PyBSDDB package and changes to file formats. Tried to clarify the issues. Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.127 retrieving revision 1.128 diff -C2 -d -r1.127 -r1.128 *** whatsnew23.tex 2 Mar 2003 02:31:58 -0000 1.127 --- whatsnew23.tex 7 Mar 2003 15:45:15 -0000 1.128 *************** *** 1267,1271 **** \module{bsddb} package is intended to be compatible with the old module, so be sure to file bugs if you discover any ! incompatibilities. \item The Distutils \class{Extension} class now supports --- 1267,1278 ---- \module{bsddb} package is intended to be compatible with the old module, so be sure to file bugs if you discover any ! incompatibilities. When upgrading to Python 2.3, if you also change ! the underlying BerkeleyDB library, you will almost certainly have to ! convert your database files to the new version. You can do this ! fairly easily with the new scripts \file{db2pickle.py} and ! \file{pickle2db.py} which you will find in the distribution's ! Tools/scripts directory. If you've already been using the PyBSDDB ! package, importing it as \module{bsddb3}, you will have to change your ! \code{import} statements. \item The Distutils \class{Extension} class now supports From theller@python.net Fri Mar 7 15:50:59 2003 From: theller@python.net (Thomas Heller) Date: 07 Mar 2003 16:50:59 +0100 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.691,1.692 In-Reply-To: References: Message-ID: gvanrossum@users.sourceforge.net writes: > Update of /cvsroot/python/python/dist/src/Misc > In directory sc8-pr-cvs1:/tmp/cvs-serv3464/Misc > > Modified Files: > NEWS > Log Message: > - The extended type structure used for heap types (new-style > classes defined by Python code using a class statement) is now > exported from object.h as PyHeapTypeObject. (SF patch #696193.) If I understand correctly, this adds no new behaviour but new possibilities for extension programmers. True? If so, it would really be nice if it would be backported to 2.2.x. Thomas From tim_one@users.sourceforge.net Fri Mar 7 15:55:41 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:55:41 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_dis.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv22717 Modified Files: test_dis.py Log Message: This test relied on significant trailing whitespace in a string literal. Evil. Index: test_dis.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_dis.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_dis.py 27 Feb 2003 21:27:07 -0000 1.1 --- test_dis.py 7 Mar 2003 15:55:36 -0000 1.2 *************** *** 11,26 **** # line numbers in dis_f def _f(a): ! print a ! return 1 dis_f = """\ 13 0 LOAD_FAST 0 (a) ! 3 PRINT_ITEM ! 4 PRINT_NEWLINE 14 5 LOAD_CONST 1 (1) ! 8 RETURN_VALUE 9 LOAD_CONST 0 (None) ! 12 RETURN_VALUE """ --- 11,26 ---- # line numbers in dis_f def _f(a): ! print a ! return 1 dis_f = """\ 13 0 LOAD_FAST 0 (a) ! 3 PRINT_ITEM ! 4 PRINT_NEWLINE 14 5 LOAD_CONST 1 (1) ! 8 RETURN_VALUE 9 LOAD_CONST 0 (None) ! 12 RETURN_VALUE """ *************** *** 44,48 **** dis.dis(_f) sys.stdout = save_stdout ! self.assertEqual(dis_f, s.getvalue()) def test_main(): --- 44,53 ---- dis.dis(_f) sys.stdout = save_stdout ! got = s.getvalue() ! # Trim trailing blanks (if any). ! lines = got.split('\n') ! lines = [line.rstrip() for line in lines] ! got = '\n'.join(lines) ! self.assertEqual(dis_f, got) def test_main(): From bwarsaw@users.sourceforge.net Fri Mar 7 15:58:53 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Fri, 07 Mar 2003 07:58:53 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv25158 Modified Files: test_email.py Log Message: whitespace normalization Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** test_email.py 7 Mar 2003 15:35:47 -0000 1.34 --- test_email.py 7 Mar 2003 15:58:51 -0000 1.35 *************** *** 773,781 **** self.assertEqual(msg.as_string(), """\ Received-1: from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by ! hrothgar.la.mastaler.com (tmda-ofmipd) with ESMTP; ! Wed, 05 Mar 2003 18:10:18 -0700 Received-2: from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by ! hrothgar.la.mastaler.com (tmda-ofmipd) with ESMTP; ! Wed, 05 Mar 2003 18:10:18 -0700 """) --- 773,781 ---- self.assertEqual(msg.as_string(), """\ Received-1: from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by ! \throthgar.la.mastaler.com (tmda-ofmipd) with ESMTP; ! \tWed, 05 Mar 2003 18:10:18 -0700 Received-2: from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by ! \throthgar.la.mastaler.com (tmda-ofmipd) with ESMTP; ! \tWed, 05 Mar 2003 18:10:18 -0700 """) *************** *** 789,795 **** self.assertEqual(msg.as_string(), """\ Received-1: <15975.17901.207240.414604@sgigritzmann1.mathematik.tu-muenchen.de> ! (David Bremner's message of "Thu, 6 Mar 2003 13:58:21 +0100") Received-2: <15975.17901.207240.414604@sgigritzmann1.mathematik.tu-muenchen.de> ! (David Bremner's message of "Thu, 6 Mar 2003 13:58:21 +0100") """) --- 789,795 ---- self.assertEqual(msg.as_string(), """\ Received-1: <15975.17901.207240.414604@sgigritzmann1.mathematik.tu-muenchen.de> ! \t(David Bremner's message of "Thu, 6 Mar 2003 13:58:21 +0100") Received-2: <15975.17901.207240.414604@sgigritzmann1.mathematik.tu-muenchen.de> ! \t(David Bremner's message of "Thu, 6 Mar 2003 13:58:21 +0100") """) From tim_one@users.sourceforge.net Fri Mar 7 17:30:53 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 07 Mar 2003 09:30:53 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_plistlib.py,1.1,1.2 test_ucn.py,1.12,1.13 test_unicodedata.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv6619/python/Lib/test Modified Files: test_plistlib.py test_ucn.py test_unicodedata.py Log Message: Whitespace normalization. Index: test_plistlib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_plistlib.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_plistlib.py 25 Feb 2003 12:58:58 -0000 1.1 --- test_plistlib.py 7 Mar 2003 17:30:47 -0000 1.2 *************** *** 38,42 **** pl['aDate'] = plistlib.Date(time.mktime(time.gmtime())) return pl ! def test_create(self): pl = self._create() --- 38,42 ---- pl['aDate'] = plistlib.Date(time.mktime(time.gmtime())) return pl ! def test_create(self): pl = self._create() *************** *** 48,52 **** pl.write(test_support.TESTFN) pl2 = plistlib.Plist.fromFile(test_support.TESTFN) ! self.assertEqual(dict(pl), dict(pl2)) --- 48,52 ---- pl.write(test_support.TESTFN) pl2 = plistlib.Plist.fromFile(test_support.TESTFN) ! self.assertEqual(dict(pl), dict(pl2)) Index: test_ucn.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_ucn.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_ucn.py 26 Feb 2003 14:49:38 -0000 1.12 --- test_ucn.py 7 Mar 2003 17:30:48 -0000 1.13 *************** *** 16,20 **** def checkletter(self, name, code): # Helper that put all \N escapes inside eval'd raw strings, ! # to make sure this script runs even if the compiler # chokes on \N escapes res = eval(ur'u"\N{%s}"' % name) --- 16,20 ---- def checkletter(self, name, code): # Helper that put all \N escapes inside eval'd raw strings, ! # to make sure this script runs even if the compiler # chokes on \N escapes res = eval(ur'u"\N{%s}"' % name) Index: test_unicodedata.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicodedata.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_unicodedata.py 26 Feb 2003 14:49:39 -0000 1.7 --- test_unicodedata.py 7 Mar 2003 17:30:48 -0000 1.8 *************** *** 192,196 **** def test_digit_numeric_consistent(self): # Test that digit and numeric are consistent, ! # i.e. if a character has a digit value, # it's numeric value should be the same. count = 0 --- 192,196 ---- def test_digit_numeric_consistent(self): # Test that digit and numeric are consistent, ! # i.e. if a character has a digit value, # it's numeric value should be the same. count = 0 From tim_one@users.sourceforge.net Fri Mar 7 17:31:20 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 07 Mar 2003 09:31:20 -0800 Subject: [Python-checkins] python/dist/src/Lib dis.py,1.45,1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv6619/python/Lib Modified Files: dis.py Log Message: Whitespace normalization. Index: dis.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dis.py,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** dis.py 27 Feb 2003 21:29:27 -0000 1.45 --- dis.py 7 Mar 2003 17:30:45 -0000 1.46 *************** *** 132,174 **** def disassemble_string(code, lasti=-1, varnames=None, names=None, constants=None): ! labels = findlabels(code) ! n = len(code) ! i = 0 ! while i < n: ! c = code[i] ! op = ord(c) ! if op == opmap['SET_LINENO'] and i > 0: ! print # Extra blank line ! if i == lasti: print '-->', ! else: print ' ', ! if i in labels: print '>>', ! else: print ' ', ! print `i`.rjust(4), ! print opname[op].ljust(15), ! i = i+1 ! if op >= HAVE_ARGUMENT: ! oparg = ord(code[i]) + ord(code[i+1])*256 ! i = i+2 ! print `oparg`.rjust(5), ! if op in hasconst: ! if constants: ! print '(' + `constants[oparg]` + ')', ! else: ! print '(%d)'%oparg, ! elif op in hasname: ! if names is not None: ! print '(' + names[oparg] + ')', ! else: ! print '(%d)'%oparg, ! elif op in hasjrel: ! print '(to ' + `i + oparg` + ')', ! elif op in haslocal: ! if varnames: ! print '(' + varnames[oparg] + ')', ! else: ! print '(%d)' % oparg, ! elif op in hascompare: ! print '(' + cmp_op[oparg] + ')', ! print disco = disassemble # XXX For backwards compatibility --- 132,174 ---- def disassemble_string(code, lasti=-1, varnames=None, names=None, constants=None): ! labels = findlabels(code) ! n = len(code) ! i = 0 ! while i < n: ! c = code[i] ! op = ord(c) ! if op == opmap['SET_LINENO'] and i > 0: ! print # Extra blank line ! if i == lasti: print '-->', ! else: print ' ', ! if i in labels: print '>>', ! else: print ' ', ! print `i`.rjust(4), ! print opname[op].ljust(15), ! i = i+1 ! if op >= HAVE_ARGUMENT: ! oparg = ord(code[i]) + ord(code[i+1])*256 ! i = i+2 ! print `oparg`.rjust(5), ! if op in hasconst: ! if constants: ! print '(' + `constants[oparg]` + ')', ! else: ! print '(%d)'%oparg, ! elif op in hasname: ! if names is not None: ! print '(' + names[oparg] + ')', ! else: ! print '(%d)'%oparg, ! elif op in hasjrel: ! print '(to ' + `i + oparg` + ')', ! elif op in haslocal: ! if varnames: ! print '(' + varnames[oparg] + ')', ! else: ! print '(%d)' % oparg, ! elif op in hascompare: ! print '(' + cmp_op[oparg] + ')', ! print disco = disassemble # XXX For backwards compatibility From tim_one@users.sourceforge.net Fri Mar 7 17:31:21 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 07 Mar 2003 09:31:21 -0800 Subject: [Python-checkins] python/dist/src/Lib/compiler transformer.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/compiler In directory sc8-pr-cvs1:/tmp/cvs-serv6619/python/Lib/compiler Modified Files: transformer.py Log Message: Whitespace normalization. Index: transformer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/transformer.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** transformer.py 3 Jan 2003 10:25:20 -0000 1.36 --- transformer.py 7 Mar 2003 17:30:47 -0000 1.37 *************** *** 143,147 **** node = node[1] n = node[0] ! if n == symbol.single_input: return self.single_input(node[1:]) --- 143,147 ---- node = node[1] n = node[0] ! if n == symbol.single_input: return self.single_input(node[1:]) From guido@python.org Fri Mar 7 17:44:56 2003 From: guido@python.org (Guido van Rossum) Date: Fri, 07 Mar 2003 12:44:56 -0500 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.691,1.692 In-Reply-To: "Your message of 07 Mar 2003 16:50:59 +0100." References: Message-ID: <200303071744.h27HiuD23061@pcp02138704pcs.reston01.va.comcast.net> > > Modified Files: > > NEWS > > Log Message: > > - The extended type structure used for heap types (new-style > > classes defined by Python code using a class statement) is now > > exported from object.h as PyHeapTypeObject. (SF patch #696193.) > > If I understand correctly, this adds no new behaviour but new > possibilities for extension programmers. True? > If so, it would really be nice if it would be backported to 2.2.x. If you would do the honors, that's fine with me. --Guido van Rossum (home page: http://www.python.org/~guido/) From tim_one@users.sourceforge.net Fri Mar 7 21:10:25 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Fri, 07 Mar 2003 13:10:25 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_popen.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv17046/Lib/test Modified Files: test_popen.py Log Message: Don't quote the path to Python unless the path contains an embedded space. Quoting the path doesn't work on Win2K (cmd.exe) regardless, this is just a hack to let the test pass again on Win2K (so long as Python isn't installed in a path that does contain an embedded space). On Win2K it looks like we'd also have to add a second pair of double quotes, around the entire command line. Index: test_popen.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_popen.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_popen.py 24 Feb 2003 15:26:39 -0000 1.4 --- test_popen.py 7 Mar 2003 21:10:21 -0000 1.5 *************** *** 15,20 **** # This results in Python being spawned and printing the sys.argv list. # We can then eval() the result of this, and see what each argv was. def _do_test_commandline(cmdline, expected): ! cmd = '"%s" -c "import sys;print sys.argv" %s' % (sys.executable, cmdline) data = popen(cmd).read() got = eval(data)[1:] # strip off argv[0] --- 15,23 ---- # This results in Python being spawned and printing the sys.argv list. # We can then eval() the result of this, and see what each argv was. + python = sys.executable + if ' ' in python: + python = '"' + python + '"' # quote embedded space for cmdline def _do_test_commandline(cmdline, expected): ! cmd = '%s -c "import sys;print sys.argv" %s' % (python, cmdline) data = popen(cmd).read() got = eval(data)[1:] # strip off argv[0] From theller@python.net Fri Mar 7 21:43:21 2003 From: theller@python.net (Thomas Heller) Date: 07 Mar 2003 22:43:21 +0100 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.691,1.692 In-Reply-To: <200303071744.h27HiuD23061@pcp02138704pcs.reston01.va.comcast.net> References: <200303071744.h27HiuD23061@pcp02138704pcs.reston01.va.comcast.net> Message-ID: Guido van Rossum writes: > > > Modified Files: > > > NEWS > > > Log Message: > > > - The extended type structure used for heap types (new-style > > > classes defined by Python code using a class statement) is now > > > exported from object.h as PyHeapTypeObject. (SF patch #696193.) > > [me] > > If I understand correctly, this adds no new behaviour but new > > possibilities for extension programmers. True? > > If so, it would really be nice if it would be backported to 2.2.x. > > If you would do the honors, that's fine with me. > I'm afraid I don't have time for it. Christian, do you have a patch ready for the 2.2 branch? Thomas From bwarsaw@users.sourceforge.net Fri Mar 7 22:45:58 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Fri, 07 Mar 2003 14:45:58 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv27382 Modified Files: test_email.py Log Message: test_rfc2231_no_language_or_charset(): RFC 2231 allows leaving out both the charset and language without including any single quotes. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** test_email.py 7 Mar 2003 15:58:51 -0000 1.35 --- test_email.py 7 Mar 2003 22:45:55 -0000 1.36 *************** *** 2547,2550 **** --- 2547,2561 ---- eq(msg.get_content_charset(), 'us-ascii') + def test_rfc2231_no_language_or_charset(self): + m = '''\ + Content-Transfer-Encoding: 8bit + Content-Disposition: inline; filename="file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm" + Content-Type: text/html; NAME*0=file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEM; NAME*1=P_nsmail.htm + + ''' + msg = email.message_from_string(m) + self.assertEqual(msg.get_param('NAME'), + (None, None, 'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm')) + From bwarsaw@users.sourceforge.net Fri Mar 7 22:46:44 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Fri, 07 Mar 2003 14:46:44 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Utils.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv27678 Modified Files: Utils.py Log Message: decode_rfc2231(): RFC 2231 allows leaving out both the charset and language without including any single quotes. Index: Utils.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Utils.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** Utils.py 5 Nov 2002 19:54:21 -0000 1.21 --- Utils.py 7 Mar 2003 22:46:41 -0000 1.22 *************** *** 281,287 **** """Decode string according to RFC 2231""" import urllib ! charset, language, s = s.split("'", 2) ! s = urllib.unquote(s) ! return charset, language, s --- 281,289 ---- """Decode string according to RFC 2231""" import urllib ! parts = s.split("'", 2) ! if len(parts) == 1: ! return None, None, s ! charset, language, s = parts ! return charset, language, urllib.unquote(s) *************** *** 336,340 **** value.append(continuation) charset, language, value = decode_rfc2231(EMPTYSTRING.join(value)) ! new_params.append((name, ! (charset, language, '"%s"' % quote(value)))) return new_params --- 338,342 ---- value.append(continuation) charset, language, value = decode_rfc2231(EMPTYSTRING.join(value)) ! new_params.append( ! (name, (charset, language, '"%s"' % quote(value)))) return new_params From bwarsaw@users.sourceforge.net Fri Mar 7 23:23:07 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Fri, 07 Mar 2003 15:23:07 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv11458 Modified Files: test_email.py Log Message: test_long_unbreakable_lines_with_continuation(): Another funky example from Jason Mastaler :) Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** test_email.py 7 Mar 2003 22:45:55 -0000 1.36 --- test_email.py 7 Mar 2003 23:23:04 -0000 1.37 *************** *** 795,798 **** --- 795,814 ---- """) + def test_long_unbreakable_lines_with_continuation(self): + eq = self.ndiffAssertEqual + msg = Message() + t = """\ + iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9 + locQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp""" + msg['Face-1'] = t + msg['Face-2'] = Header(t, header_name='Face-2') + eq(msg.as_string(), """\ + Face-1: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9 + \tlocQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp + Face-2: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9 + locQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp + + """) + From bwarsaw@users.sourceforge.net Fri Mar 7 23:24:37 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Fri, 07 Mar 2003 15:24:37 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Header.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv12181 Modified Files: Header.py Log Message: _split_ascii(): lstrip the individual lines in the ascii split lines, since we'll be adding our own continuation whitespace later. Index: Header.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Header.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** Header.py 7 Mar 2003 15:39:37 -0000 1.23 --- Header.py 7 Mar 2003 23:24:34 -0000 1.24 *************** *** 417,420 **** --- 417,423 ---- maxlen = firstlen for line in s.splitlines(): + # Ignore any leading whitespace (i.e. continuation whitespace) already + # on the line, since we'll be adding our own. + line = line.lstrip() if len(line) < maxlen: lines.append(line) From loewis@users.sourceforge.net Sat Mar 8 10:25:34 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Sat, 08 Mar 2003 02:25:34 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_unicode_file.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv25398 Modified Files: test_unicode_file.py Log Message: Skip the test if TESTFN_ENCODING is None. Fixes #699386. Index: test_unicode_file.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode_file.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_unicode_file.py 3 Oct 2002 05:10:38 -0000 1.6 --- test_unicode_file.py 8 Mar 2003 10:25:31 -0000 1.7 *************** *** 5,26 **** from test.test_support import verify, TestSkipped, TESTFN_UNICODE try: ! from test.test_support import TESTFN_ENCODING ! oldlocale = None ! except ImportError: ! import locale ! # try to run the test in an UTF-8 locale. If this locale is not ! # available, avoid running the test since the locale's encoding ! # might not support TESTFN_UNICODE. Likewise, if the system does ! # not support locale.CODESET, Unicode file semantics is not ! # available, either. ! oldlocale = locale.setlocale(locale.LC_CTYPE) ! try: ! locale.setlocale(locale.LC_CTYPE,"en_US.UTF-8") ! TESTFN_ENCODING = locale.nl_langinfo(locale.CODESET) ! except (locale.Error, AttributeError): ! raise TestSkipped("No Unicode filesystem semantics on this platform.") ! ! TESTFN_ENCODED = TESTFN_UNICODE.encode(TESTFN_ENCODING) # Check with creation as Unicode string. --- 5,15 ---- from test.test_support import verify, TestSkipped, TESTFN_UNICODE + from test.test_support import TESTFN_ENCODING try: ! TESTFN_ENCODED = TESTFN_UNICODE.encode(TESTFN_ENCODING) ! except (ImportError, TypeError): ! # Either the file system encoding is None, or the file name ! # cannot be encoded in the file system encoding. ! raise TestSkipped("No Unicode filesystem semantics on this platform.") # Check with creation as Unicode string. *************** *** 105,108 **** os.rmdir(abs_encoded) print "All the Unicode tests appeared to work" - if oldlocale: - locale.setlocale(locale.LC_CTYPE, oldlocale) --- 94,95 ---- From jvr@users.sourceforge.net Sat Mar 8 19:50:40 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Sat, 08 Mar 2003 11:50:40 -0800 Subject: [Python-checkins] python/dist/src/Tools/freeze freeze.py,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/freeze In directory sc8-pr-cvs1:/tmp/cvs-serv26611 Modified Files: freeze.py Log Message: [ 684677 ] Allow freeze to exclude implicits Index: freeze.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/freeze/freeze.py,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** freeze.py 11 Sep 2002 20:36:00 -0000 1.42 --- freeze.py 8 Mar 2003 19:50:38 -0000 1.43 *************** *** 131,137 **** fail_import = exclude[:] - # modules that are imported by the Python runtime - implicits = ["site", "exceptions"] - # output files frozen_c = 'frozen.c' --- 131,134 ---- *************** *** 202,205 **** --- 199,208 ---- f,r = a.split("=", 2) replace_paths.append( (f,r) ) + + # modules that are imported by the Python runtime + implicits = [] + for module in ('site', 'exceptions',): + if module not in exclude: + implicits.append(module) # default prefix and exec_prefix From theller@python.net Sat Mar 8 21:13:09 2003 From: theller@python.net (Thomas Heller) Date: 08 Mar 2003 22:13:09 +0100 Subject: [Python-checkins] python/dist/src/Tools/freeze freeze.py,1.42,1.43 In-Reply-To: References: Message-ID: jvr@users.sourceforge.net writes: > Update of /cvsroot/python/python/dist/src/Tools/freeze > In directory sc8-pr-cvs1:/tmp/cvs-serv26611 > > Modified Files: > freeze.py > Log Message: > [ 684677 ] Allow freeze to exclude implicits > > Index: freeze.py > =================================================================== > RCS file: /cvsroot/python/python/dist/src/Tools/freeze/freeze.py,v > + # modules that are imported by the Python runtime > + implicits = [] > + for module in ('site', 'exceptions',): ^^^^^^^^^^^ Isn't this a relict from the times when exceptions was *not* a builtin module (1.5, iirc)? > + if module not in exclude: > + implicits.append(module) > > # default prefix and exec_prefix > > > > _______________________________________________ > Python-checkins mailing list > Python-checkins@python.org > http://mail.python.org/mailman/listinfo/python-checkins From just@letterror.com Sat Mar 8 21:21:40 2003 From: just@letterror.com (Just van Rossum) Date: Sat, 8 Mar 2003 22:21:40 +0100 Subject: [Python-checkins] python/dist/src/Tools/freeze freeze.py,1.42,1.43 In-Reply-To: Message-ID: Thomas Heller wrote: > > + # modules that are imported by the Python runtime > > + implicits = [] > > + for module in ('site', 'exceptions',): > ^^^^^^^^^^^ > > Isn't this a relict from the times when exceptions was *not* > a builtin module (1.5, iirc)? Good point, I think 'exceptions' should be replaced with 'warnings'... Just From rhettinger@users.sourceforge.net Sun Mar 9 05:33:34 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 08 Mar 2003 21:33:34 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.692,1.693 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv26947/Misc Modified Files: NEWS Log Message: SF 698520: Iterator for urllib.URLOpener Contributed by Brett Cannon. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.692 retrieving revision 1.693 diff -C2 -d -r1.692 -r1.693 *** NEWS 7 Mar 2003 15:13:06 -0000 1.692 --- NEWS 9 Mar 2003 05:33:32 -0000 1.693 *************** *** 47,50 **** --- 47,53 ---- ------- + - The urllib module now offers support for the iterator protocol. + SF patch 698520 contributed by Brett Cannon. + - New module timeit provides a simple framework for timing the execution speed of expressions and statements. From rhettinger@users.sourceforge.net Sun Mar 9 05:33:35 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 08 Mar 2003 21:33:35 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib liburllib.tex,1.44,1.45 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv26947/Doc/lib Modified Files: liburllib.tex Log Message: SF 698520: Iterator for urllib.URLOpener Contributed by Brett Cannon. Index: liburllib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liburllib.tex,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** liburllib.tex 22 Oct 2002 21:58:06 -0000 1.44 --- liburllib.tex 9 Mar 2003 05:33:32 -0000 1.45 *************** *** 28,32 **** supports the following methods: \method{read()}, \method{readline()}, \method{readlines()}, \method{fileno()}, \method{close()}, ! \method{info()} and \method{geturl()}. Except for the \method{info()} and \method{geturl()} methods, --- 28,33 ---- supports the following methods: \method{read()}, \method{readline()}, \method{readlines()}, \method{fileno()}, \method{close()}, ! \method{info()} and \method{geturl()}. It also has proper support for ! the iterator protocol. Except for the \method{info()} and \method{geturl()} methods, From rhettinger@users.sourceforge.net Sun Mar 9 05:33:35 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 08 Mar 2003 21:33:35 -0800 Subject: [Python-checkins] python/dist/src/Lib urllib.py,1.154,1.155 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv26947/Lib Modified Files: urllib.py Log Message: SF 698520: Iterator for urllib.URLOpener Contributed by Brett Cannon. Index: urllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/urllib.py,v retrieving revision 1.154 retrieving revision 1.155 diff -C2 -d -r1.154 -r1.155 *** urllib.py 27 Feb 2003 20:14:43 -0000 1.154 --- urllib.py 9 Mar 2003 05:33:33 -0000 1.155 *************** *** 781,784 **** --- 781,788 ---- if hasattr(self.fp, "readlines"): self.readlines = self.fp.readlines if hasattr(self.fp, "fileno"): self.fileno = self.fp.fileno + if hasattr(self.fp, "__iter__"): + self.__iter__ = self.fp.__iter__ + if hasattr(self.fp, "next"): + self.next = self.fp.next def __repr__(self): From rhettinger@users.sourceforge.net Sun Mar 9 07:05:17 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 08 Mar 2003 23:05:17 -0800 Subject: [Python-checkins] python/dist/src/Lib weakref.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv14516/Lib Modified Files: weakref.py Log Message: SF patch #667730: More DictMixin * Adds missing pop() methods to weakref.py * Expands test suite to broaden coverage of objects with a mapping interface. Contributed by Sebastien Keim. Index: weakref.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/weakref.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** weakref.py 16 Jul 2002 21:35:23 -0000 1.18 --- weakref.py 9 Mar 2003 07:05:13 -0000 1.19 *************** *** 102,105 **** --- 102,117 ---- return key, o + def pop(self, key, *args): + try: + o = self.data.pop(key)() + except KeyError: + if args: + return args[0] + raise + if o is None: + raise KeyError, key + else: + return o + def setdefault(self, key, default): try: *************** *** 225,228 **** --- 237,243 ---- if o is not None: return o, value + + def pop(self, key, *args): + return self.data.pop(ref(key), *args) def setdefault(self, key, default): From rhettinger@users.sourceforge.net Sun Mar 9 07:05:17 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 08 Mar 2003 23:05:17 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_os.py,1.13,1.14 test_shelve.py,1.2,1.3 test_userdict.py,1.13,1.14 test_weakref.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv14516/Lib/test Modified Files: test_os.py test_shelve.py test_userdict.py test_weakref.py Log Message: SF patch #667730: More DictMixin * Adds missing pop() methods to weakref.py * Expands test suite to broaden coverage of objects with a mapping interface. Contributed by Sebastien Keim. Index: test_os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_os.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** test_os.py 22 Aug 2002 19:40:33 -0000 1.13 --- test_os.py 9 Mar 2003 07:05:13 -0000 1.14 *************** *** 186,193 **** --- 186,211 ---- pass + from test_userdict import TestMappingProtocol + + class EnvironTests(TestMappingProtocol): + """check that os.environ object conform to mapping protocol""" + _tested_class = None + def _reference(self): + return {"KEY1":"VALUE1", "KEY2":"VALUE2", "KEY3":"VALUE3"} + def _empty_mapping(self): + os.environ.clear() + return os.environ + def setUp(self): + self.__save = dict(os.environ) + os.environ.clear() + def tearDown(self): + os.environ.clear() + os.environ.update(self.__save) + def test_main(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TemporaryFileTests)) suite.addTest(unittest.makeSuite(StatAttributeTests)) + suite.addTest(unittest.makeSuite(EnvironTests)) run_suite(suite) Index: test_shelve.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_shelve.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_shelve.py 24 Dec 2002 18:31:27 -0000 1.2 --- test_shelve.py 9 Mar 2003 07:05:14 -0000 1.3 *************** *** 44,50 **** self.assertNotEqual(d1, d2) ! def test_main(): ! test_support.run_unittest(TestCase) if __name__ == "__main__": --- 44,95 ---- self.assertNotEqual(d1, d2) ! from test_userdict import TestMappingProtocol + class TestShelveBase(TestMappingProtocol): + fn = "shelftemp.db" + counter = 0 + def __init__(self, *args, **kw): + self._db = [] + TestMappingProtocol.__init__(self, *args, **kw) + _tested_class = shelve.Shelf + def _reference(self): + return {"key1":"value1", "key2":2, "key3":(1,2,3)} + def _empty_mapping(self): + if self._in_mem: + x= shelve.Shelf({}, binary = self._binary) + else: + self.counter+=1 + x= shelve.open(self.fn+str(self.counter), binary=self._binary) + self._db.append(x) + return x + def tearDown(self): + for db in self._db: + db.close() + self._db = [] + if not self._in_mem: + for f in glob.glob(self.fn+"*"): + os.unlink(f) + + class TestAsciiFileShelve(TestShelveBase): + _binary = False + _in_mem = False + class TestBinaryFileShelve(TestShelveBase): + _binary = True + _in_mem = False + class TestAsciiMemShelve(TestShelveBase): + _binary = False + _in_mem = True + class TestBinaryMemShelve(TestShelveBase): + _binary = True + _in_mem = True + + def test_main(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(TestAsciiFileShelve)) + suite.addTest(unittest.makeSuite(TestBinaryFileShelve)) + suite.addTest(unittest.makeSuite(TestAsciiMemShelve)) + suite.addTest(unittest.makeSuite(TestBinaryMemShelve)) + suite.addTest(unittest.makeSuite(TestCase)) + test_support.run_suite(suite) if __name__ == "__main__": Index: test_userdict.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_userdict.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** test_userdict.py 6 Mar 2003 23:54:27 -0000 1.13 --- test_userdict.py 9 Mar 2003 07:05:14 -0000 1.14 *************** *** 5,8 **** --- 5,125 ---- import UserDict + class TestMappingProtocol(unittest.TestCase): + # This base class can be used to check that an object conforms to the + # mapping protocol + + # Functions that can be useful to override to adapt to dictionary + # semantics + _tested_class = dict # which class is being tested + + def _reference(self): + """Return a dictionary of values which are invariant by storage + in the object under test.""" + return {1:2, "key1":"value1", "key2":(1,2,3)} + def _empty_mapping(self): + """Return an empty mapping object""" + return self._tested_class() + def _full_mapping(self, data): + """Return a mapping object with the value contained in data + dictionary""" + x = self._empty_mapping() + for key, value in data.items(): + x[key] = value + return x + + def __init__(self, *args, **kw): + unittest.TestCase.__init__(self, *args, **kw) + self.reference = self._reference().copy() + key, value = self.reference.popitem() + self.other = {key:value} + + def test_read(self): + # Test for read only operations on mapping + p = self._empty_mapping() + p1 = dict(p) #workaround for singleton objects + d = self._full_mapping(self.reference) + if d is p: + p = p1 + #Indexing + for key, value in self.reference.items(): + self.assertEqual(d[key], value) + knownkey = self.other.keys()[0] + self.failUnlessRaises(KeyError, lambda:d[knownkey]) + #len + self.assertEqual(len(p), 0) + self.assertEqual(len(d), len(self.reference)) + #has_key + for k in self.reference: + self.assert_(d.has_key(k)) + self.assert_(k in d) + for k in self.other: + self.failIf(d.has_key(k)) + self.failIf(k in d) + #cmp + self.assertEqual(cmp(p,p), 0) + self.assertEqual(cmp(d,d), 0) + self.assertEqual(cmp(p,d), -1) + self.assertEqual(cmp(d,p), 1) + #__non__zero__ + if p: self.fail("Empty mapping must compare to False") + if not d: self.fail("Full mapping must compare to True") + # keys(), items(), iterkeys() ... + def check_iterandlist(iter, lst, ref): + self.assert_(hasattr(iter, 'next')) + self.assert_(hasattr(iter, '__iter__')) + x = list(iter) + x.sort() + lst.sort() + ref.sort() + self.assert_(x==lst==ref) + check_iterandlist(d.iterkeys(), d.keys(), self.reference.keys()) + check_iterandlist(iter(d), d.keys(), self.reference.keys()) + check_iterandlist(d.itervalues(), d.values(), self.reference.values()) + check_iterandlist(d.iteritems(), d.items(), self.reference.items()) + #get + key, value = d.iteritems().next() + knownkey, knownvalue = self.other.iteritems().next() + self.assertEqual(d.get(key, knownvalue), value) + self.assertEqual(d.get(knownkey, knownvalue), knownvalue) + self.failIf(knownkey in d) + + def test_write(self): + # Test for write operations on mapping + p = self._empty_mapping() + #Indexing + for key, value in self.reference.items(): + p[key] = value + self.assertEqual(p[key], value) + for key in self.reference.keys(): + del p[key] + self.failUnlessRaises(KeyError, lambda:p[key]) + p = self._empty_mapping() + #update + p.update(self.reference) + self.assertEqual(dict(p), self.reference) + d = self._full_mapping(self.reference) + #setdefaullt + key, value = d.iteritems().next() + knownkey, knownvalue = self.other.iteritems().next() + self.assertEqual(d.setdefault(key, knownvalue), value) + self.assertEqual(d[key], value) + self.assertEqual(d.setdefault(knownkey, knownvalue), knownvalue) + self.assertEqual(d[knownkey], knownvalue) + #pop + self.assertEqual(d.pop(knownkey), knownvalue) + self.failIf(knownkey in d) + self.assertRaises(KeyError, d.pop, knownkey) + default = 909 + d[knownkey] = knownvalue + self.assertEqual(d.pop(knownkey, default), knownvalue) + self.failIf(knownkey in d) + self.assertEqual(d.pop(knownkey, default), default) + #popitem + key, value = d.popitem() + self.failIf(key in d) + self.assertEqual(value, self.reference[key]) + p=self._empty_mapping() + self.assertRaises(KeyError, p.popitem) + d0 = {} d1 = {"one": 1} *************** *** 12,16 **** d5 = {"one": 1, "two": 1} ! class UserDictTest(unittest.TestCase): def test_all(self): # Test constructors --- 129,135 ---- d5 = {"one": 1, "two": 1} ! class UserDictTest(TestMappingProtocol): ! _tested_class = UserDict.IterableUserDict ! def test_all(self): # Test constructors *************** *** 183,187 **** return list(self.keylist) ! class UserDictMixinTest(unittest.TestCase): def test_all(self): ## Setup test and verify working of the test class --- 302,308 ---- return list(self.keylist) ! class UserDictMixinTest(TestMappingProtocol): ! _tested_class = SeqDict ! def test_all(self): ## Setup test and verify working of the test class *************** *** 276,279 **** --- 397,401 ---- def test_main(): suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(TestMappingProtocol)) suite.addTest(unittest.makeSuite(UserDictTest)) suite.addTest(unittest.makeSuite(UserDictMixinTest)) Index: test_weakref.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_weakref.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** test_weakref.py 22 Aug 2002 20:21:30 -0000 1.21 --- test_weakref.py 9 Mar 2003 07:05:14 -0000 1.22 *************** *** 518,521 **** --- 518,536 ---- self.assert_(d.items() == [('something else', o2)]) + from test_userdict import TestMappingProtocol + + class WeakValueDictionaryTestCase(TestMappingProtocol): + """Check that WeakValueDictionary class conforms to the mapping protocol""" + __ref = {"key1":Object(1), "key2":Object(2), "key3":Object(3)} + _tested_class = weakref.WeakValueDictionary + def _reference(self): + return self.__ref.copy() + + class WeakKeyDictionaryTestCase(TestMappingProtocol): + """Check that WeakKeyDictionary class conforms to the mapping protocol""" + __ref = {Object("key1"):1, Object("key2"):2, Object("key3"):3} + _tested_class = weakref.WeakKeyDictionary + def _reference(self): + return self.__ref.copy() def test_main(): *************** *** 523,526 **** --- 538,543 ---- suite.addTest(unittest.makeSuite(ReferencesTestCase)) suite.addTest(unittest.makeSuite(MappingTestCase)) + suite.addTest(unittest.makeSuite(WeakValueDictionaryTestCase)) + suite.addTest(unittest.makeSuite(WeakKeyDictionaryTestCase)) test_support.run_suite(suite) From rhettinger@users.sourceforge.net Sun Mar 9 07:05:46 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 08 Mar 2003 23:05:46 -0800 Subject: [Python-checkins] python/dist/src/Misc ACKS,1.227,1.228 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv15204 Modified Files: ACKS Log Message: SF patch #667730: More DictMixin * Adds missing pop() methods to weakref.py * Expands test suite to broaden coverage of objects with a mapping interface. Contributed by Sebastien Keim. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.227 retrieving revision 1.228 diff -C2 -d -r1.227 -r1.228 *** ACKS 10 Feb 2003 01:09:49 -0000 1.227 --- ACKS 9 Mar 2003 07:05:43 -0000 1.228 *************** *** 282,285 **** --- 282,286 ---- Jacob Kaplan-Moss Lou Kates + Sebastien Keim Randall Kern Robert Kern From rhettinger@users.sourceforge.net Sun Mar 9 07:19:41 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 08 Mar 2003 23:19:41 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.128,1.129 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv18590 Modified Files: whatsnew23.tex Log Message: Add contributor name. Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.128 retrieving revision 1.129 diff -C2 -d -r1.128 -r1.129 *** whatsnew23.tex 7 Mar 2003 15:45:15 -0000 1.128 --- whatsnew23.tex 9 Mar 2003 07:19:38 -0000 1.129 *************** *** 1373,1376 **** --- 1373,1377 ---- the module; see the \ulink{package's reference documentation}{../lib/module-itertools.html} for details. + (Contributed by Raymond Hettinger.) \item Two new functions in the \module{math} module, From rhettinger@users.sourceforge.net Sun Mar 9 07:30:45 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 08 Mar 2003 23:30:45 -0800 Subject: [Python-checkins] python/dist/src/Objects unicodeobject.c,2.183,2.184 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv20399 Modified Files: unicodeobject.c Log Message: Sf patch #700047: unicode object leaks refcount on resizing Contributed by Hye-Shik Chang. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.183 retrieving revision 2.184 diff -C2 -d -r2.183 -r2.184 *** unicodeobject.c 6 Mar 2003 12:53:07 -0000 2.183 --- unicodeobject.c 9 Mar 2003 07:30:43 -0000 2.184 *************** *** 277,280 **** --- 277,281 ---- Py_UNICODE_COPY(w->str, v->str, length < v->length ? length : v->length); + Py_DECREF(*unicode); *unicode = (PyObject *)w; return 0; From rhettinger@users.sourceforge.net Sun Mar 9 07:44:44 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 08 Mar 2003 23:44:44 -0800 Subject: [Python-checkins] python/dist/src/Lib _strptime.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv22888 Modified Files: _strptime.py Log Message: SF patch #691928: Use datetime in _strptime Contributed by Brett Cannon. To prevent code duplication, I patched _strptime to use datetime's date object to do Julian day, Gregorian, and day of the week calculations. Patch also includes new regression tests to test results and the calculation gets triggered. Very minor comment changes and the contact email are also changed. Index: _strptime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/_strptime.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** _strptime.py 29 Jan 2003 03:49:43 -0000 1.12 --- _strptime.py 9 Mar 2003 07:44:41 -0000 1.13 *************** *** 7,22 **** FUNCTIONS: ! firstjulian -- Calculates the Julian date up to the first of the specified ! year ! gregorian -- Calculates the Gregorian date based on the Julian day and ! year ! julianday -- Calculates the Julian day since the first of the year based ! on the Gregorian date ! dayofweek -- Calculates the day of the week from the Gregorian date. strptime -- Calculates the time struct represented by the passed-in string ! Requires Python 2.2.1 or higher. Can be used in Python 2.2 if the following line is added: ! >>> True = 1; False = 0 """ import time --- 7,16 ---- FUNCTIONS: ! _getlang -- Figure out what language is being used for the locale strptime -- Calculates the time struct represented by the passed-in string ! Requires Python 2.2.1 or higher (mainly because of the use of property()). Can be used in Python 2.2 if the following line is added: ! True = 1; False = 0 """ import time *************** *** 25,36 **** from re import compile as re_compile from re import IGNORECASE __author__ = "Brett Cannon" ! __email__ = "drifty@bigfoot.com" __all__ = ['strptime'] - RegexpType = type(re_compile('')) - def _getlang(): # Figure out what the current language is set to. --- 19,29 ---- from re import compile as re_compile from re import IGNORECASE + from datetime import date as datetime_date __author__ = "Brett Cannon" ! __email__ = "brett@python.org" __all__ = ['strptime'] def _getlang(): # Figure out what the current language is set to. *************** *** 426,430 **** hour = minute = second = 0 tz = -1 ! # Defaulted to -1 so as to signal using functions to calc values weekday = julian = -1 found_dict = found.groupdict() --- 419,423 ---- hour = minute = second = 0 tz = -1 ! # weekday and julian defaulted to -1 so as to signal need to calculate values weekday = julian = -1 found_dict = found.groupdict() *************** *** 496,509 **** elif locale_time.timezone[2].lower() == found_zone: tz = -1 ! #XXX : If calculating fxns are never exposed to the general ! #populous then just inline calculations. Also might be able to use ! #``datetime`` and the methods it provides. if julian == -1: ! julian = julianday(year, month, day) ! else: # Assuming that if they bothered to include Julian day it will #be accurate ! year, month, day = gregorian(julian, year) if weekday == -1: ! weekday = dayofweek(year, month, day) return time.struct_time((year, month, day, hour, minute, second, --- 489,507 ---- elif locale_time.timezone[2].lower() == found_zone: tz = -1 ! # Cannot pre-calculate datetime_date() since can change in Julian ! #calculation and thus could have different value for the day of the week ! #calculation if julian == -1: ! # Need to add 1 to result since first day of the year is 1, not 0. ! julian = datetime_date(year, month, day).toordinal() - \ ! datetime_date(year, 1, 1).toordinal() + 1 ! else: # Assume that if they bothered to include Julian day it will #be accurate ! datetime_result = datetime_date.fromordinal((julian - 1) + datetime_date(year, 1, 1).toordinal()) ! year = datetime_result.year ! month = datetime_result.month ! day = datetime_result.day if weekday == -1: ! weekday = datetime_date(year, month, day).weekday() return time.struct_time((year, month, day, hour, minute, second, *************** *** 523,560 **** raise ValueError("value not in list") - def firstjulian(year): - """Calculate the Julian date up until the first of the year.""" - return ((146097 * (year + 4799)) // 400) - 31738 - - def julianday(year, month, day): - """Calculate the Julian day since the beginning of the year. - Calculated from the Gregorian date. - """ - a = (14 - month) // 12 - return (day - 32045 - + (((153 * (month + (12 * a) - 3)) + 2) // 5) - + ((146097 * (year + 4800 - a)) // 400)) - firstjulian(year) + 1 - - def gregorian(julian, year): - """Return 3-item list containing Gregorian date based on the Julian day.""" - a = 32043 + julian + firstjulian(year) - b = ((4 * a) + 3) // 146097 - c = a - ((146097 * b) // 4) - d = ((4 * c) + 3) // 1461 - e = c - ((1461 * d) // 4) - m = ((5 * e) + 2) // 153 - day = 1 + e - (((153 * m) + 2) // 5) - month = m + 3 - (12 * (m // 10)) - year = (100 * b) + d - 4800 + (m // 10) - return [year, month, day] - - def dayofweek(year, month, day): - """Calculate the day of the week (Monday is 0).""" - a = (14 - month) // 12 - y = year - a - weekday = (day + y + ((97 * y) // 400) - + ((31 * (month + (12 * a) -2 )) // 12)) % 7 - if weekday == 0: - return 6 - else: - return weekday-1 --- 521,522 ---- From rhettinger@users.sourceforge.net Sun Mar 9 07:44:45 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 08 Mar 2003 23:44:45 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_strptime.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv22888/test Modified Files: test_strptime.py Log Message: SF patch #691928: Use datetime in _strptime Contributed by Brett Cannon. To prevent code duplication, I patched _strptime to use datetime's date object to do Julian day, Gregorian, and day of the week calculations. Patch also includes new regression tests to test results and the calculation gets triggered. Very minor comment changes and the contact email are also changed. Index: test_strptime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_strptime.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_strptime.py 18 Jan 2003 03:53:49 -0000 1.9 --- test_strptime.py 9 Mar 2003 07:44:42 -0000 1.10 *************** *** 330,364 **** " %s != %s" % (strp_output, defaults)) - class FxnTests(unittest.TestCase): - """Test functions that fill in info by validating result and are triggered - properly.""" - - def setUp(self): - """Create an initial time tuple.""" - self.time_tuple = time.gmtime() - - def test_julianday_result(self): - # Test julianday - result = _strptime.julianday(self.time_tuple[0], self.time_tuple[1], - self.time_tuple[2]) - self.failUnless(result == self.time_tuple[7], - "julianday failed; %s != %s" % - (result, self.time_tuple[7])) - - def test_gregorian_result(self): - # Test gregorian - result = _strptime.gregorian(self.time_tuple[7], self.time_tuple[0]) - comparison = [self.time_tuple[0], self.time_tuple[1], self.time_tuple[2]] - self.failUnless(result == comparison, - "gregorian() failed; %s != %s" % (result, comparison)) - - def test_dayofweek_result(self): - # Test dayofweek - result = _strptime.dayofweek(self.time_tuple[0], self.time_tuple[1], - self.time_tuple[2]) - comparison = self.time_tuple[6] - self.failUnless(result == comparison, - "dayofweek() failed; %s != %s" % (result, comparison)) - class Strptime12AMPMTests(unittest.TestCase): """Test a _strptime regression in '%I %p' at 12 noon (12 PM)""" --- 330,333 ---- *************** *** 381,384 **** --- 350,390 ---- eq(_strptime.strptime('%d 2004' % i, '%j %Y')[7], i) + class CalculationTests(unittest.TestCase): + """Test that strptime() fills in missing info correctly""" + + def setUp(self): + self.time_tuple = time.gmtime() + + def test_julian_calculation(self): + # Make sure that when Julian is missing that it is calculated + format_string = "%Y %m %d %H %M %S %w %Z" + result = _strptime.strptime(time.strftime(format_string, self.time_tuple), + format_string) + self.failUnless(result.tm_yday == self.time_tuple.tm_yday, + "Calculation of tm_yday failed; %s != %s" % + (result.tm_yday, self.time_tuple.tm_yday)) + + def test_gregorian_calculation(self): + # Test that Gregorian date can be calculated from Julian day + format_string = "%Y %H %M %S %w %j %Z" + result = _strptime.strptime(time.strftime(format_string, self.time_tuple), + format_string) + self.failUnless(result.tm_year == self.time_tuple.tm_year and + result.tm_mon == self.time_tuple.tm_mon and + result.tm_mday == self.time_tuple.tm_mday, + "Calculation of Gregorian date failed;" + "%s-%s-%s != %s-%s-%s" % + (result.tm_year, result.tm_mon, result.tm_mday, + self.time_tuple.tm_year, self.time_tuple.tm_mon, + self.time_tuple.tm_mday)) + + def test_day_of_week_calculation(self): + # Test that the day of the week is calculated as needed + format_string = "%Y %m %d %H %S %j %Z" + result = _strptime.strptime(time.strftime(format_string, self.time_tuple), + format_string) + self.failUnless(result.tm_wday == self.time_tuple.tm_wday, + "Calculation of day of the week failed;" + "%s != %s" % (result.tm_wday, self.time_tuple.tm_wday)) def test_main(): *************** *** 387,393 **** suite.addTest(unittest.makeSuite(TimeRETests)) suite.addTest(unittest.makeSuite(StrptimeTests)) - suite.addTest(unittest.makeSuite(FxnTests)) suite.addTest(unittest.makeSuite(Strptime12AMPMTests)) suite.addTest(unittest.makeSuite(JulianTests)) test_support.run_suite(suite) --- 393,399 ---- suite.addTest(unittest.makeSuite(TimeRETests)) suite.addTest(unittest.makeSuite(StrptimeTests)) suite.addTest(unittest.makeSuite(Strptime12AMPMTests)) suite.addTest(unittest.makeSuite(JulianTests)) + suite.addTest(unittest.makeSuite(CalculationTests)) test_support.run_suite(suite) From gward@users.sourceforge.net Sun Mar 9 23:34:54 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Sun, 09 Mar 2003 15:34:54 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libossaudiodev.tex,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv12154 Added Files: libossaudiodev.tex Log Message: Documentation for the ossaudiodev module. Initial revision supplied by Nicholas FitzRoy-Dale (emailed to me [gward@python.net] 2003-03-08 23:37 +1100). --- NEW FILE: libossaudiodev.tex --- \section{\module{ossaudiodev} --- Access to Open Sound System-compatible audio hardware} \declaremodule{builtin}{ossaudiodev} \platform{OSS} \modulesynopsis{Access to OSS-compatible audio hardware.} % I know FreeBSD uses OSS - what about Net- and Open-? This module allows you to access the Open Sound System audio interface. The Open Sound System interface is present on Linux and FreeBSD. This module provides a very "bare bones" wrapper over the IOCTLs used to access the audio hardware. The best - albeit rather daunting - way to get a feel for the interface is from the Open Sound System official documentation: \url{http://www.opensound.com/pguide/oss.pdf} The module defines a number of constants which may be used to program the device. These constants are the same as those defined in the C include file \code{}. \code{ossaudiodev} defines the following variables and functions: \begin{excdesc}{error} This exception is raised on errors. The argument is a string describing what went wrong. \end{excdesc} \begin{funcdesc}{open}{\optional{device, }mode} This function opens the audio device and returns an OSS audio device object. This object can then be used to do I/O on. The \var{device} parameter is the audio device filename to use. If it is not specified, this module first looks in the environment variable \code{AUDIODEV} for a device to use. If not found, it falls back to \file{/dev/dsp}. The \var{mode} parameter is one of \code{'r'} for record-only access, \code{'w'} for play-only access and \code{'rw'} for both. Since many soundcards only allow one process to have the recorder or player open at a time it is a good idea to open the device only for the activity needed. Further, some soundcards are half-duplex: they can be opened for reading or writing, but not both at once. \end{funcdesc} \begin{funcdesc}{openmixer}{\optional{device\optional{, mode}}} This function opens the mixer device and returns an OSS mixer device object. The \var{device} parameter is the mixer device filename to use. If it is not specified, this module first looks in the environment variable \code{MIXERDEV} for a device to use. If not found, it falls back to \file{/dev/mixer}. You may specify \code{'r'}, \code{'rw'} or \code{'w'} for \var{mode}; the default is \code{'r'}. \end{funcdesc} \subsection{Audio Device Objects \label{ossaudio-device-objects}} Setting up the device To set up the device, three functions must be called in the correct sequence: \code{setfmt} to set the output format, \code{channels} to set the number of channels, and \code{speed} to set the sample rate. The audio device objects are returned by \function{open()} define the following methods: \begin{methoddesc}[audio device]{close}{} This method explicitly closes the device. It is useful in situations where deleting the object does not immediately close it since there are other references to it. A closed device should not be used again. \end{methoddesc} \begin{methoddesc}[audio device]{fileno}{} Returns the file descriptor associated with the device. \end{methoddesc} \begin{methoddesc}[audio device]{read}{size} Reads \var{size} samples from the audio input and returns them as a Python string. The function blocks until enough data is available. \end{methoddesc} \begin{methoddesc}[audio device]{write}{data} Writes Python string \var{data} to the audio device and returns the number of bytes written. If the audio device is opened in blocking mode, the entire string is always written. If the device is opened in nonblocking mode, some data may not be written - see \code{writeall}. \end{methoddesc} \begin{methoddesc}[audio device]{writeall}{data} Writes the entire Python string \var{data} to the audio device. If the device is opened in blocking mode, behaves identially to \code{write}; in nonblocking mode, waits until the device becomes available before feeding it more data. Returns None, since the amount of data written is always equal to the amount of data supplied. \end{methoddesc} Simple IOCTLs: \begin{methoddesc}[audio device]{nonblock}{} Attempts to put the device into nonblocking mode. Once in nonblocking mode there is no way to return to blocking mode. Raises \exception{IOError} if the IOCTL failed. \end{methoddesc} \begin{methoddesc}[audio device]{getfmts}{} Returns a bitmask of the audio output formats supported by the soundcard. On a typical Linux system, these formats are: AFMT_MU_LAW - a logarithmic encoding. This is the default format on /dev/audio and is the format used by Sun .au files. AFMT_A_LAW - a logarithmic encoding AFMT_IMA_ADPCM - a 4:1 compressed format defined by the Interactive Multimedia Association. AFMT_U8 - Unsigned, 8-bit audio. AFMT_S16_LE - Unsigned, 16-bit audio, little-endian byte order (as used by Intel processors) AFMT_S16_BE - Unsigned, 16-bit audio, big-endian byte order (as used by 68k, PowerPC, Sparc) AFMT_S8 - Signed, 8 bit audio. AFMT_U16_LE - Signed, 16-bit little-endian audio AFMT_U16_BE - Signed, 16-bit big-endian audio Most systems support only a subset of these formats. Many devices only support AFTM_U8; the most common format used today is AFMT_S16_LE. \end{methoddesc} \begin{methoddesc}[audio device]{setfmt}{format} Used to set the current audio format to \var{format} - see \code{getfmts} for a list. May also be used to return the current audio format - do this by passing an ``audio format'' of \code{AFMT_QUERY}. Returns the audio format that the device was set to, which may not be the requested format. \end{methoddesc} \begin{methoddesc}[audio device]{channels}{num_channels} Sets the number of output channels to \var{num_channels}. A value of 1 indicates monophonic sound, 2 stereophonic. Some devices may have more than 2 channels, and some high-end devices may not support mono. Returns the number of channels the device was set to. \end{methoddesc} \begin{methoddesc}[audio device]{speed}{samplerate} Sets the samplerate to \var{samplerate} samples per second and returns the rate actually set. Most sound devices don't support arbitrary sample rates. Common rates are: 8000 - default rate 11025 - speech recording 22050 44100 - Audio CD-quality (at 16 bits/sample and 2 channels) 96000 - DVD-quality \end{methoddesc} \begin{methoddesc}[audio device]{sync} Waits until the sound device has played every byte in its buffer and returns. This also occurs when the sound device is closed. The OSS documentation recommends simply closing and re-opening the device rather than using \code{sync}. \end{methoddesc} \begin{methoddesc}[audio device]{reset} Immediately stops and playing or recording and returns the device to a state where it can accept commands. The OSS documentation recommends closing and re-opening the device after calling \code{reset}. \end{methoddesc} \begin{methoddesc}[audio device]{post} To be used like a lightweight \code{sync}, the \code{post} IOCTL informs the audio device that there is a likely to be a pause in the audio output - ie, after playing a spot sound effect, before waiting for user input, or before doing disk IO. \end{methoddesc} Convenience methods \begin{methoddesc}[audio device]{setparameters}{samplerate,num_channels,format,emulate} Initialise the sound device in one method. \var{samplerate}, \var{channels} and \var{format} should be as specified in the \code{speed}, \code{channels} and \code{setfmt} methods. If \var{emulate} is true, attempt to find the closest matching format instead, otherwise raise ValueError if the device does not support the format. The default is to raise ValueError on unsupported formats. \end{methoddesc} \begin{methoddesc}[audio device]{bufsize}{} Returns the size of the hardware buffer, in samples. \end{methoddesc} \begin{methoddesc}[audio device]{obufcount}{} Returns the number of samples that are in the hardware buffer yet to be played. \end{methoddesc} \begin{methoddesc}[audio device]{obuffree}{} Returns the number of samples that could be queued into the hardware buffer to be played without blocking. \end{methoddesc} \subsection{Mixer Device Objects \label{mixer-device-objects}} File-like interface \begin{methoddesc}[mixer device]{close}{} This method closes the open mixer device file. Any further attempts to use the mixer after this file is closed will raise an IOError. \end{methoddesc} \begin{methoddesc}[mixer device]{fileno}{} Returns the file handle number of the open mixer device file. \end{methoddesc} Mixer interface \begin{methoddesc}[mixer device]{controls}{} This method returns a bitmask specifying the available mixer controls (``Control'' being a specific mixable ``channel'', such as \code{SOUND_MIXER_PCM} or \code{SOUND_MIXER_SYNTH}). This bitmask indicates a subset of all available mixer channels - the \code{SOUND_MIXER_*} constants defined at module level. To determine if, for example, the current mixer object supports a PCM mixer, use the following Python code: \begin{verbatim} mixer=ossaudiodev.openmixer() if mixer.channels() & (1 << ossaudiodev.SOUND_MIXER_PCM): # PCM is supported \end{verbatim} For most purposes, the \code{SOUND_MIXER_VOLUME} (Master volume) and \code{SOUND_MIXER_PCM} channels should suffice - but code that uses the mixer should be flexible when it comes to choosing sound channels. On the Gravis Ultrasound, for example, \code{SOUND_MIXER_VOLUME} does not exist. \end{methoddesc} \begin{methoddesc}[mixer device]{stereocontrols}{} Returns a bitmask indicating stereo mixer channels. If a bit is set, the corresponding channel is stereo; if it is unset, the channel is either monophonic or not supported by the mixer (use in combination with \function{channels} to determine which). See the code example for the \function{channels} function for an example of getting data from a bitmask. \end{methoddesc} \begin{methoddesc}[mixer device]{reccontrols}{} Returns a bitmask specifying the mixer controls that may be used to record. See the code example for \function{controls} for an example of reading from a bitmask. \end{methoddesc} \begin{methoddesc}[mixer device]{get}{channel} Returns the volume of a given mixer channel. The returned volume is a 2-tuple of \code{left volume, right volume}. Volumes are specified as numbers from 0 (silent) to 100 (full volume). If the channel is monophonic, a 2-tuple is still returned, but both channel volumes are the same. If an unknown channel is specified, \exception{error} is raised. \end{methoddesc} \begin{methoddesc}[mixer device]{set}{channel, (left, right)} Sets the volume for a given mixer channel to \code{(left, right)}. \code{left} and \code{right} must be ints and between 0 (silent) and 100 (full volume). On success, the new volume is returned as a 2-tuple. Note that this may not be exactly the same as the volume specified, because of the limited resolution of some soundcard's mixers. Raises \exception{IOError} if an invalid mixer channel was specified; \exception{TypeError} if the argument format was incorrect, and \exception{error} if the specified volumes were out-of-range. \end{methoddesc} \begin{methoddesc}[mixer device]{get_recsrc}{} This method returns a bitmask indicating which channel or channels are currently being used as a recording source. \end{methoddesc} \begin{methoddesc}[mixer device]{set_recsrc}{bitmask} Call this function to specify a recording source. Returns a bitmask indicating the new recording source (or sources) if successful; raises \exception{IOError} if an invalid source was specified. To set the current recording source to the microphone input: \begin{verbatim} mixer.setrecsrc (1 << ossaudiodev.SOUND_MIXER_MIC) \end{verbatim} \end{methoddesc} From gward@users.sourceforge.net Sun Mar 9 23:57:36 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Sun, 09 Mar 2003 15:57:36 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libossaudiodev.tex,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv20251 Modified Files: libossaudiodev.tex Log Message: Wrap all paragraphs to 72 columns. Two spaces between sentences. Fix em-dashes -- should be "---" not " - ". Spelling fix. Index: libossaudiodev.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libossaudiodev.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** libossaudiodev.tex 9 Mar 2003 23:34:52 -0000 1.1 --- libossaudiodev.tex 9 Mar 2003 23:57:34 -0000 1.2 *************** *** 6,15 **** \modulesynopsis{Access to OSS-compatible audio hardware.} ! % I know FreeBSD uses OSS - what about Net- and Open-? This module allows you to access the Open Sound System audio interface. The Open Sound System interface is present on Linux and FreeBSD. This module provides a very "bare bones" wrapper over the IOCTLs used to ! access the audio hardware. The best - albeit rather daunting - way to get a feel for the interface is from the Open Sound System official documentation: --- 6,15 ---- \modulesynopsis{Access to OSS-compatible audio hardware.} ! % I know FreeBSD uses OSS -- what about Net- and Open-? This module allows you to access the Open Sound System audio interface. The Open Sound System interface is present on Linux and FreeBSD. This module provides a very "bare bones" wrapper over the IOCTLs used to ! access the audio hardware. The best---albeit rather daunting---way to get a feel for the interface is from the Open Sound System official documentation: *************** *** 17,52 **** \url{http://www.opensound.com/pguide/oss.pdf} ! The module defines a number of constants which may be used to program the ! device. These constants are the same as those defined in the C include file ! \code{}. \code{ossaudiodev} defines the following variables and functions: \begin{excdesc}{error} ! This exception is raised on errors. The argument is a string ! describing what went wrong. \end{excdesc} \begin{funcdesc}{open}{\optional{device, }mode} This function opens the audio device and returns an OSS audio device ! object. This object can then be used to do I/O on. The \var{device} ! parameter is the audio device filename to use. If it is not specified, this ! module first looks in the environment variable \code{AUDIODEV} for a device ! to use. If not found, it falls back to \file{/dev/dsp}. The \var{mode} parameter is one of \code{'r'} for record-only access, ! \code{'w'} for play-only access and \code{'rw'} for both. Since many soundcards only allow one process to have the recorder or player open at a time it is a good idea to open the device only for the activity ! needed. Further, some soundcards are half-duplex: they can be opened for reading ! or writing, but not both at once. \end{funcdesc} \begin{funcdesc}{openmixer}{\optional{device\optional{, mode}}} This function ! opens the mixer device and returns an OSS mixer device object. The \var{device} ! parameter is the mixer device filename to use. If it is not specified, this ! module first looks in the environment variable \code{MIXERDEV} for a device to ! use. If not found, it falls back to \file{/dev/mixer}. You may specify ! \code{'r'}, \code{'rw'} or \code{'w'} for \var{mode}; the default is \code{'r'}. \end{funcdesc} --- 17,53 ---- \url{http://www.opensound.com/pguide/oss.pdf} ! The module defines a number of constants which may be used to program ! the device. These constants are the same as those defined in the C ! include file \code{}. \code{ossaudiodev} defines the following variables and functions: \begin{excdesc}{error} ! This exception is raised on errors. The argument is a string describing ! what went wrong. \end{excdesc} \begin{funcdesc}{open}{\optional{device, }mode} This function opens the audio device and returns an OSS audio device ! object. This object can then be used to do I/O on. The \var{device} ! parameter is the audio device filename to use. If it is not specified, ! this module first looks in the environment variable \code{AUDIODEV} for ! a device to use. If not found, it falls back to \file{/dev/dsp}. The \var{mode} parameter is one of \code{'r'} for record-only access, ! \code{'w'} for play-only access and \code{'rw'} for both. Since many soundcards only allow one process to have the recorder or player open at a time it is a good idea to open the device only for the activity ! needed. Further, some soundcards are half-duplex: they can be opened ! for reading or writing, but not both at once. \end{funcdesc} \begin{funcdesc}{openmixer}{\optional{device\optional{, mode}}} This function ! opens the mixer device and returns an OSS mixer device object. The ! \var{device} parameter is the mixer device filename to use. If it is ! not specified, this module first looks in the environment variable ! \code{MIXERDEV} for a device to use. If not found, it falls back to ! \file{/dev/mixer}. You may specify \code{'r'}, \code{'rw'} or ! \code{'w'} for \var{mode}; the default is \code{'r'}. \end{funcdesc} *************** *** 56,60 **** Setting up the device ! To set up the device, three functions must be called in the correct sequence: \code{setfmt} to set the output format, --- 57,62 ---- Setting up the device ! To set up the device, three functions must be called in the correct ! sequence: \code{setfmt} to set the output format, *************** *** 66,96 **** \begin{methoddesc}[audio device]{close}{} ! This method explicitly closes the device. It is useful in situations ! where deleting the object does not immediately close it since there ! are other references to it. A closed device should not be used again. \end{methoddesc} \begin{methoddesc}[audio device]{fileno}{} ! Returns the file descriptor associated with the device. \end{methoddesc} \begin{methoddesc}[audio device]{read}{size} ! Reads \var{size} samples from the audio input and returns ! them as a Python string. The function blocks until enough data is available. \end{methoddesc} \begin{methoddesc}[audio device]{write}{data} ! Writes Python string \var{data} to the audio device and returns the number of ! bytes written. If the audio device is opened in blocking mode, the entire ! string is always written. If the device is opened in nonblocking mode, some data ! may not be written - see \code{writeall}. \end{methoddesc} \begin{methoddesc}[audio device]{writeall}{data} ! Writes the entire Python string \var{data} to the audio device. If the device ! is opened in blocking mode, behaves identially to \code{write}; in nonblocking ! mode, waits until the device becomes available before feeding it more data. ! Returns None, since the amount of data written is always equal to the amount ! of data supplied. \end{methoddesc} --- 68,98 ---- \begin{methoddesc}[audio device]{close}{} ! This method explicitly closes the device. It is useful in situations ! where deleting the object does not immediately close it since there are ! other references to it. A closed device should not be used again. \end{methoddesc} \begin{methoddesc}[audio device]{fileno}{} ! Returns the file descriptor associated with the device. \end{methoddesc} \begin{methoddesc}[audio device]{read}{size} ! Reads \var{size} samples from the audio input and returns them as a ! Python string. The function blocks until enough data is available. \end{methoddesc} \begin{methoddesc}[audio device]{write}{data} ! Writes Python string \var{data} to the audio device and returns the ! number of bytes written. If the audio device is opened in blocking ! mode, the entire string is always written. If the device is opened in ! nonblocking mode, some data may not be written---see \code{writeall}. \end{methoddesc} \begin{methoddesc}[audio device]{writeall}{data} ! Writes the entire Python string \var{data} to the audio device. If the ! device is opened in blocking mode, behaves identially to \code{write}; ! in nonblocking mode, waits until the device becomes available before ! feeding it more data. Returns None, since the amount of data written is ! always equal to the amount of data supplied. \end{methoddesc} *************** *** 98,103 **** \begin{methoddesc}[audio device]{nonblock}{} ! Attempts to put the device into nonblocking mode. Once in nonblocking mode there ! is no way to return to blocking mode. Raises \exception{IOError} if the IOCTL failed. --- 100,105 ---- \begin{methoddesc}[audio device]{nonblock}{} ! Attempts to put the device into nonblocking mode. Once in nonblocking ! mode there is no way to return to blocking mode. Raises \exception{IOError} if the IOCTL failed. *************** *** 105,173 **** \begin{methoddesc}[audio device]{getfmts}{} ! Returns a bitmask of the audio output formats supported by the soundcard. ! On a typical Linux system, these formats are: ! AFMT_MU_LAW - a logarithmic encoding. This is the default format on /dev/audio ! and is the format used by Sun .au files. ! AFMT_A_LAW - a logarithmic encoding ! AFMT_IMA_ADPCM - a 4:1 compressed format defined by the Interactive Multimedia ! Association. ! AFMT_U8 - Unsigned, 8-bit audio. ! AFMT_S16_LE - Unsigned, 16-bit audio, little-endian byte order (as used by Intel ! processors) ! AFMT_S16_BE - Unsigned, 16-bit audio, big-endian byte order (as used by 68k, ! PowerPC, Sparc) ! AFMT_S8 - Signed, 8 bit audio. ! AFMT_U16_LE - Signed, 16-bit little-endian audio ! AFMT_U16_BE - Signed, 16-bit big-endian audio ! Most systems support only a subset of these formats. Many devices only support ! AFTM_U8; the most common format used today is AFMT_S16_LE. \end{methoddesc} \begin{methoddesc}[audio device]{setfmt}{format} ! Used to set the current audio format to \var{format} - see \code{getfmts} for a ! list. May also be used to return the current audio format - do this by passing ! an ``audio format'' of \code{AFMT_QUERY}. Returns the audio format that the ! device was set to, which may not be the requested format. \end{methoddesc} \begin{methoddesc}[audio device]{channels}{num_channels} ! Sets the number of output channels to \var{num_channels}. A value of 1 indicates ! monophonic sound, 2 stereophonic. Some devices may have more than 2 channels, ! and some high-end devices may not support mono. Returns the number of channels ! the device was set to. \end{methoddesc} \begin{methoddesc}[audio device]{speed}{samplerate} ! Sets the samplerate to \var{samplerate} samples per second and returns the rate ! actually set. Most sound devices don't support arbitrary sample rates. Common ! rates are: ! 8000 - default rate ! 11025 - speech recording 22050 ! 44100 - Audio CD-quality (at 16 bits/sample and 2 channels) ! 96000 - DVD-quality \end{methoddesc} \begin{methoddesc}[audio device]{sync} ! Waits until the sound device has played every byte in its buffer and returns. ! This also occurs when the sound device is closed. The OSS documentation ! recommends simply closing and re-opening the device rather than using ! \code{sync}. \end{methoddesc} \begin{methoddesc}[audio device]{reset} ! Immediately stops and playing or recording and returns the device to a state ! where it can accept commands. The OSS documentation recommends closing and ! re-opening the device after calling \code{reset}. \end{methoddesc} \begin{methoddesc}[audio device]{post} ! To be used like a lightweight \code{sync}, the \code{post} IOCTL informs the ! audio device that there is a likely to be a pause in the audio output - ie, ! after playing a spot sound effect, before waiting for user input, or before ! doing disk IO. \end{methoddesc} --- 107,176 ---- \begin{methoddesc}[audio device]{getfmts}{} ! Returns a bitmask of the audio output formats supported by the ! soundcard. On a typical Linux system, these formats are: ! AFMT_MU_LAW---a logarithmic encoding. This is the default format on ! /dev/audio and is the format used by Sun .au files. ! AFMT_A_LAW---a logarithmic encoding ! AFMT_IMA_ADPCM---a 4:1 compressed format defined by the Interactive ! Multimedia Association. ! AFMT_U8---Unsigned, 8-bit audio. ! AFMT_S16_LE---Unsigned, 16-bit audio, little-endian byte order (as used ! by Intel processors) ! AFMT_S16_BE---Unsigned, 16-bit audio, big-endian byte order (as used by ! 68k, PowerPC, Sparc) ! AFMT_S8---Signed, 8 bit audio. ! AFMT_U16_LE---Signed, 16-bit little-endian audio ! AFMT_U16_BE---Signed, 16-bit big-endian audio ! Most systems support only a subset of these formats. Many devices only ! support AFTM_U8; the most common format used today is AFMT_S16_LE. \end{methoddesc} \begin{methoddesc}[audio device]{setfmt}{format} ! Used to set the current audio format to \var{format}---see ! \code{getfmts} for a list. May also be used to return the current audio ! format---do this by passing an ``audio format'' of \code{AFMT_QUERY}. ! Returns the audio format that the device was set to, which may not be ! the requested format. \end{methoddesc} \begin{methoddesc}[audio device]{channels}{num_channels} ! Sets the number of output channels to \var{num_channels}. A value of 1 ! indicates monophonic sound, 2 stereophonic. Some devices may have more ! than 2 channels, and some high-end devices may not support mono. ! Returns the number of channels the device was set to. \end{methoddesc} \begin{methoddesc}[audio device]{speed}{samplerate} ! Sets the samplerate to \var{samplerate} samples per second and returns ! the rate actually set. Most sound devices don't support arbitrary ! sample rates. Common rates are: ! 8000---default rate ! 11025---speech recording 22050 ! 44100---Audio CD-quality (at 16 bits/sample and 2 channels) ! 96000---DVD-quality \end{methoddesc} \begin{methoddesc}[audio device]{sync} ! Waits until the sound device has played every byte in its buffer and ! returns. This also occurs when the sound device is closed. The OSS ! documentation recommends simply closing and re-opening the device rather ! than using \code{sync}. \end{methoddesc} \begin{methoddesc}[audio device]{reset} ! Immediately stops and playing or recording and returns the device to a ! state where it can accept commands. The OSS documentation recommends ! closing and re-opening the device after calling \code{reset}. \end{methoddesc} \begin{methoddesc}[audio device]{post} ! To be used like a lightweight \code{sync}, the \code{post} IOCTL informs ! the audio device that there is a likely to be a pause in the audio ! output---i.e., after playing a spot sound effect, before waiting for ! user input, or before doing disk IO. \end{methoddesc} *************** *** 175,184 **** \begin{methoddesc}[audio device]{setparameters}{samplerate,num_channels,format,emulate} ! Initialise the sound device in one method. \var{samplerate}, \var{channels} and ! \var{format} should be as specified in the \code{speed}, \code{channels} and ! \code{setfmt} methods. If \var{emulate} is true, attempt to find the closest ! matching format instead, otherwise raise ValueError if the ! device does not support the format. The default is to raise ValueError on ! unsupported formats. \end{methoddesc} --- 178,187 ---- \begin{methoddesc}[audio device]{setparameters}{samplerate,num_channels,format,emulate} ! Initialise the sound device in one method. \var{samplerate}, ! \var{channels} and \var{format} should be as specified in the ! \code{speed}, \code{channels} and \code{setfmt} methods. If ! \var{emulate} is true, attempt to find the closest matching format ! instead, otherwise raise ValueError if the device does not support the ! format. The default is to raise ValueError on unsupported formats. \end{methoddesc} *************** *** 188,197 **** \begin{methoddesc}[audio device]{obufcount}{} ! Returns the number of samples that are in the hardware buffer yet to be played. \end{methoddesc} \begin{methoddesc}[audio device]{obuffree}{} ! Returns the number of samples that could be queued into the hardware buffer to ! be played without blocking. \end{methoddesc} --- 191,201 ---- \begin{methoddesc}[audio device]{obufcount}{} ! Returns the number of samples that are in the hardware buffer yet to be ! played. \end{methoddesc} \begin{methoddesc}[audio device]{obuffree}{} ! Returns the number of samples that could be queued into the hardware ! buffer to be played without blocking. \end{methoddesc} *************** *** 201,206 **** \begin{methoddesc}[mixer device]{close}{} ! This method closes the open mixer device file. Any further attempts to use the ! mixer after this file is closed will raise an IOError. \end{methoddesc} --- 205,210 ---- \begin{methoddesc}[mixer device]{close}{} ! This method closes the open mixer device file. Any further attempts to ! use the mixer after this file is closed will raise an IOError. \end{methoddesc} *************** *** 214,220 **** This method returns a bitmask specifying the available mixer controls (``Control'' being a specific mixable ``channel'', such as ! \code{SOUND_MIXER_PCM} or \code{SOUND_MIXER_SYNTH}). This ! bitmask indicates a subset of all available mixer channels - the ! \code{SOUND_MIXER_*} constants defined at module level. To determine if, for example, the current mixer object supports a PCM mixer, use the following Python code: --- 218,224 ---- This method returns a bitmask specifying the available mixer controls (``Control'' being a specific mixable ``channel'', such as ! \code{SOUND_MIXER_PCM} or \code{SOUND_MIXER_SYNTH}). This ! bitmask indicates a subset of all available mixer channels---the ! \code{SOUND_MIXER_*} constants defined at module level. To determine if, for example, the current mixer object supports a PCM mixer, use the following Python code: *************** *** 228,257 **** For most purposes, the \code{SOUND_MIXER_VOLUME} (Master volume) and ! \code{SOUND_MIXER_PCM} channels should suffice - but code that uses the mixer ! should be flexible when it comes to choosing sound channels. On the Gravis ! Ultrasound, for example, \code{SOUND_MIXER_VOLUME} does not exist. \end{methoddesc} \begin{methoddesc}[mixer device]{stereocontrols}{} ! Returns a bitmask indicating stereo mixer channels. If a bit is set, the ! corresponding channel is stereo; if it is unset, the channel is either ! monophonic or not supported by the mixer (use in combination with \function{channels} to determine which). ! See the code example for the \function{channels} function for an example of ! getting data from a bitmask. \end{methoddesc} \begin{methoddesc}[mixer device]{reccontrols}{} ! Returns a bitmask specifying the mixer controls that may be used to record. ! See the code example for \function{controls} for an example of reading from ! a bitmask. \end{methoddesc} \begin{methoddesc}[mixer device]{get}{channel} ! Returns the volume of a given mixer channel. The returned volume is a ! 2-tuple of \code{left volume, right volume}. Volumes are specified as ! numbers from 0 (silent) to 100 (full volume). If the channel is monophonic, ! a 2-tuple is still returned, but both channel volumes are the same. If an unknown channel is specified, \exception{error} is raised. --- 232,263 ---- For most purposes, the \code{SOUND_MIXER_VOLUME} (Master volume) and ! \code{SOUND_MIXER_PCM} channels should suffice---but code that uses the ! mixer should be flexible when it comes to choosing sound channels. On ! the Gravis Ultrasound, for example, \code{SOUND_MIXER_VOLUME} does not ! exist. \end{methoddesc} \begin{methoddesc}[mixer device]{stereocontrols}{} ! Returns a bitmask indicating stereo mixer channels. If a bit is set, ! the corresponding channel is stereo; if it is unset, the channel is ! either monophonic or not supported by the mixer (use in combination with \function{channels} to determine which). ! See the code example for the \function{channels} function for an example ! of getting data from a bitmask. \end{methoddesc} \begin{methoddesc}[mixer device]{reccontrols}{} ! Returns a bitmask specifying the mixer controls that may be used to ! record. See the code example for \function{controls} for an example of ! reading from a bitmask. \end{methoddesc} \begin{methoddesc}[mixer device]{get}{channel} ! Returns the volume of a given mixer channel. The returned volume is a ! 2-tuple of \code{left volume, right volume}. Volumes are specified as ! numbers from 0 (silent) to 100 (full volume). If the channel is ! monophonic, a 2-tuple is still returned, but both channel volumes are ! the same. If an unknown channel is specified, \exception{error} is raised. *************** *** 261,270 **** Sets the volume for a given mixer channel to \code{(left, right)}. \code{left} and \code{right} must be ints and between 0 (silent) and 100 ! (full volume). On success, the new volume is returned as a 2-tuple. Note ! that this may not be exactly the same as the volume specified, because of ! the limited resolution of some soundcard's mixers. Raises \exception{IOError} if an invalid mixer channel was specified; ! \exception{TypeError} if the argument format was incorrect, and \exception{error} if the specified volumes were out-of-range. \end{methoddesc} --- 267,276 ---- Sets the volume for a given mixer channel to \code{(left, right)}. \code{left} and \code{right} must be ints and between 0 (silent) and 100 ! (full volume). On success, the new volume is returned as a 2-tuple. ! Note that this may not be exactly the same as the volume specified, ! because of the limited resolution of some soundcard's mixers. Raises \exception{IOError} if an invalid mixer channel was specified; ! \exception{TypeError} if the argument format was incorrect, and \exception{error} if the specified volumes were out-of-range. \end{methoddesc} *************** *** 276,282 **** \begin{methoddesc}[mixer device]{set_recsrc}{bitmask} ! Call this function to specify a recording source. Returns a bitmask indicating the new recording source (or sources) if successful; raises ! \exception{IOError} if an invalid source was specified. To set the current recording source to the microphone input: --- 282,288 ---- \begin{methoddesc}[mixer device]{set_recsrc}{bitmask} ! Call this function to specify a recording source. Returns a bitmask indicating the new recording source (or sources) if successful; raises ! \exception{IOError} if an invalid source was specified. To set the current recording source to the microphone input: From gward@users.sourceforge.net Mon Mar 10 00:07:19 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Sun, 09 Mar 2003 16:07:19 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib lib.tex,1.214,1.215 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv23678/lib Modified Files: lib.tex Log Message: Add libossaudiodev.tex. Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.214 retrieving revision 1.215 diff -C2 -d -r1.214 -r1.215 *** lib.tex 1 Feb 2003 00:10:09 -0000 1.214 --- lib.tex 10 Mar 2003 00:07:14 -0000 1.215 *************** *** 284,287 **** --- 284,288 ---- \input{libimghdr} \input{libsndhdr} + \input{libossaudiodev} \input{libcrypto} % Cryptographic Services From gward@users.sourceforge.net Mon Mar 10 00:07:22 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Sun, 09 Mar 2003 16:07:22 -0800 Subject: [Python-checkins] python/dist/src/Doc Makefile.deps,1.98,1.99 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory sc8-pr-cvs1:/tmp/cvs-serv23678 Modified Files: Makefile.deps Log Message: Add libossaudiodev.tex. Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.98 retrieving revision 1.99 diff -C2 -d -r1.98 -r1.99 *** Makefile.deps 14 Feb 2003 01:45:53 -0000 1.98 --- Makefile.deps 10 Mar 2003 00:07:13 -0000 1.99 *************** *** 192,195 **** --- 192,196 ---- lib/libjpeg.tex \ lib/librgbimg.tex \ + lib/libossaudiodev.tex \ lib/libcrypto.tex \ lib/libmd5.tex \ From gward@users.sourceforge.net Mon Mar 10 00:24:45 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Sun, 09 Mar 2003 16:24:45 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libossaudiodev.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv29776 Modified Files: libossaudiodev.tex Log Message: Fix two unformatted lists: one is now an 'enumerate' environment, the other a 'tableii'. Formatting/typo fix. Index: libossaudiodev.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libossaudiodev.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** libossaudiodev.tex 9 Mar 2003 23:57:34 -0000 1.2 --- libossaudiodev.tex 10 Mar 2003 00:24:42 -0000 1.3 *************** *** 59,66 **** To set up the device, three functions must be called in the correct sequence: ! ! \code{setfmt} to set the output format, ! \code{channels} to set the number of channels, and ! \code{speed} to set the sample rate. The audio device objects are returned by \function{open()} define the --- 59,67 ---- To set up the device, three functions must be called in the correct sequence: ! \begin{enumerate} ! \item \code{setfmt()} to set the output format, ! \item \code{channels()} to set the number of channels, and ! \item \code{speed()} to set the sample rate. ! \end{enumerate} The audio device objects are returned by \function{open()} define the *************** *** 110,129 **** soundcard. On a typical Linux system, these formats are: ! AFMT_MU_LAW---a logarithmic encoding. This is the default format on ! /dev/audio and is the format used by Sun .au files. ! AFMT_A_LAW---a logarithmic encoding ! AFMT_IMA_ADPCM---a 4:1 compressed format defined by the Interactive ! Multimedia Association. ! AFMT_U8---Unsigned, 8-bit audio. ! AFMT_S16_LE---Unsigned, 16-bit audio, little-endian byte order (as used ! by Intel processors) ! AFMT_S16_BE---Unsigned, 16-bit audio, big-endian byte order (as used by ! 68k, PowerPC, Sparc) ! AFMT_S8---Signed, 8 bit audio. ! AFMT_U16_LE---Signed, 16-bit little-endian audio ! AFMT_U16_BE---Signed, 16-bit big-endian audio ! Most systems support only a subset of these formats. Many devices only ! support AFTM_U8; the most common format used today is AFMT_S16_LE. \end{methoddesc} --- 111,141 ---- soundcard. On a typical Linux system, these formats are: ! \begin{tableii}{l|l}{constant}{Format}{Description} ! \lineii{AFMT_MU_LAW} ! {a logarithmic encoding. This is the default format on ! /dev/audio and is the format used by Sun .au files.} ! \lineii{AFMT_A_LAW} ! {a logarithmic encoding} ! \lineii{AFMT_IMA_ADPCM} ! {a 4:1 compressed format defined by the Interactive Multimedia ! Association.} ! \lineii{AFMT_U8} ! {Unsigned, 8-bit audio.} ! \lineii{AFMT_S16_LE} ! {Unsigned, 16-bit audio, little-endian byte order (as used by ! Intel processors)} ! \lineii{AFMT_S16_BE} ! {Unsigned, 16-bit audio, big-endian byte order (as used by 68k, ! PowerPC, Sparc)} ! \lineii{AFMT_S8} ! {Signed, 8 bit audio.} ! \lineii{AFMT_U16_LE} ! {Signed, 16-bit little-endian audio} ! \lineii{AFMT_U16_BE} ! {Signed, 16-bit big-endian audio} ! \end{tableii} Most systems support only a subset of these formats. Many devices only ! support \code{AFMT_U8}; the most common format used today is ! \code{AFMT_S16_LE}. \end{methoddesc} From gward@users.sourceforge.net Mon Mar 10 02:09:53 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Sun, 09 Mar 2003 18:09:53 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libossaudiodev.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv16191 Modified Files: libossaudiodev.tex Log Message: Rewrite intro paragraphs and add a "See also" box for the link to the official OSS docs. Markup fixes: change \code{} variously to \function{}, \method{}, or \constant{} as appropriate. Index: libossaudiodev.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libossaudiodev.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** libossaudiodev.tex 10 Mar 2003 00:24:42 -0000 1.3 --- libossaudiodev.tex 10 Mar 2003 02:09:51 -0000 1.4 *************** *** 1,25 **** \section{\module{ossaudiodev} --- ! Access to Open Sound System-compatible audio hardware} \declaremodule{builtin}{ossaudiodev} ! \platform{OSS} ! \modulesynopsis{Access to OSS-compatible audio hardware.} ! ! % I know FreeBSD uses OSS -- what about Net- and Open-? ! This module allows you to access the Open Sound System audio interface. ! The Open Sound System interface is present on Linux and FreeBSD. ! ! This module provides a very "bare bones" wrapper over the IOCTLs used to ! access the audio hardware. The best---albeit rather daunting---way to ! get a feel for the interface is from the Open Sound System official ! documentation: ! \url{http://www.opensound.com/pguide/oss.pdf} ! The module defines a number of constants which may be used to program ! the device. These constants are the same as those defined in the C ! include file \code{}. ! \code{ossaudiodev} defines the following variables and functions: \begin{excdesc}{error} --- 1,26 ---- \section{\module{ossaudiodev} --- ! Access to OSS-compatible audio devices} \declaremodule{builtin}{ossaudiodev} ! \platform{Linux, FreeBSD} ! \modulesynopsis{Access to OSS-compatible audio devices.} ! % XXX OSS is standard for Linux and FreeBSD -- what about NetBSD? ! % OpenBSD? others? ! This module allows you to access the OSS (Open Sound System) audio ! interface. OSS is available for a wide range of open-source and ! commercial Unices, and is the standard audio interface for Linux (up to ! kernel 2.4) and FreeBSD. ! \begin{seealso} ! \seetitle[http://www.opensound.com/pguide/oss.pdf] ! {Open Sound System Programmer's Guide} ! {the official documentation for the OSS C API} ! \seetext{The module defines a large number of constants supplied by ! the OSS device driver; see \file{} on either ! Linux or FreeBSD for a listing .} ! \end{seealso} ! \module{ossaudiodev} defines the following variables and functions: \begin{excdesc}{error} *************** *** 32,36 **** object. This object can then be used to do I/O on. The \var{device} parameter is the audio device filename to use. If it is not specified, ! this module first looks in the environment variable \code{AUDIODEV} for a device to use. If not found, it falls back to \file{/dev/dsp}. --- 33,37 ---- object. This object can then be used to do I/O on. The \var{device} parameter is the audio device filename to use. If it is not specified, ! this module first looks in the environment variable \envvar{AUDIODEV} for a device to use. If not found, it falls back to \file{/dev/dsp}. *************** *** 47,51 **** \var{device} parameter is the mixer device filename to use. If it is not specified, this module first looks in the environment variable ! \code{MIXERDEV} for a device to use. If not found, it falls back to \file{/dev/mixer}. You may specify \code{'r'}, \code{'rw'} or \code{'w'} for \var{mode}; the default is \code{'r'}. --- 48,52 ---- \var{device} parameter is the mixer device filename to use. If it is not specified, this module first looks in the environment variable ! \envvar{MIXERDEV} for a device to use. If not found, it falls back to \file{/dev/mixer}. You may specify \code{'r'}, \code{'rw'} or \code{'w'} for \var{mode}; the default is \code{'r'}. *************** *** 60,66 **** sequence: \begin{enumerate} ! \item \code{setfmt()} to set the output format, ! \item \code{channels()} to set the number of channels, and ! \item \code{speed()} to set the sample rate. \end{enumerate} --- 61,67 ---- sequence: \begin{enumerate} ! \item \method{setfmt()} to set the output format, ! \item \method{channels()} to set the number of channels, and ! \item \method{speed()} to set the sample rate. \end{enumerate} *************** *** 87,99 **** number of bytes written. If the audio device is opened in blocking mode, the entire string is always written. If the device is opened in ! nonblocking mode, some data may not be written---see \code{writeall}. \end{methoddesc} \begin{methoddesc}[audio device]{writeall}{data} Writes the entire Python string \var{data} to the audio device. If the ! device is opened in blocking mode, behaves identially to \code{write}; ! in nonblocking mode, waits until the device becomes available before ! feeding it more data. Returns None, since the amount of data written is ! always equal to the amount of data supplied. \end{methoddesc} --- 88,101 ---- number of bytes written. If the audio device is opened in blocking mode, the entire string is always written. If the device is opened in ! nonblocking mode, some data may not be written---see ! \method{writeall()}. \end{methoddesc} \begin{methoddesc}[audio device]{writeall}{data} Writes the entire Python string \var{data} to the audio device. If the ! device is opened in blocking mode, behaves identially to ! \method{write()}; in nonblocking mode, waits until the device becomes ! available before feeding it more data. Returns \code{None}, since the ! amount of data written is always equal to the amount of data supplied. \end{methoddesc} *************** *** 114,118 **** \lineii{AFMT_MU_LAW} {a logarithmic encoding. This is the default format on ! /dev/audio and is the format used by Sun .au files.} \lineii{AFMT_A_LAW} {a logarithmic encoding} --- 116,120 ---- \lineii{AFMT_MU_LAW} {a logarithmic encoding. This is the default format on ! \file{/dev/audio} and is the format used by Sun .au files.} \lineii{AFMT_A_LAW} {a logarithmic encoding} *************** *** 136,149 **** \end{tableii} Most systems support only a subset of these formats. Many devices only ! support \code{AFMT_U8}; the most common format used today is ! \code{AFMT_S16_LE}. \end{methoddesc} \begin{methoddesc}[audio device]{setfmt}{format} Used to set the current audio format to \var{format}---see ! \code{getfmts} for a list. May also be used to return the current audio ! format---do this by passing an ``audio format'' of \code{AFMT_QUERY}. ! Returns the audio format that the device was set to, which may not be ! the requested format. \end{methoddesc} --- 138,151 ---- \end{tableii} Most systems support only a subset of these formats. Many devices only ! support \constant{AFMT_U8}; the most common format used today is ! \constant{AFMT_S16_LE}. \end{methoddesc} \begin{methoddesc}[audio device]{setfmt}{format} Used to set the current audio format to \var{format}---see ! \method{getfmts()} for a list. May also be used to return the current ! audio format---do this by passing an ``audio format'' of ! \constant{AFMT_QUERY}. Returns the audio format that the device was set ! to, which may not be the requested format. \end{methoddesc} *************** *** 171,175 **** returns. This also occurs when the sound device is closed. The OSS documentation recommends simply closing and re-opening the device rather ! than using \code{sync}. \end{methoddesc} --- 173,177 ---- returns. This also occurs when the sound device is closed. The OSS documentation recommends simply closing and re-opening the device rather ! than using \method{sync()}. \end{methoddesc} *************** *** 177,188 **** Immediately stops and playing or recording and returns the device to a state where it can accept commands. The OSS documentation recommends ! closing and re-opening the device after calling \code{reset}. \end{methoddesc} \begin{methoddesc}[audio device]{post} ! To be used like a lightweight \code{sync}, the \code{post} IOCTL informs ! the audio device that there is a likely to be a pause in the audio ! output---i.e., after playing a spot sound effect, before waiting for ! user input, or before doing disk IO. \end{methoddesc} --- 179,190 ---- Immediately stops and playing or recording and returns the device to a state where it can accept commands. The OSS documentation recommends ! closing and re-opening the device after calling \method{reset()}. \end{methoddesc} \begin{methoddesc}[audio device]{post} ! To be used like a lightweight \method{sync()}, the \method{post()} ! IOCTL informs the audio device that there is a likely to be a pause in ! the audio output---i.e., after playing a spot sound effect, before ! waiting for user input, or before doing disk I/O. \end{methoddesc} *************** *** 192,199 **** Initialise the sound device in one method. \var{samplerate}, \var{channels} and \var{format} should be as specified in the ! \code{speed}, \code{channels} and \code{setfmt} methods. If ! \var{emulate} is true, attempt to find the closest matching format ! instead, otherwise raise ValueError if the device does not support the ! format. The default is to raise ValueError on unsupported formats. \end{methoddesc} --- 194,202 ---- Initialise the sound device in one method. \var{samplerate}, \var{channels} and \var{format} should be as specified in the ! \method{speed()}, \method{channels()} and \method{setfmt()} ! methods. If \var{emulate} is true, attempt to find the closest matching ! format instead, otherwise raise ValueError if the device does not ! support the format. The default is to raise ValueError on unsupported ! formats. \end{methoddesc} *************** *** 230,236 **** This method returns a bitmask specifying the available mixer controls (``Control'' being a specific mixable ``channel'', such as ! \code{SOUND_MIXER_PCM} or \code{SOUND_MIXER_SYNTH}). This bitmask indicates a subset of all available mixer channels---the ! \code{SOUND_MIXER_*} constants defined at module level. To determine if, for example, the current mixer object supports a PCM mixer, use the following Python code: --- 233,239 ---- This method returns a bitmask specifying the available mixer controls (``Control'' being a specific mixable ``channel'', such as ! \constant{SOUND_MIXER_PCM} or \constant{SOUND_MIXER_SYNTH}). This bitmask indicates a subset of all available mixer channels---the ! \constant{SOUND_MIXER_*} constants defined at module level. To determine if, for example, the current mixer object supports a PCM mixer, use the following Python code: *************** *** 243,250 **** \end{verbatim} ! For most purposes, the \code{SOUND_MIXER_VOLUME} (Master volume) and ! \code{SOUND_MIXER_PCM} channels should suffice---but code that uses the mixer should be flexible when it comes to choosing sound channels. On ! the Gravis Ultrasound, for example, \code{SOUND_MIXER_VOLUME} does not exist. \end{methoddesc} --- 246,253 ---- \end{verbatim} ! For most purposes, the \constant{SOUND_MIXER_VOLUME} (Master volume) and ! \constant{SOUND_MIXER_PCM} channels should suffice---but code that uses the mixer should be flexible when it comes to choosing sound channels. On ! the Gravis Ultrasound, for example, \constant{SOUND_MIXER_VOLUME} does not exist. \end{methoddesc} *************** *** 254,260 **** the corresponding channel is stereo; if it is unset, the channel is either monophonic or not supported by the mixer (use in combination with ! \function{channels} to determine which). ! See the code example for the \function{channels} function for an example of getting data from a bitmask. \end{methoddesc} --- 257,263 ---- the corresponding channel is stereo; if it is unset, the channel is either monophonic or not supported by the mixer (use in combination with ! \method{channels()} to determine which). ! See the code example for the \method{channels()} function for an example of getting data from a bitmask. \end{methoddesc} *************** *** 262,266 **** \begin{methoddesc}[mixer device]{reccontrols}{} Returns a bitmask specifying the mixer controls that may be used to ! record. See the code example for \function{controls} for an example of reading from a bitmask. \end{methoddesc} --- 265,269 ---- \begin{methoddesc}[mixer device]{reccontrols}{} Returns a bitmask specifying the mixer controls that may be used to ! record. See the code example for \method{controls()} for an example of reading from a bitmask. \end{methoddesc} *************** *** 268,272 **** \begin{methoddesc}[mixer device]{get}{channel} Returns the volume of a given mixer channel. The returned volume is a ! 2-tuple of \code{left volume, right volume}. Volumes are specified as numbers from 0 (silent) to 100 (full volume). If the channel is monophonic, a 2-tuple is still returned, but both channel volumes are --- 271,275 ---- \begin{methoddesc}[mixer device]{get}{channel} Returns the volume of a given mixer channel. The returned volume is a ! 2-tuple \code{(left_volume,right_volume)}. Volumes are specified as numbers from 0 (silent) to 100 (full volume). If the channel is monophonic, a 2-tuple is still returned, but both channel volumes are *************** *** 277,281 **** \begin{methoddesc}[mixer device]{set}{channel, (left, right)} ! Sets the volume for a given mixer channel to \code{(left, right)}. \code{left} and \code{right} must be ints and between 0 (silent) and 100 (full volume). On success, the new volume is returned as a 2-tuple. --- 280,284 ---- \begin{methoddesc}[mixer device]{set}{channel, (left, right)} ! Sets the volume for a given mixer channel to \code{(left,right)}. \code{left} and \code{right} must be ints and between 0 (silent) and 100 (full volume). On success, the new volume is returned as a 2-tuple. From gward@users.sourceforge.net Mon Mar 10 03:05:25 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Sun, 09 Mar 2003 19:05:25 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libossaudiodev.tex,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv1089/lib Modified Files: libossaudiodev.tex Log Message: Expand description of ossaudiodev.error exception. Improve descriptions of open(), openmixer(). Index: libossaudiodev.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libossaudiodev.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** libossaudiodev.tex 10 Mar 2003 02:09:51 -0000 1.4 --- libossaudiodev.tex 10 Mar 2003 03:05:21 -0000 1.5 *************** *** 25,54 **** \begin{excdesc}{error} ! This exception is raised on errors. The argument is a string describing ! what went wrong. \end{excdesc} \begin{funcdesc}{open}{\optional{device, }mode} ! This function opens the audio device and returns an OSS audio device ! object. This object can then be used to do I/O on. The \var{device} ! parameter is the audio device filename to use. If it is not specified, ! this module first looks in the environment variable \envvar{AUDIODEV} for ! a device to use. If not found, it falls back to \file{/dev/dsp}. ! The \var{mode} parameter is one of \code{'r'} for record-only access, ! \code{'w'} for play-only access and \code{'rw'} for both. Since many ! soundcards only allow one process to have the recorder or player open at ! a time it is a good idea to open the device only for the activity ! needed. Further, some soundcards are half-duplex: they can be opened ! for reading or writing, but not both at once. \end{funcdesc} ! \begin{funcdesc}{openmixer}{\optional{device\optional{, mode}}} This function ! opens the mixer device and returns an OSS mixer device object. The ! \var{device} parameter is the mixer device filename to use. If it is not specified, this module first looks in the environment variable \envvar{MIXERDEV} for a device to use. If not found, it falls back to \file{/dev/mixer}. You may specify \code{'r'}, \code{'rw'} or \code{'w'} for \var{mode}; the default is \code{'r'}. \end{funcdesc} --- 25,75 ---- \begin{excdesc}{error} ! This exception is raised on certain errors. The argument is a string ! describing what went wrong. ! ! (If \module{ossaudiodev} receives an error from a system call such as ! \cfunction{open()}, \cfunction{write()}, or \cfunction{ioctl()}, it ! raises \exception{IOError}. Errors detected directly by ! \module{ossaudiodev} result in \exception{ossaudiodev.error}.) \end{excdesc} \begin{funcdesc}{open}{\optional{device, }mode} ! Open an audio device and return an OSS audio device object. This ! object supports many file-like methods, such as \method{read()}, ! \method{write()}, and \method{fileno()} (although there are subtle ! differences between conventional Unix read/write semantics and those of ! OSS audio devices). It also supports a number of audio-specific ! methods; see below for the complete list of methods. ! Note the unusual calling syntax: the \emph{first} argument is optional, ! and the second is required. This is a historical artifact for ! compatibility with the older \module{linuxaudiodev} module which ! \module{ossaudiodev} supersedes. % XXX it might also be motivated ! % by my unfounded-but-still-possibly-true belief that the default ! % audio device varies unpredictably across operating systems. -GW ! ! \var{device} is the audio device filename to use. If it is not ! specified, this module first looks in the environment variable ! \envvar{AUDIODEV} for a device to use. If not found, it falls back to ! \file{/dev/dsp}. ! ! \var{mode} is one of \code{'r'} for read-only (record) access, ! \code{'w'} for write-only (playback) access and \code{'rw'} for both. ! Since many soundcards only allow one process to have the recorder or ! player open at a time it is a good idea to open the device only for the ! activity needed. Further, some soundcards are half-duplex: they can be ! opened for reading or writing, but not both at once. \end{funcdesc} ! \begin{funcdesc}{openmixer}{\optional{device\optional{, mode}}} ! Open a mixer device and return an OSS mixer device object. ! \var{device} is the mixer device filename to use. If it is not specified, this module first looks in the environment variable \envvar{MIXERDEV} for a device to use. If not found, it falls back to \file{/dev/mixer}. You may specify \code{'r'}, \code{'rw'} or \code{'w'} for \var{mode}; the default is \code{'r'}. + + % XXX I suspect 'mode' is irrelevant, ie. that OSS doesn't care. + % If so this argument and the code that handles it should be ripped out. \end{funcdesc} From gward@users.sourceforge.net Mon Mar 10 03:17:13 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Sun, 09 Mar 2003 19:17:13 -0800 Subject: [Python-checkins] python/dist/src/Modules ossaudiodev.c,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv4076/Modules Modified Files: ossaudiodev.c Log Message: seems to exist on both Linux and FreeBSD, so include it instead of the OS-specific or . Mixers devices have an ioctl-only interface, no read/write -- so the flags passed to open() don't really matter. Thus, drop the 'mode' parameter to openmixer() (ie. second arg to newossmixerobject()) and always open mixers with O_RDWR. Index: ossaudiodev.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/ossaudiodev.c,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** ossaudiodev.c 13 Feb 2003 13:27:07 -0000 1.23 --- ossaudiodev.c 10 Mar 2003 03:17:06 -0000 1.24 *************** *** 30,46 **** #endif - #include #if defined(linux) - #include typedef unsigned long uint32_t; #elif defined(__FreeBSD__) - #include ! #ifndef SNDCTL_DSP_CHANNELS ! #define SNDCTL_DSP_CHANNELS SOUND_PCM_WRITE_CHANNELS ! #endif #endif --- 30,45 ---- #endif #include + #include + #if defined(linux) typedef unsigned long uint32_t; #elif defined(__FreeBSD__) ! # ifndef SNDCTL_DSP_CHANNELS ! # define SNDCTL_DSP_CHANNELS SOUND_PCM_WRITE_CHANNELS ! # endif #endif *************** *** 170,178 **** newossmixerobject(PyObject *arg) { ! char *basedev = NULL, *mode = NULL; ! int fd, imode; oss_mixer_t *self; ! if (!PyArg_ParseTuple(arg, "|ss", &basedev, &mode)) { return NULL; } --- 169,177 ---- newossmixerobject(PyObject *arg) { ! char *basedev = NULL; ! int fd; oss_mixer_t *self; ! if (!PyArg_ParseTuple(arg, "|s", &basedev)) { return NULL; } *************** *** 184,203 **** } ! if (mode == NULL || strcmp(mode, "r") == 0) ! imode = O_RDONLY; ! else if (strcmp(mode, "w") == 0) ! imode = O_WRONLY; ! else if (strcmp(mode, "rw") == 0) ! imode = O_RDWR; ! else { ! PyErr_SetString(OSSAudioError, "mode must be 'r', 'w', or 'rw'"); ! return NULL; ! } ! ! if ((fd = open(basedev, imode)) == -1) { PyErr_SetFromErrnoWithFilename(PyExc_IOError, basedev); return NULL; } ! if ((self = PyObject_New(oss_mixer_t, &OSSMixerType)) == NULL) { close(fd); --- 183,191 ---- } ! if ((fd = open(basedev, O_RDWR)) == -1) { PyErr_SetFromErrnoWithFilename(PyExc_IOError, basedev); return NULL; } ! if ((self = PyObject_New(oss_mixer_t, &OSSMixerType)) == NULL) { close(fd); From gward@users.sourceforge.net Mon Mar 10 03:18:22 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Sun, 09 Mar 2003 19:18:22 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libossaudiodev.tex,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv4966 Modified Files: libossaudiodev.tex Log Message: openmixer()'s 'mode' parameter has been removed. Index: libossaudiodev.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libossaudiodev.tex,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** libossaudiodev.tex 10 Mar 2003 03:05:21 -0000 1.5 --- libossaudiodev.tex 10 Mar 2003 03:18:19 -0000 1.6 *************** *** 62,75 **** \end{funcdesc} ! \begin{funcdesc}{openmixer}{\optional{device\optional{, mode}}} Open a mixer device and return an OSS mixer device object. \var{device} is the mixer device filename to use. If it is not specified, this module first looks in the environment variable \envvar{MIXERDEV} for a device to use. If not found, it falls back to ! \file{/dev/mixer}. You may specify \code{'r'}, \code{'rw'} or ! \code{'w'} for \var{mode}; the default is \code{'r'}. ! ! % XXX I suspect 'mode' is irrelevant, ie. that OSS doesn't care. ! % If so this argument and the code that handles it should be ripped out. \end{funcdesc} --- 62,71 ---- \end{funcdesc} ! \begin{funcdesc}{openmixer}{\optional{device}} Open a mixer device and return an OSS mixer device object. \var{device} is the mixer device filename to use. If it is not specified, this module first looks in the environment variable \envvar{MIXERDEV} for a device to use. If not found, it falls back to ! \file{/dev/mixer}. \end{funcdesc} From bwarsaw@users.sourceforge.net Mon Mar 10 15:11:36 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 07:11:36 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv13169 Modified Files: test_email.py Log Message: test_another_long_multiline_header(): Yet another formatting test. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** test_email.py 7 Mar 2003 23:23:04 -0000 1.37 --- test_email.py 10 Mar 2003 15:11:29 -0000 1.38 *************** *** 811,814 **** --- 811,826 ---- """) + def test_another_long_multiline_header(self): + eq = self.ndiffAssertEqual + m = '''\ + Received: from siimage.com ([172.25.1.3]) by zima.siliconimage.com with Microsoft SMTPSVC(5.0.2195.4905); + Wed, 16 Oct 2002 07:41:11 -0700''' + msg = email.message_from_string(m) + eq(msg.as_string(), '''\ + Received: from siimage.com ([172.25.1.3]) by zima.siliconimage.com with + Microsoft SMTPSVC(5.0.2195.4905); Wed, 16 Oct 2002 07:41:11 -0700 + + ''') + From akuchling@users.sourceforge.net Mon Mar 10 15:12:08 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 10 Mar 2003 07:12:08 -0800 Subject: [Python-checkins] python/dist/src/Lib asynchat.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv13379 Modified Files: asynchat.py Log Message: Use isinstance() instead of type comparison Index: asynchat.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asynchat.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** asynchat.py 30 Jun 2002 03:39:14 -0000 1.19 --- asynchat.py 10 Mar 2003 15:12:00 -0000 1.20 *************** *** 105,109 **** self.collect_incoming_data (self.ac_in_buffer) self.ac_in_buffer = '' ! elif type(terminator) == type(0): # numeric terminator n = terminator --- 105,109 ---- self.collect_incoming_data (self.ac_in_buffer) self.ac_in_buffer = '' ! elif isinstance(terminator, int): # numeric terminator n = terminator *************** *** 184,188 **** # of the first producer in the queue def refill_buffer (self): - _string_type = type('') while 1: if len(self.producer_fifo): --- 184,187 ---- *************** *** 195,199 **** self.close() return ! elif type(p) is _string_type: self.producer_fifo.pop() self.ac_out_buffer = self.ac_out_buffer + p --- 194,198 ---- self.close() return ! elif isinstance(p, str): self.producer_fifo.pop() self.ac_out_buffer = self.ac_out_buffer + p From bwarsaw@users.sourceforge.net Mon Mar 10 15:14:12 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 07:14:12 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Header.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv14235 Modified Files: Header.py Log Message: _split_ascii() [method and function]: Don't join the lines just to split them again. Simply return them as chunk lists. _encode_chunks(): Don't add more folding whitespace than necessary. Index: Header.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Header.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** Header.py 7 Mar 2003 23:24:34 -0000 1.24 --- Header.py 10 Mar 2003 15:14:08 -0000 1.25 *************** *** 338,345 **** def _split_ascii(self, s, charset, firstlen, splitchars): ! line = _split_ascii(s, firstlen, self._maxlinelen, ! self._continuation_ws, splitchars) ! lines = line.splitlines() ! return zip(lines, [charset]*len(lines)) def _encode_chunks(self, newchunks, maxlinelen): --- 338,344 ---- def _split_ascii(self, s, charset, firstlen, splitchars): ! chunks = _split_ascii(s, firstlen, self._maxlinelen, ! self._continuation_ws, splitchars) ! return zip(chunks, [charset]*len(chunks)) def _encode_chunks(self, newchunks, maxlinelen): *************** *** 361,365 **** # =?charset1?q?Mar=EDa_Gonz=E1lez_Alonso?=\n # =?charset2?b?SvxyZ2VuIEL2aW5n?=" - # chunks = [] for header, charset in newchunks: --- 360,363 ---- *************** *** 368,372 **** else: s = charset.header_encode(header) ! _max_append(chunks, s, maxlinelen, ' ') joiner = NL + self._continuation_ws return joiner.join(chunks) --- 366,375 ---- else: s = charset.header_encode(header) ! # Don't add more folding whitespace than necessary ! if chunks and chunks[-1].endswith(' '): ! extra = '' ! else: ! extra = ' ' ! _max_append(chunks, s, maxlinelen, extra) joiner = NL + self._continuation_ws return joiner.join(chunks) *************** *** 413,417 **** def _split_ascii(s, firstlen, restlen, continuation_ws, splitchars): - linejoiner = '\n' + continuation_ws lines = [] maxlen = firstlen --- 416,419 ---- *************** *** 465,471 **** # on whitespace. if partlen > maxlen and ch <> ' ': ! subs = _split_ascii(part, maxlen, restlen, continuation_ws, ' ') - subl = re.split(linejoiner, subs) lines.extend(subl[:-1]) this = [subl[-1]] --- 467,472 ---- # on whitespace. if partlen > maxlen and ch <> ' ': ! subl = _split_ascii(part, maxlen, restlen, continuation_ws, ' ') lines.extend(subl[:-1]) this = [subl[-1]] *************** *** 480,484 **** if this: lines.append(joiner.join(this)) ! return linejoiner.join(lines) --- 481,485 ---- if this: lines.append(joiner.join(this)) ! return lines From akuchling@users.sourceforge.net Mon Mar 10 15:16:57 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Mon, 10 Mar 2003 07:16:57 -0800 Subject: [Python-checkins] python/dist/src/Lib asynchat.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv14644 Modified Files: asynchat.py Log Message: [Patch #649762] Fix for asynchat endless loop When the null string is used as the terminator, it used to be the same as None, meaning "collect all the data". In the current code, however, it falls into an endless loop; this change reverts to the old behavior. Index: asynchat.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asynchat.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** asynchat.py 10 Mar 2003 15:12:00 -0000 1.20 --- asynchat.py 10 Mar 2003 15:16:54 -0000 1.21 *************** *** 101,105 **** lb = len(self.ac_in_buffer) terminator = self.get_terminator() ! if terminator is None: # no terminator, collect it all self.collect_incoming_data (self.ac_in_buffer) --- 101,105 ---- lb = len(self.ac_in_buffer) terminator = self.get_terminator() ! if terminator is None or terminator == '': # no terminator, collect it all self.collect_incoming_data (self.ac_in_buffer) From loewis@users.sourceforge.net Mon Mar 10 16:01:46 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Mon, 10 Mar 2003 08:01:46 -0800 Subject: [Python-checkins] python/dist/src/Lib gettext.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv10742 Modified Files: gettext.py Log Message: Patch #700839: Fix bugs in the plural handling. Index: gettext.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/gettext.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** gettext.py 21 Nov 2002 21:45:32 -0000 1.16 --- gettext.py 10 Mar 2003 16:01:43 -0000 1.17 *************** *** 33,37 **** # module. # ! # J. David Ibanez implemented plural forms. # # TODO: --- 33,37 ---- # module. # ! # J. David Ibanez implemented plural forms. Bruno Haible fixed some bugs. # # TODO: *************** *** 81,87 **** import token, tokenize tokens = tokenize.generate_tokens(StringIO(plural).readline) ! danger = [ x for x in tokens if x[0] == token.NAME and x[1] != 'n' ] ! if danger: ! raise ValueError, 'dangerous expression' # Replace some C operators by their Python equivalents --- 81,92 ---- import token, tokenize tokens = tokenize.generate_tokens(StringIO(plural).readline) ! try: ! danger = [ x for x in tokens if x[0] == token.NAME and x[1] != 'n' ] ! except tokenize.TokenError: ! raise ValueError, \ ! 'plural forms expression error, maybe unbalanced parenthesis' ! else: ! if danger: ! raise ValueError, 'plural forms expression could be dangerous' # Replace some C operators by their Python equivalents *************** *** 89,94 **** plural = plural.replace('||', ' or ') ! expr = re.compile(r'\![^=]') ! plural = expr.sub(' not ', plural) # Regular expression and replacement function used to transform --- 94,99 ---- plural = plural.replace('||', ' or ') ! expr = re.compile(r'\!([^=])') ! plural = expr.sub(' not \\1', plural) # Regular expression and replacement function used to transform *************** *** 105,109 **** stack.append('') elif c == ')': ! if len(stack) == 0: raise ValueError, 'unbalanced parenthesis in plural form' s = expr.sub(repl, stack.pop()) --- 110,117 ---- stack.append('') elif c == ')': ! if len(stack) == 1: ! # Actually, we never reach this code, because unbalanced ! # parentheses get caught in the security check at the ! # beginning. raise ValueError, 'unbalanced parenthesis in plural form' s = expr.sub(repl, stack.pop()) *************** *** 226,229 **** --- 234,238 ---- # bit words. self._catalog = catalog = {} + self.plural = lambda n: int(n != 1) # germanic plural by default buf = fp.read() buflen = len(buf) *************** *** 259,263 **** raise IOError(0, 'File is corrupt', filename) # See if we're looking at GNU .mo conventions for metadata ! if mlen == 0 and tmsg.lower().startswith('project-id-version:'): # Catalog description for item in tmsg.split('\n'): --- 268,272 ---- raise IOError(0, 'File is corrupt', filename) # See if we're looking at GNU .mo conventions for metadata ! if mlen == 0: # Catalog description for item in tmsg.split('\n'): From bwarsaw@users.sourceforge.net Mon Mar 10 16:09:56 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 08:09:56 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv16003 Modified Files: test_email.py Log Message: test_broken_base64_payload(): Test for crash in low-level binascii module when decoding a message with broken base64. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** test_email.py 10 Mar 2003 15:11:29 -0000 1.38 --- test_email.py 10 Mar 2003 16:09:51 -0000 1.39 *************** *** 459,462 **** --- 459,470 ---- self.assertRaises(KeyError, msg.replace_header, 'Fourth', 'Missing') + def test_broken_base64_payload(self): + x = 'AwDp0P7//y6LwKEAcPa/6Q=9' + msg = Message() + msg['content-type'] = 'audio/x-midi' + msg['content-transfer-encoding'] = 'base64' + msg.set_payload(x) + self.assertEqual(msg.get_payload(decode=True), x) + From bwarsaw@users.sourceforge.net Mon Mar 10 16:13:23 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 08:13:23 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Message.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv17913 Modified Files: Message.py Log Message: get_payload(): If we get a low-level binascii.Error when base64 decoding the payload, just return it as-is. Index: Message.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Message.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** Message.py 10 Oct 2002 15:13:26 -0000 1.28 --- Message.py 10 Mar 2003 16:13:14 -0000 1.29 *************** *** 6,9 **** --- 6,10 ---- import re + import binascii import warnings from cStringIO import StringIO *************** *** 11,16 **** # Intrapackage imports - from email import Errors from email import Utils from email import Charset --- 12,17 ---- # Intrapackage imports from email import Utils + from email import Errors from email import Charset *************** *** 170,176 **** multipart, the payload will be decoded if this header's value is `quoted-printable' or `base64'. If some other encoding is used, or ! the header is missing, the payload is returned as-is (undecoded). If ! the message is a multipart and the decode flag is True, then None is ! returned. """ if i is None: --- 171,179 ---- multipart, the payload will be decoded if this header's value is `quoted-printable' or `base64'. If some other encoding is used, or ! the header is missing, or if the payload has bogus base64 data, the ! payload is returned as-is (undecoded). ! ! If the message is a multipart and the decode flag is True, then None ! is returned. """ if i is None: *************** *** 187,191 **** return Utils._qdecode(payload) elif cte.lower() == 'base64': ! return Utils._bdecode(payload) # Everything else, including encodings with 8bit or 7bit are returned # unchanged. --- 190,198 ---- return Utils._qdecode(payload) elif cte.lower() == 'base64': ! try: ! return Utils._bdecode(payload) ! except binascii.Error: ! # Incorrect padding ! return payload # Everything else, including encodings with 8bit or 7bit are returned # unchanged. From bwarsaw@users.sourceforge.net Mon Mar 10 16:13:55 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 08:13:55 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib emailmessage.tex,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv18208 Modified Files: emailmessage.tex Log Message: Describe what happens when decode=True and the payload has bogus base64 data. Index: emailmessage.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailmessage.tex,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** emailmessage.tex 10 Oct 2002 15:22:16 -0000 1.9 --- emailmessage.tex 10 Mar 2003 16:13:50 -0000 1.10 *************** *** 88,94 **** \samp{base64}. If some other encoding is used, or \mailheader{Content-Transfer-Encoding} header is ! missing, the payload is returned as-is (undecoded). If the message is ! a multipart and the \var{decode} flag is \code{True}, then \code{None} is ! returned. The default for \var{decode} is \code{False}. \end{methoddesc} --- 88,95 ---- \samp{base64}. If some other encoding is used, or \mailheader{Content-Transfer-Encoding} header is ! missing, or if the payload has bogus base64 data, the payload is ! returned as-is (undecoded). If the message is a multipart and the ! \var{decode} flag is \code{True}, then \code{None} is returned. The ! default for \var{decode} is \code{False}. \end{methoddesc} From bwarsaw@users.sourceforge.net Mon Mar 10 16:59:37 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 08:59:37 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv11022 Modified Files: test_email.py Log Message: Use ndiffAssertEqual in a couple of places for better error reporting. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** test_email.py 10 Mar 2003 16:09:51 -0000 1.39 --- test_email.py 10 Mar 2003 16:59:34 -0000 1.40 *************** *** 1090,1093 **** --- 1090,1094 ---- def test_one_part_in_a_multipart(self): + eq = self.ndiffAssertEqual outer = MIMEBase('multipart', 'mixed') outer['Subject'] = 'A subject' *************** *** 1099,1103 **** msg = MIMEText('hello world') outer.attach(msg) ! self.assertEqual(outer.as_string(), '''\ Content-Type: multipart/mixed; boundary="BOUNDARY" MIME-Version: 1.0 --- 1100,1104 ---- msg = MIMEText('hello world') outer.attach(msg) ! eq(outer.as_string(), '''\ Content-Type: multipart/mixed; boundary="BOUNDARY" MIME-Version: 1.0 *************** *** 1117,1120 **** --- 1118,1122 ---- def test_seq_parts_in_a_multipart(self): + eq = self.ndiffAssertEqual outer = MIMEBase('multipart', 'mixed') outer['Subject'] = 'A subject' *************** *** 1126,1130 **** outer.attach(msg) outer.set_boundary('BOUNDARY') ! self.assertEqual(outer.as_string(), '''\ Content-Type: multipart/mixed; boundary="BOUNDARY" MIME-Version: 1.0 --- 1128,1132 ---- outer.attach(msg) outer.set_boundary('BOUNDARY') ! eq(outer.as_string(), '''\ Content-Type: multipart/mixed; boundary="BOUNDARY" MIME-Version: 1.0 *************** *** 1411,1414 **** --- 1413,1417 ---- def test_epilogue(self): + eq = self.ndiffAssertEqual fp = openfile('msg_21.txt') try: *************** *** 1430,1434 **** g = Generator(sfp) g.flatten(msg) ! self.assertEqual(sfp.getvalue(), text) def test_no_nl_preamble(self): --- 1433,1437 ---- g = Generator(sfp) g.flatten(msg) ! eq(sfp.getvalue(), text) def test_no_nl_preamble(self): From bwarsaw@users.sourceforge.net Mon Mar 10 17:00:51 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 09:00:51 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv11609 Modified Files: test_email.py Log Message: Fix base class Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** test_email.py 10 Mar 2003 16:59:34 -0000 1.40 --- test_email.py 10 Mar 2003 17:00:43 -0000 1.41 *************** *** 1007,1011 **** # Test a more complicated multipart/mixed type message ! class TestMultipartMixed(unittest.TestCase): def setUp(self): fp = openfile('PyBanner048.gif') --- 1007,1011 ---- # Test a more complicated multipart/mixed type message ! class TestMultipartMixed(TestEmailBase): def setUp(self): fp = openfile('PyBanner048.gif') From bwarsaw@users.sourceforge.net Mon Mar 10 17:36:08 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 09:36:08 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Utils.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv30210 Modified Files: Utils.py Log Message: _bdecode(): Remove redundant check. Index: Utils.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Utils.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** Utils.py 7 Mar 2003 22:46:41 -0000 1.22 --- Utils.py 10 Mar 2003 17:36:04 -0000 1.23 *************** *** 67,72 **** def _bdecode(s): - if not s: - return s # We can't quite use base64.encodestring() since it tacks on a "courtesy # newline". Blech! --- 67,70 ---- From bwarsaw@users.sourceforge.net Mon Mar 10 19:18:48 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 11:18:48 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv23679 Modified Files: test_email.py Log Message: test_escape_backslashes(): A test for SF bug #663369 by Matthew Woodcraft. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** test_email.py 10 Mar 2003 17:00:43 -0000 1.41 --- test_email.py 10 Mar 2003 19:18:34 -0000 1.42 *************** *** 1860,1863 **** --- 1860,1871 ---- self.assertEqual(Utils.parseaddr(Utils.formataddr((a, b))), (a, b)) + def test_escape_backslashes(self): + self.assertEqual( + Utils.formataddr(('Arthur \Backslash\ Foobar', 'person@dom.ain')), + r'"Arthur \\Backslash\\ Foobar" ') + a = r'Arthur \Backslash\ Foobar' + b = 'person@dom.ain' + self.assertEqual(Utils.parseaddr(Utils.formataddr((a, b))), (a, b)) + def test_name_with_dot(self): x = 'John X. Doe ' From bwarsaw@users.sourceforge.net Mon Mar 10 19:20:21 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 11:20:21 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Utils.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv24677 Modified Files: Utils.py Log Message: specialsre, escapesre: In SF bug #663369, Matthew Woodcraft points out that backslashes must be escaped in character sets. Index: Utils.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Utils.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** Utils.py 10 Mar 2003 17:36:04 -0000 1.23 --- Utils.py 10 Mar 2003 19:20:18 -0000 1.24 *************** *** 55,60 **** CRLF = '\r\n' ! specialsre = re.compile(r'[][\()<>@,:;".]') ! escapesre = re.compile(r'[][\()"]') --- 55,60 ---- CRLF = '\r\n' ! specialsre = re.compile(r'[][\\()<>@,:;".]') ! escapesre = re.compile(r'[][\\()"]') From bwarsaw@users.sourceforge.net Tue Mar 11 04:31:39 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 20:31:39 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv27845 Modified Files: test_email.py Log Message: test_get_decoded_uu_payload(): A new test for Content-Transfer-Encoding: x-uuencode Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** test_email.py 10 Mar 2003 19:18:34 -0000 1.42 --- test_email.py 11 Mar 2003 04:31:37 -0000 1.43 *************** *** 205,208 **** --- 205,219 ---- 'This has no Content-Transfer-Encoding: header.\n') + def test_get_decoded_uu_payload(self): + eq = self.assertEqual + msg = Message() + msg.set_payload('begin 666 -\n+:&5L;&\\@=V]R;&0 \n \nend\n') + for cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): + msg['content-transfer-encoding'] = cte + eq(msg.get_payload(decode=True), 'hello world') + # Now try some bogus data + msg.set_payload('foo') + eq(msg.get_payload(decode=True), 'foo') + def test_decoded_generator(self): eq = self.assertEqual From bwarsaw@users.sourceforge.net Tue Mar 11 04:33:33 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 20:33:33 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Message.py,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv28372 Modified Files: Message.py Log Message: get_payload(): Teach this about various uunencoded Content-Transfer-Encodings Index: Message.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Message.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** Message.py 10 Mar 2003 16:13:14 -0000 1.29 --- Message.py 11 Mar 2003 04:33:30 -0000 1.30 *************** *** 6,9 **** --- 6,10 ---- import re + import uu import binascii import warnings *************** *** 166,176 **** i returns that index into the payload. ! Optional decode is a flag (defaulting to False) indicating whether the ! payload should be decoded or not, according to the ! Content-Transfer-Encoding header. When True and the message is not a ! multipart, the payload will be decoded if this header's value is ! `quoted-printable' or `base64'. If some other encoding is used, or ! the header is missing, or if the payload has bogus base64 data, the ! payload is returned as-is (undecoded). If the message is a multipart and the decode flag is True, then None --- 167,179 ---- i returns that index into the payload. ! Optional decode is a flag indicating whether the payload should be ! decoded or not, according to the Content-Transfer-Encoding header ! (default is False). ! ! When True and the message is not a multipart, the payload will be ! decoded if this header's value is `quoted-printable' or `base64'. If ! some other encoding is used, or the header is missing, or if the ! payload has bogus data (i.e. bogus base64 or uuencoded data), the ! payload is returned as-is. If the message is a multipart and the decode flag is True, then None *************** *** 186,197 **** if self.is_multipart(): return None ! cte = self.get('content-transfer-encoding', '') ! if cte.lower() == 'quoted-printable': return Utils._qdecode(payload) ! elif cte.lower() == 'base64': try: return Utils._bdecode(payload) except binascii.Error: # Incorrect padding return payload # Everything else, including encodings with 8bit or 7bit are returned --- 189,208 ---- if self.is_multipart(): return None ! cte = self.get('content-transfer-encoding', '').lower() ! if cte == 'quoted-printable': return Utils._qdecode(payload) ! elif cte == 'base64': try: return Utils._bdecode(payload) except binascii.Error: # Incorrect padding + return payload + elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): + sfp = StringIO() + try: + uu.decode(StringIO(payload+'\n'), sfp) + payload = sfp.getvalue() + except uu.Error: + # Some decoding problem return payload # Everything else, including encodings with 8bit or 7bit are returned From bwarsaw@users.sourceforge.net Tue Mar 11 04:40:16 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 20:40:16 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib emailiter.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv30415 Modified Files: emailiter.tex Log Message: body_line_iterator() now takes a decode argument. Index: emailiter.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailiter.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** emailiter.tex 1 Oct 2002 01:05:52 -0000 1.3 --- emailiter.tex 11 Mar 2003 04:40:14 -0000 1.4 *************** *** 7,11 **** trees. ! \begin{funcdesc}{body_line_iterator}{msg} This iterates over all the payloads in all the subparts of \var{msg}, returning the string payloads line-by-line. It skips over all the --- 7,11 ---- trees. ! \begin{funcdesc}{body_line_iterator}{msg\optional{, decode}} This iterates over all the payloads in all the subparts of \var{msg}, returning the string payloads line-by-line. It skips over all the *************** *** 14,17 **** --- 14,19 ---- flat text representation of the message from a file using \method{readline()}, skipping over all the intervening headers. + + Optional \var{decode} is passed through to \method{Message.get_payload()}. \end{funcdesc} From bwarsaw@users.sourceforge.net Tue Mar 11 04:41:20 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 20:41:20 -0800 Subject: [Python-checkins] python/dist/src/Lib/email _compat21.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv30655 Modified Files: _compat21.py Log Message: body_line_iterator(): Accept optional decode argument, pass through to Message.get_payload(). Index: _compat21.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/_compat21.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** _compat21.py 24 Dec 2002 18:31:27 -0000 1.5 --- _compat21.py 11 Mar 2003 04:41:18 -0000 1.6 *************** *** 38,46 **** # These two functions are imported into the Iterators.py interface module. # The Python 2.2 version uses generators for efficiency. ! def body_line_iterator(msg): ! """Iterate over the parts, returning string payloads line-by-line.""" lines = [] for subpart in msg.walk(): ! payload = subpart.get_payload() if _isstring(payload): for line in StringIO(payload).readlines(): --- 38,49 ---- # These two functions are imported into the Iterators.py interface module. # The Python 2.2 version uses generators for efficiency. ! def body_line_iterator(msg, decode=False): ! """Iterate over the parts, returning string payloads line-by-line. ! ! Optional decode (default False) is passed through to .get_payload(). ! """ lines = [] for subpart in msg.walk(): ! payload = subpart.get_payload(decode=decode) if _isstring(payload): for line in StringIO(payload).readlines(): From bwarsaw@users.sourceforge.net Tue Mar 11 04:41:37 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 20:41:37 -0800 Subject: [Python-checkins] python/dist/src/Lib/email _compat22.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv30737 Modified Files: _compat22.py Log Message: body_line_iterator(): Accept optional decode argument, pass through to Message.get_payload(). Index: _compat22.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/_compat22.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** _compat22.py 10 Sep 2002 16:09:06 -0000 1.4 --- _compat22.py 11 Mar 2003 04:41:35 -0000 1.5 *************** *** 39,46 **** # These two functions are imported into the Iterators.py interface module. # The Python 2.2 version uses generators for efficiency. ! def body_line_iterator(msg): ! """Iterate over the parts, returning string payloads line-by-line.""" for subpart in msg.walk(): ! payload = subpart.get_payload() if _isstring(payload): for line in StringIO(payload): --- 39,49 ---- # These two functions are imported into the Iterators.py interface module. # The Python 2.2 version uses generators for efficiency. ! def body_line_iterator(msg, decode=False): ! """Iterate over the parts, returning string payloads line-by-line. ! ! Optional decode (default False) is passed through to .get_payload(). ! """ for subpart in msg.walk(): ! payload = subpart.get_payload(decode=decode) if _isstring(payload): for line in StringIO(payload): From goodger@users.sourceforge.net Tue Mar 11 04:49:47 2003 From: goodger@users.sourceforge.net (goodger@users.sourceforge.net) Date: Mon, 10 Mar 2003 20:49:47 -0800 Subject: [Python-checkins] python/nondist/peps pep-0309.txt,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory sc8-pr-cvs1:/tmp/cvs-serv425 Modified Files: pep-0309.txt Log Message: update from Peter Harris, plus spell-check & edit Index: pep-0309.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0309.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pep-0309.txt 19 Feb 2003 00:46:51 -0000 1.2 --- pep-0309.txt 11 Mar 2003 04:49:44 -0000 1.3 *************** *** 9,31 **** Created: 08-Feb-2003 Python-Version: 2.4 ! Post-History: 10-Feb-2003 Abstract ! ========= ! This proposal is for a built-in closure or curry type for Python that ! allows a new callable to be constructed from another callable and a ! partial argument list (including positional and keyword arguments). A ! concise syntax shorthand for curried functions is suggested ! (tentatively). Note: after feedback on comp.lang.python, I am persuaded that the most ! accurate term for this is a 'curry', so the terminology has been ! amended since the first version of this PEP. Motivation ! =========== Curried functions are useful as functional 'sections' or as convenient --- 9,32 ---- Created: 08-Feb-2003 Python-Version: 2.4 ! Post-History: 10-Feb-2003, 27-Feb-2003 Abstract ! ======== ! This proposal is for a standard curry type for Python that ! allows a new callable to be constructed from a callable and a ! partial argument list (including positional and keyword arguments). Note: after feedback on comp.lang.python, I am persuaded that the most ! accurate term for this is a 'curry' rather than a 'closure', so the ! terminology has been amended since the first version of this PEP. ! ! I propose a standard library module called "functional", to hold useful ! higher-order functions, including the curry() class. Motivation ! ========== Curried functions are useful as functional 'sections' or as convenient *************** *** 50,54 **** Rationale ! ========== Here is one way to do a curry in Python:: --- 51,55 ---- Rationale ! ========= Here is one way to do a curry in Python:: *************** *** 60,65 **** def __call__(self, *args, **kw): ! d = self.kw.copy() ! d.update(kw) return self.fn(*(self.args + args), **d) --- 61,69 ---- def __call__(self, *args, **kw): ! if self.kw: ! d = self.kw.copy() ! d.update(kw) ! else: ! d = kw return self.fn(*(self.args + args), **d) *************** *** 79,93 **** http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549. - Tentative Syntax Proposal - ========================== ! I know syntax proposals have the odds stacked against them, and ! introducing new punctuation characters is frowned upon, but I think ! curries may be a sufficiently powerful abstraction to deserve it. ! I suggest the syntax ``fn@(*args, **kw)``, meaning the same as ! ``curry(fn, *args, **kw)``. I have no idea what havoc this would ! wreak on the parser. At least there are no backwards-compatibility issues because the @ --- 83,96 ---- http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549. + Update: It seems likely that a standard library implementation would + be in Python, and would have to prove its worth there before making + it into the built-ins. ! Abandoned Syntax Proposal ! ========================= ! I originally suggested the syntax ``fn@(*args, **kw)``, meaning the same ! as ``curry(fn, *args, **kw)``. At least there are no backwards-compatibility issues because the @ *************** *** 120,126 **** nextarg = sys.argv.pop@(0) Feedback from comp.lang.python ! =============================== Among the opinions voiced were the following (which I summarise): --- 123,132 ---- nextarg = sys.argv.pop@(0) + It has not been well-received, so I am not pursuing this as a serious + proposal. + Feedback from comp.lang.python ! ============================== Among the opinions voiced were the following (which I summarise): *************** *** 137,141 **** library. ! * It maybe isn't useful enough to be in the builtins. I agree that lambda is usually good enough, just not always. And I --- 143,155 ---- library. ! * It maybe isn't useful enough to be in the built-ins. ! ! * The idea of a module called ``functional`` was well received, and ! there are other things that belong there (for example function ! composition). ! ! * For completeness, another curry class that appends curried arguments ! after those supplied in the function call (maybe called ! ``rightcurry``) has been suggested. I agree that lambda is usually good enough, just not always. And I *************** *** 152,162 **** amended this PEP accordingly. - I think it's best as a builtin type rather than in a separate standard - library module, because it's simple and general enough. It may not be - an idiom that is very common in Python programming at the moment, but - I think that's because you have to code it yourself if you want it. - If added as a built-in feature, we would soon be wondering how we - managed without it. - Carl Banks posted an implementation as a real functional closure:: --- 166,169 ---- *************** *** 177,205 **** cdef class curry: cdef object fn, args, kw def __init__(self, fn, *args, **kw): self.fn=fn ! self.args=args ! self.kw = kw def __call__(self, *args, **kw): ! if self.kw: # from Python Cookbook version ! d = self.kw.copy() d.update(kw) ! else: ! d=kw return self.fn(*(self.args + args), **d) ! but I'm guessing that there would be minimal performance improvement ! since it compiles to a load of Python API calls. Summary ! ======== ! I maintain that curry should be a built-in, with the semantics as ! described, whether as a function or a class. The @ syntax proposal is withdrawn. --- 184,225 ---- cdef class curry: + cdef object fn, args, kw + def __init__(self, fn, *args, **kw): self.fn=fn ! self.args=args ! self.kw = kw def __call__(self, *args, **kw): ! if self.kw: # from Python Cookbook version ! d = self.kw.copy() d.update(kw) ! else: ! d=kw return self.fn(*(self.args + args), **d) ! The performance gain in Pyrex is less than 100% over the nested function ! implementation, since to be fully general it has to operate by Python API ! calls. Any C implementation will be unlikely to be much faster, so the ! case for a builtin coded in C is not very strong. ! Summary ! ======= ! I prefer that curry should be a built-in, with the semantics as ! described, whether as a function or a class. However, it should do its ! apprenticeship in the standard library first. ! ! The standard library module ``functional`` should contain ``curry`` and ! ``rightcurry`` classes, and any other higher-order functions the community ! want. These other functions fall outside this PEP though. The @ syntax proposal is withdrawn. + + Since this proposal is now much less ambitious, I'd like to aim for + inclusion in Python 2.3. From bwarsaw@users.sourceforge.net Tue Mar 11 05:03:27 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 21:03:27 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib emailmimebase.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv4137 Modified Files: emailmimebase.tex Log Message: For email 2.5b1, we no longer add a trailing newline to MIMEText.__init__()'s _text argument if it doesn't already end in a newline. This may be controversial. Index: emailmimebase.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailmimebase.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** emailmimebase.tex 1 Oct 2002 04:33:16 -0000 1.2 --- emailmimebase.tex 11 Mar 2003 05:03:25 -0000 1.3 *************** *** 152,157 **** character set of the text and is passed as a parameter to the \class{MIMENonMultipart} constructor; it defaults to \code{us-ascii}. No ! guessing or encoding is performed on the text data, but a newline is ! appended to \var{_text} if it doesn't already end with a newline. \deprecated{2.2.2}{The \var{_encoding} argument has been deprecated. --- 152,156 ---- character set of the text and is passed as a parameter to the \class{MIMENonMultipart} constructor; it defaults to \code{us-ascii}. No ! guessing or encoding is performed on the text data. \deprecated{2.2.2}{The \var{_encoding} argument has been deprecated. From bwarsaw@users.sourceforge.net Tue Mar 11 05:04:11 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 21:04:11 -0800 Subject: [Python-checkins] python/dist/src/Lib/email MIMEText.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv4392 Modified Files: MIMEText.py Log Message: __init__(): Don't add a newline to _text if it doesn't already end in one. Possibly controversial. Index: MIMEText.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/MIMEText.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** MIMEText.py 1 Oct 2002 00:52:27 -0000 1.7 --- MIMEText.py 11 Mar 2003 05:04:09 -0000 1.8 *************** *** 18,23 **** """Create a text/* type MIME document. ! _text is the string for this message object. If the text does not end ! in a newline, one is added. _subtype is the MIME sub content type, defaulting to "plain". --- 18,22 ---- """Create a text/* type MIME document. ! _text is the string for this message object. _subtype is the MIME sub content type, defaulting to "plain". *************** *** 36,41 **** MIMENonMultipart.__init__(self, 'text', _subtype, **{'charset': _charset}) - if _text and not _text.endswith('\n'): - _text += '\n' self.set_payload(_text, _charset) if _encoder is not None: --- 35,38 ---- From bwarsaw@users.sourceforge.net Tue Mar 11 05:04:56 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 21:04:56 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.43,1.44 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv4565 Modified Files: test_email.py Log Message: Adjust tests for no newline appending to MIMEText.__init__()'s _text argument. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** test_email.py 11 Mar 2003 04:31:37 -0000 1.43 --- test_email.py 11 Mar 2003 05:04:54 -0000 1.44 *************** *** 485,497 **** eq = self.assertEqual msg = MIMEText('hello world', _encoder=Encoders.encode_noop) ! eq(msg.get_payload(), 'hello world\n') def test_encode_7bit(self): eq = self.assertEqual msg = MIMEText('hello world', _encoder=Encoders.encode_7or8bit) ! eq(msg.get_payload(), 'hello world\n') eq(msg['content-transfer-encoding'], '7bit') msg = MIMEText('hello \x7f world', _encoder=Encoders.encode_7or8bit) ! eq(msg.get_payload(), 'hello \x7f world\n') eq(msg['content-transfer-encoding'], '7bit') --- 485,497 ---- eq = self.assertEqual msg = MIMEText('hello world', _encoder=Encoders.encode_noop) ! eq(msg.get_payload(), 'hello world') def test_encode_7bit(self): eq = self.assertEqual msg = MIMEText('hello world', _encoder=Encoders.encode_7or8bit) ! eq(msg.get_payload(), 'hello world') eq(msg['content-transfer-encoding'], '7bit') msg = MIMEText('hello \x7f world', _encoder=Encoders.encode_7or8bit) ! eq(msg.get_payload(), 'hello \x7f world') eq(msg['content-transfer-encoding'], '7bit') *************** *** 499,503 **** eq = self.assertEqual msg = MIMEText('hello \x80 world', _encoder=Encoders.encode_7or8bit) ! eq(msg.get_payload(), 'hello \x80 world\n') eq(msg['content-transfer-encoding'], '8bit') --- 499,503 ---- eq = self.assertEqual msg = MIMEText('hello \x80 world', _encoder=Encoders.encode_7or8bit) ! eq(msg.get_payload(), 'hello \x80 world') eq(msg['content-transfer-encoding'], '8bit') *************** *** 511,515 **** eq = self.assertEqual msg = MIMEText('hello world', _encoder=Encoders.encode_base64) ! eq(msg.get_payload(), 'aGVsbG8gd29ybGQK\n') eq(msg['content-transfer-encoding'], 'base64') --- 511,515 ---- eq = self.assertEqual msg = MIMEText('hello world', _encoder=Encoders.encode_base64) ! eq(msg.get_payload(), 'aGVsbG8gd29ybGQ=') eq(msg['content-transfer-encoding'], 'base64') *************** *** 517,521 **** eq = self.assertEqual msg = MIMEText('hello world', _encoder=Encoders.encode_quopri) ! eq(msg.get_payload(), 'hello=20world\n') eq(msg['content-transfer-encoding'], 'quoted-printable') --- 517,521 ---- eq = self.assertEqual msg = MIMEText('hello world', _encoder=Encoders.encode_quopri) ! eq(msg.get_payload(), 'hello=20world') eq(msg['content-transfer-encoding'], 'quoted-printable') *************** *** 1006,1010 **** def test_payload(self): ! self.assertEqual(self._msg.get_payload(), 'hello there\n') self.failUnless(not self._msg.is_multipart()) --- 1006,1010 ---- def test_payload(self): ! self.assertEqual(self._msg.get_payload(), 'hello there') self.failUnless(not self._msg.is_multipart()) *************** *** 1124,1128 **** hello world - --BOUNDARY-- ''') --- 1124,1127 ---- *************** *** 1152,1156 **** hello world - --BOUNDARY-- ''') --- 1151,1154 ---- *************** *** 1472,1476 **** One - --BOUNDARY Content-Type: text/plain; charset="us-ascii" --- 1470,1473 ---- *************** *** 1479,1483 **** Two - --BOUNDARY-- """) --- 1476,1479 ---- From bwarsaw@users.sourceforge.net Tue Mar 11 05:05:23 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 21:05:23 -0800 Subject: [Python-checkins] python/dist/src/Lib/email __init__.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv4757 Modified Files: __init__.py Log Message: beta 1 Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/__init__.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** __init__.py 30 Dec 2002 19:08:38 -0000 1.23 --- __init__.py 11 Mar 2003 05:05:21 -0000 1.24 *************** *** 5,9 **** """ ! __version__ = '2.5a1' __all__ = [ --- 5,9 ---- """ ! __version__ = '2.5b1' __all__ = [ From bwarsaw@users.sourceforge.net Tue Mar 11 05:10:48 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 10 Mar 2003 21:10:48 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test/data msg_21.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test/data In directory sc8-pr-cvs1:/tmp/cvs-serv6334 Modified Files: msg_21.txt Log Message: Adjust tests for no newline appending to MIMEText.__init__()'s _text argument. Index: msg_21.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/data/msg_21.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** msg_21.txt 19 Jul 2002 22:29:49 -0000 1.1 --- msg_21.txt 11 Mar 2003 05:10:46 -0000 1.2 *************** *** 11,15 **** One - --BOUNDARY Content-Type: text/plain; charset="us-ascii" --- 11,14 ---- *************** *** 18,22 **** Two - --BOUNDARY-- End of MIME message --- 17,20 ---- From jackjansen@users.sourceforge.net Tue Mar 11 14:37:26 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 11 Mar 2003 06:37:26 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac pimp.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv976 Modified Files: pimp.py Log Message: Patch by Andrew Straw: use urllib2 so proxie access works. Index: pimp.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/pimp.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** pimp.py 17 Feb 2003 12:21:05 -0000 1.12 --- pimp.py 11 Mar 2003 14:37:19 -0000 1.13 *************** *** 16,19 **** --- 16,20 ---- import os import urllib + import urllib2 import urlparse import plistlib *************** *** 50,58 **** ] - class MyURLopener(urllib.FancyURLopener): - """Like FancyURLOpener, but we do want to get errors as exceptions.""" - def http_error_default(self, url, fp, errcode, errmsg, headers): - urllib.URLopener.http_error_default(self, url, fp, errcode, errmsg, headers) - class PimpPreferences: """Container for per-user preferences, such as the database to use --- 51,54 ---- *************** *** 150,154 **** return self._urllist.append(url) ! fp = MyURLopener().open(url).fp dict = plistlib.Plist.fromFile(fp) # Test here for Pimp version, etc --- 146,150 ---- return self._urllist.append(url) ! fp = urllib2.urlopen(url).fp dict = plistlib.Plist.fromFile(fp) # Test here for Pimp version, etc *************** *** 799,801 **** main() ! \ No newline at end of file --- 795,797 ---- main() ! From gvanrossum@users.sourceforge.net Tue Mar 11 14:46:50 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Tue, 11 Mar 2003 06:46:50 -0800 Subject: [Python-checkins] python/dist/src/Lib/test regrtest.py,1.134,1.135 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv6900 Modified Files: regrtest.py Log Message: Add 'audio' resource. ALERT! A month ago or so I made test_ossaudiodev.py require the 'audio' resource, but I didn't make the necessary changes to regrtest.py. This means that *nobody* has been testing the oss module all that time! Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.134 retrieving revision 1.135 diff -C2 -d -r1.134 -r1.135 *** regrtest.py 7 Mar 2003 15:38:11 -0000 1.134 --- regrtest.py 11 Mar 2003 14:46:48 -0000 1.135 *************** *** 47,50 **** --- 47,54 ---- all - Enable all special resources. + audio - Tests that use the audio device. (There are known + cases of broken audio drivers that can crash Python or + even the Linux kernel.) + curses - Tests that use curses and will modify the terminal's state and output modes. *************** *** 102,106 **** from test import test_support ! RESOURCE_NAMES = ('curses', 'largefile', 'network', 'bsddb') --- 106,110 ---- from test import test_support ! RESOURCE_NAMES = ('audio', 'curses', 'largefile', 'network', 'bsddb') From gward@users.sourceforge.net Tue Mar 11 16:53:21 2003 From: gward@users.sourceforge.net (gward@users.sourceforge.net) Date: Tue, 11 Mar 2003 08:53:21 -0800 Subject: [Python-checkins] python/dist/src/Modules ossaudiodev.c,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv12830 Modified Files: ossaudiodev.c Log Message: Open with O_NONBLOCK to avoid hanging on open(). Index: ossaudiodev.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/ossaudiodev.c,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** ossaudiodev.c 10 Mar 2003 03:17:06 -0000 1.24 --- ossaudiodev.c 11 Mar 2003 16:53:13 -0000 1.25 *************** *** 132,136 **** } ! if ((fd = open(basedev, imode)) == -1) { PyErr_SetFromErrnoWithFilename(PyExc_IOError, basedev); return NULL; --- 132,140 ---- } ! /* Open with O_NONBLOCK to avoid hanging on devices that only allow ! one open at a time. This does *not* affect later I/O; OSS ! provides a special ioctl() for non-blocking read/write, which is ! exposed via oss_nonblock() below. */ ! if ((fd = open(basedev, imode|O_NONBLOCK)) == -1) { PyErr_SetFromErrnoWithFilename(PyExc_IOError, basedev); return NULL; From rhettinger@users.sourceforge.net Tue Mar 11 21:44:00 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue, 11 Mar 2003 13:44:00 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.693,1.694 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv23388 Modified Files: NEWS Log Message: Fix spelling. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.693 retrieving revision 1.694 diff -C2 -d -r1.693 -r1.694 *** NEWS 9 Mar 2003 05:33:32 -0000 1.693 --- NEWS 11 Mar 2003 21:43:55 -0000 1.694 *************** *** 248,252 **** an mmap'ed file which was already closed. (SF patch #665913) ! - Fixed serveral serious bugs in the zipimport implementation. - datetime changes: --- 248,252 ---- an mmap'ed file which was already closed. (SF patch #665913) ! - Fixed several serious bugs in the zipimport implementation. - datetime changes: *************** *** 622,626 **** Jython 2.1. ! - PEP 302 has been accepted. Although it was inititally developed to support zipimport, it offers a new, general import hook mechanism. Several new variables have been added to the sys module: --- 622,626 ---- Jython 2.1. ! - PEP 302 has been accepted. Although it was initially developed to support zipimport, it offers a new, general import hook mechanism. Several new variables have been added to the sys module: *************** *** 1024,1030 **** - unittest.py now has two additional methods called assertAlmostEqual() ! and failIfAlmostEqual(). They implement an approximate comparision by rounding the difference between the two arguments and comparing ! the result to zero. Approximate comparision is essential for unit tests of floating point results. --- 1024,1030 ---- - unittest.py now has two additional methods called assertAlmostEqual() ! and failIfAlmostEqual(). They implement an approximate comparison by rounding the difference between the two arguments and comparing ! the result to zero. Approximate comparison is essential for unit tests of floating point results. *************** *** 1042,1046 **** test the current module. ! - When cancelling a server that implemented threading with a keyboard interrupt, the server would shut down but not terminate (waiting on client threads). A new member variable, daemon_threads, was added to --- 1042,1046 ---- test the current module. ! - When canceling a server that implemented threading with a keyboard interrupt, the server would shut down but not terminate (waiting on client threads). A new member variable, daemon_threads, was added to *************** *** 1403,1407 **** incremented. The apparently unused feature of "indirect interned strings", supported by the ob_sinterned member, is gone. Interned ! strings are now usually mortal; theres a new API, PyString_InternImmortal() that creates immortal interned strings. (The ob_sstate member can only take three values; however, while --- 1403,1407 ---- incremented. The apparently unused feature of "indirect interned strings", supported by the ob_sinterned member, is gone. Interned ! strings are now usually mortal; there is a new API, PyString_InternImmortal() that creates immortal interned strings. (The ob_sstate member can only take three values; however, while *************** *** 1495,1499 **** bugs. XXX What are the licensing issues here? ! XXX If a user has a database created with a previous verion of XXX Python, what must they do to convert it? XXX I'm still not sure how to link this thing (see PCbuild/readme.txt). --- 1495,1499 ---- bugs. XXX What are the licensing issues here? ! XXX If a user has a database created with a previous version of XXX Python, what must they do to convert it? XXX I'm still not sure how to link this thing (see PCbuild/readme.txt). *************** *** 1508,1512 **** - When Python is built under a Microsoft compiler, sys.version now includes the compiler version number (_MSC_VER). For example, under ! MSVC 6, sys.version constains the substring "MSC v.1200 ". 1200 is the value of _MSC_VER under MSVC 6. --- 1508,1512 ---- - When Python is built under a Microsoft compiler, sys.version now includes the compiler version number (_MSC_VER). For example, under ! MSVC 6, sys.version contains the substring "MSC v.1200 ". 1200 is the value of _MSC_VER under MSVC 6. *************** *** 1613,1617 **** (and Apple's Carbon and Cocoa documentation) through the Help Viewer. See Mac/OSX/README for converting the Python documentation to a ! Help Viewer comaptible form and installing it. - OSA support has been redesigned and the generated Python classes now --- 1613,1617 ---- (and Apple's Carbon and Cocoa documentation) through the Help Viewer. See Mac/OSX/README for converting the Python documentation to a ! Help Viewer compatible form and installing it. - OSA support has been redesigned and the generated Python classes now *************** *** 2176,2180 **** 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 --- 2176,2180 ---- module). ! Note that Profile.calibrate() must be overridden by subclasses. Improving the accuracy required exploiting detailed knowledge of profiler internals; the earlier method abstracted away the details From jackjansen@users.sourceforge.net Tue Mar 11 21:48:58 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 11 Mar 2003 13:48:58 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_macfs.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv25603/Lib/test Modified Files: test_macfs.py Log Message: Allow unicode pathnames where FSRefs are expected. Fixes 696253. Index: test_macfs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_macfs.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_macfs.py 19 Feb 2003 02:35:05 -0000 1.3 --- test_macfs.py 11 Mar 2003 21:48:55 -0000 1.4 *************** *** 27,30 **** --- 27,35 ---- fsr = macfs.FSRef(test_support.TESTFN) self.assertEqual(os.path.realpath(test_support.TESTFN), fsr.as_pathname()) + + def test_fsref_unicode(self): + testfn_unicode = unicode(test_support.TESTFN) + fsr = macfs.FSRef(testfn_unicode) + self.assertEqual(os.path.realpath(test_support.TESTFN), fsr.as_pathname()) def test_coercion(self): From jackjansen@users.sourceforge.net Tue Mar 11 21:49:00 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 11 Mar 2003 13:49:00 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules/file _Filemodule.c,1.17,1.18 filesupport.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/file In directory sc8-pr-cvs1:/tmp/cvs-serv25603/Mac/Modules/file Modified Files: _Filemodule.c filesupport.py Log Message: Allow unicode pathnames where FSRefs are expected. Fixes 696253. Index: _Filemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/_Filemodule.c,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** _Filemodule.c 2 Feb 2003 23:00:19 -0000 1.17 --- _Filemodule.c 11 Mar 2003 21:48:56 -0000 1.18 *************** *** 3223,3228 **** #if TARGET_API_MAC_OSX /* On OSX we now try a pathname */ ! if ( PyString_Check(v) ) { ! if ( (err=FSPathMakeRef(PyString_AsString(v), fsr, NULL)) ) { PyMac_Error(err); return 0; --- 3223,3231 ---- #if TARGET_API_MAC_OSX /* On OSX we now try a pathname */ ! if ( PyString_Check(v) || PyUnicode_Check(v)) { ! char *path = NULL; ! if (!PyArg_Parse(v, "et", Py_FileSystemDefaultEncoding, &path)) ! return NULL; ! if ( (err=FSPathMakeRef(path, fsr, NULL)) ) { PyMac_Error(err); return 0; Index: filesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/file/filesupport.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** filesupport.py 28 Jan 2003 23:29:46 -0000 1.15 --- filesupport.py 11 Mar 2003 21:48:57 -0000 1.16 *************** *** 281,286 **** #if TARGET_API_MAC_OSX /* On OSX we now try a pathname */ ! if ( PyString_Check(v) ) { ! if ( (err=FSPathMakeRef(PyString_AsString(v), fsr, NULL)) ) { PyMac_Error(err); return 0; --- 281,289 ---- #if TARGET_API_MAC_OSX /* On OSX we now try a pathname */ ! if ( PyString_Check(v) || PyUnicode_Check(v)) { ! char *path = NULL; ! if (!PyArg_Parse(v, "et", Py_FileSystemDefaultEncoding, &path)) ! return NULL; ! if ( (err=FSPathMakeRef(path, fsr, NULL)) ) { PyMac_Error(err); return 0; From jackjansen@users.sourceforge.net Tue Mar 11 21:50:27 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 11 Mar 2003 13:50:27 -0800 Subject: [Python-checkins] python/dist/src/Mac/Demo plugins.html,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Demo In directory sc8-pr-cvs1:/tmp/cvs-serv26687/Mac/Demo Modified Files: plugins.html Log Message: This file was terribly outdated. The example is still silly (and won't work), but at least the rest of the text is okay now. Index: plugins.html =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Demo/plugins.html,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** plugins.html 25 Feb 1998 15:40:24 -0000 1.3 --- plugins.html 11 Mar 2003 21:50:21 -0000 1.4 *************** *** 8,12 **** to interface to the programmers' API of InterSLIP, a package that allows you to use MacTCP (and, hence, all internet services) over a ! modem connection.

Prerequisites

--- 8,14 ---- to interface to the programmers' API of InterSLIP, a package that allows you to use MacTCP (and, hence, all internet services) over a ! modem connection. The actual example does not work anymore, as both ! MacTCP and Interslip died long ago, but the text is still mostly ! correct.

Prerequisites

*************** *** 15,20 **** you need a C development environment. Actually, you need a specific development environment, CodeWarrior by MetroWerks. You will probably ! need the latest version. You may be able to get by with an older version of CodeWarrior or with another development environment (Up to about 1994 python was developed with THINK C, and in the dim past it --- 17,22 ---- you need a C development environment. Actually, you need a specific development environment, CodeWarrior by MetroWerks. You will ! need Version 7 or later. You may be able to get by with an older version of CodeWarrior or with another development environment (Up to about 1994 python was developed with THINK C, and in the dim past it *************** *** 23,33 **** character of this document will be lost.

! Next, you need a python source ! distribution. For PowerPC and cfm68k development you can actually ! get by without a full source distribution, using the Development ! distribution. You'll also need a functional python interpreter, and ! the Modulator program (which lives in Tools:Modulator in ! the standard source distribution). You may also find that Guido's Extending and embedding the Python interpreter is a very handy piece of documentation. I --- 25,30 ---- character of this document will be lost.

! Next, you need to install the Developer option in the MacPython installer. ! You may also find that Guido's Extending and embedding the Python interpreter is a very handy piece of documentation. I *************** *** 156,223 **** way...

-

Adding a module to Classic 68K Python

- - What you do now depends on whether you're developing for PowerPC (or - for CFM68K) or for "traditional" mac. For a traditional 68K Python, - you will have to add your new module to the project file of the Python - interpreter, and you have to edit "config.c" to add the module to the - set of builtin modules. In config.c you will add the module at two - places: near the start of the file there is a list of external - declarations for all init() routines. Add a line of the form -
- 		extern void initinterslip();
- 
- here. Further down the file there is an array that is initialized with - modulename/initfunction pairs. Add a line of the form -
- 		{"interslip",	initinterslip},
- 
- here. You may want to bracket these two lines with -
- 	#ifdef USE_INTERSLIP
- 	#endif
- 
- lines, that way you can easily control whether the module is - incorporated into python at compile time. If you decide to do the - latter edit your config file (you can find the name in the "C/C++ - language" section of the MW preferences dialog, it will probably be - "mwerks_nonshared_config.h") and add a -
- 	#define USE_INTERSLIP
- 
- - Make the new interpreter and check that you can import the module, see - the methods (with "dir(interslip)") and call them.

-

Creating a plugin module

! For PowerPC or cfm68k development you could follow the same path, but it is ! actually a better idea to use a dynamically loadable module. The ! advantage of dynamically loadable modules is that they are not loaded ! until a python program actually uses them (resulting in less memory ! usage by the interpreter) and that development is a lot simpler (since ! your projects will all be smaller). Moreover, you can distribute a ! plugin module by itself without haveing to distribute a complete ! python interpreter.

! Go to the "PlugIns" folder and copy the files xx.prj, ! and xx.prj.exp to interslipmodule.prj and ! interslipmodule.prj.exp, respectively. Edit ! interslipmodule.prj.exp and change the name of the exported routine ! "initxx" to "initinterslip". Open interslipmodule.prj with CodeWarrior, remove the file xxmodule.c and add interslipmodule.c and make a number of adjustments to the preferences:

    !
  • in PPC target, set the output file name to "interslipmodule.pcc.slb", !
  • in cfm68k target set the output file name to "interslipmodule.cfm68k.slb".
  • if you are working without a source distribution (i.e. with a normal binary distribution plus a development distribution) you will not have ! a file PythonCore. The installation process has deposited this file in the System Extensions folder under the name ! PythonCore version. Add that file to the project, replacing ! PythonCore.
! Next, compile and link your module, fire up python and do the same ! tests as for 68K python.

Getting the module to do real work

--- 153,186 ---- way...

Creating a plugin module

! The easiest way to build a plugin module is to use the distutils package, ! this works fine on MacOS with CodeWarrior. See the distutils documentation ! for details. Keep in mind that even though you are on the Mac you specify ! filenames with Unix syntax: they are actually URLs, not filenames. !

! Alternatively you can build the project file by hand. ! Go to the ":Mac:Build" folder and copy the files xx.carbon.mcp, ! and xx.carbon.mcp.exp to interslipmodule.carbon.mcp and ! interslipmodule.carbon.mcp.exp, respectively. Edit ! interslipmodule.carbon.mcp.exp and change the name of the exported routine ! "initxx" to "initinterslip". Open interslipmodule.carbon.mcp with CodeWarrior, remove the file xxmodule.c and add interslipmodule.c and make a number of adjustments to the preferences:

    !
  • in PPC target, set the output file name to "interslipmodule.carbon.slb",
  • if you are working without a source distribution (i.e. with a normal binary distribution plus a development distribution) you will not have ! a file PythonCoreCarbon. The installation process has deposited this file in the System Extensions folder under the name ! PythonCoreCarbon version. Add that file to the project, replacing ! PythonCoreCarbon. !
  • you must either download and build GUSI (if your extension module uses sockets ! or other Unix I/O constructs) or remove GUSI references from the Access Paths ! settings. See the Building document for where to get GUSI ! and how to build it.
! Next, compile and link your module, fire up python and test it.

Getting the module to do real work

From jackjansen@users.sourceforge.net Tue Mar 11 22:48:39 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 11 Mar 2003 14:48:39 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation In directory sc8-pr-cvs1:/tmp/cvs-serv20021/Documentation Log Message: Directory /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation added to the repository From jackjansen@users.sourceforge.net Tue Mar 11 22:56:43 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 11 Mar 2003 14:56:43 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation/macpython_ide_tutorial - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation/macpython_ide_tutorial In directory sc8-pr-cvs1:/tmp/cvs-serv22882/macpython_ide_tutorial Log Message: Directory /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation/macpython_ide_tutorial added to the repository From jackjansen@users.sourceforge.net Tue Mar 11 22:56:43 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 11 Mar 2003 14:56:43 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation/doc - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation/doc In directory sc8-pr-cvs1:/tmp/cvs-serv22882/doc Log Message: Directory /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation/doc added to the repository From jackjansen@users.sourceforge.net Tue Mar 11 22:59:19 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 11 Mar 2003 14:59:19 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation/doc index.html,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation/doc In directory sc8-pr-cvs1:/tmp/cvs-serv23138/doc Added Files: index.html Log Message: Adding MacPython online help. Only the basics are installed, with a placeholder for the full documentation (pointing to the online docs and explaining you can also install them locally to make them searchable, etc). --- NEW FILE: index.html --- Python Language Documentation

Python Language and runtime documentation

This volume of documentation is rather big (17 Megabytes) and contains a tutorial, full description of the Python library (all the modules and packages included), formal description of the language and more.

You can view it online, where you can also download PDFs for printing, or you can download and install it through the Package Manager for viewing and searching via Apple Help Viewer.

From jackjansen@users.sourceforge.net Tue Mar 11 22:59:19 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 11 Mar 2003 14:59:19 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation PackageManager.gif,NONE,1.1 finder.html,NONE,1.1 index.html,NONE,1.1 intro.html,NONE,1.1 packman.html,NONE,1.1 python.gif,NONE,1.1 pythonsmall.gif,NONE,1.1 shell.html,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation In directory sc8-pr-cvs1:/tmp/cvs-serv23138 Added Files: PackageManager.gif finder.html index.html intro.html packman.html python.gif pythonsmall.gif shell.html Log Message: Adding MacPython online help. Only the basics are installed, with a placeholder for the full documentation (pointing to the online docs and explaining you can also install them locally to make them searchable, etc). --- NEW FILE: PackageManager.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: finder.html --- Python and the Finder

Running Python scripts from the Finder

The application PythonLauncher will start a Python interpreter when you drop a Python source file onto it, any file with a .py or .pyw extension. If you set PythonLauncher as the default application to open a file ( tell me more) this also works when you double click a Python script.

PythonLauncher has preferences per filetype for selecting the interpreter to use, and how to launch it: in a Terminal window or not, etc. Holding the Option key while launching your script will bring up a window that allows changing these settings for a single run.


--- NEW FILE: index.html --- MacPython Help

MacPython Help

Choose a topic, or enter keywords into the search field:


--- NEW FILE: intro.html --- What is MacPython?

What is MacPython?

Python is a programming language. MacPython is a package containing that programming language plus Mac-specific tools and extensions.


The Python Language

The Python programming language is available for many hardware platforms, and most general documentation is Unix- or Windows-centered. Keep this in mind when reading the rest of this help, or information on the web.

The Python website, www.python.org, has a Beginners Guide section including an executive summary on the language and a comparison of Python to other languages. Or read the (rather longwinded) Python Tutorial in the Python Language and runtime documentation.

MacPython contains a complete unix interpreter so if you are familiar with Python on unix you should feel right at home.

MacPython additions

The MacPython Integrated Development Environment (IDE) allows easy editing, running and debugging of scripts. Read the Introduction to the IDE to whet your appetite.

MacPython comes with lots of modules that allow access to MacOS-specific technology, such as Carbon, Quicktime and AppleScript. See the Macintosh Modules section of the Python Language and runtime documentation, but please keep in mind that some information there still pertains to Mac OS 9. Full access to the Cocoa APIs and tools such as Interface Builder is available separately through the Package Manager.

The Package Manager also gives you access to extension packages for cross-platform GUI development (Tkinter, wxPython, PyOpenGL), image processing (PIL), scientific computing (Numeric) and much more. PyObjC deserves a special mention: it allows transparent access to Cocoa and Interface Builder, similar to what Java provides, thereby making Python a first class citizen in the Mac OS X developer world.

Python scripts can be saved as applets, semi-standalone applications that work just like a normal application. Additionally you can even create true standalone application that have everything embedded and can be shipped to anyone, without the need to install Python. You do not need to install the Apple Developer Tools for this.

--- NEW FILE: packman.html --- Python Package Manager

Installing additional Python Packages

The Python Package Manager helps you installing additional packages that enhance Python. It determines the exact MacOS version and Python version you have and uses that information to download a database that has packages that are test and tried on that combination. In other words: if something is in your Package Manager window but does not work you are free to blame the database maintainer.

PackageManager then checks which of the packages you have installed and which ones not. This should also work when you have installed packages outside of PackageManager. You can select packages and install them, and PackageManager will work out the requirements and install these too.

Often PackageManager will list a package in two flavors: binary and source. Binary should always work, source will only work if you have installed the Apple Developer Tools. PackageManager will warn you about this, and also about other external dependencies.

PackageManager is available as a separate application and also as a function of the IDE, through the File->Package Manager menu entry.


--- NEW FILE: python.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: pythonsmall.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: shell.html --- Python and the Unix Shell

Running Python scripts from the Unix Shell

MacPython 2.3 installs a perfectly normal Unix commandline python interpreter in /usr/local/bin/python. As of Mac OS X 10.2, however, /usr/local/bin is not on the search path of your shell. Moreover, Apple's python 2.2, which lives in /usr/bin is on your search path, so this can lead to confusion.

If you use tcsh you should add the following line to the file .login in your home directory and restart Terminal:
setenv PATH /usr/local/bin:$PATH

If you use bash or zsh you should add the following line to the file .profile in your home directory and restart Terminal:
export PATH=/usr/local/bin:$PATH

GUI scripts

Due to the way MacOS handles windowing applications you need to run all scripts that use the window manager (be it through Carbon, Cocoa, Tkinter, wxPython, PyOpenGL or anything else) with the pythonw interpreter, also installed in /usr/local/bin.

Running with python results in an inability to bring the script to the front, or interacting with it.


From jackjansen@users.sourceforge.net Tue Mar 11 22:59:28 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 11 Mar 2003 14:59:28 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation/macpython_ide_tutorial IDE.gif,NONE,1.1 entering_in_new_window.gif,NONE,1.1 hello_world.gif,NONE,1.1 index.html,NONE,1.1 loading_ide.gif,NONE,1.1 making_new_window.gif,NONE,1.1 new_ide_window.gif,NONE,1.1 new_window_made.gif,NONE,1.1 output_window.gif,NONE,1.1 saving_edited_file.gif,NONE,1.1 simple_commands.gif,NONE,1.1 syntax_error.gif,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation/macpython_ide_tutorial In directory sc8-pr-cvs1:/tmp/cvs-serv23138/macpython_ide_tutorial Added Files: IDE.gif entering_in_new_window.gif hello_world.gif index.html loading_ide.gif making_new_window.gif new_ide_window.gif new_window_made.gif output_window.gif saving_edited_file.gif simple_commands.gif syntax_error.gif Log Message: Adding MacPython online help. Only the basics are installed, with a placeholder for the full documentation (pointing to the online docs and explaining you can also install them locally to make them searchable, etc). --- NEW FILE: IDE.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: entering_in_new_window.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: hello_world.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: index.html --- One Day of MacPython IDE Toying

One Day of MacPython IDE Toying

This document gives a very basic introduction to the MacPython Integrated Development Environment on Mac OS. It was written specifically for MacPython 2.3 on Mac OS X, but most of it is applicable to MacPython-OS9 too. It is based on "One Day of IDLE Toying" by Danny Yoo, which you should read if you want to use the cross-platform IDLE Python development environment.



Ok, let's assume that we've already installed Python. (If not, we can visit: http://www.cwi.nl/~jack/macpython.html or http://python.org and download the most recent Python interpreter. Get the Mac OSX binary installer.) The first thing we'd like to do is actually start running it! We can do this by opening up the IDE, which should be in Applications under the newly-created MacPython program folder:



The IDE starts up and shows an interactive window:

If the window does not show up (because you have run the IDE before and closed it: it remembers that between runs) open it with the Windows->Python Interactive menu entry.

This is the interactive window to the IDE, it allows us to enter commands directly into Python, and as soon as we enter a command, Python will execute it and spit out its result back to us. We'll be using this interactive window a lot when we're exploring Python: it's very nice because we get back our results immediately. If it helps, we can think of it as a very powerful calculator.



Let's try something now! As per tradition, let's get Python to say the immortal words, "Hello World".

Those '>>>' signs act as a prompt for us: Python is ready to read in a new command by giving us that visual cue. Also, we notice that as we enter commands, Python will give us its output immediately.



Ok, this seems pretty simple enough. Let's try a few more commands. If we look below:

we'll see the result of running a few more commands. Don't worry too much about knowing the exact rules for making programs yet: the idea is that we can experiment with Python by typing in commands. If things don't work, then we can correct the mistake, and try it again.

If you got to this point, you now know enough to start playing around with Python! Crack open one of the tutorials from the Python For Beginners web page, and start exploring with the interpreter. No time limit here. *grin*



Now that we've paddled long enough, we might be asking: ok, this is neat, but if we close down Python and start it up again, how do we get the computer to remember what we typed?

The solution is a little subtle: we can't directly save what's on the interpreter window, because it will include both our commands and the system's responses. What we'd like is to make a prepared file, with just our own commands, and to be able to save that file as a document. When we're in the mood, we can later open that file and "run" Python over it, saving us the time of retyping the whole thing over again.

Let's try this. First, let's start with a clean slate by opening up a new window.

Here's the result of that menu command:

We notice that there's nothing in this new window. What this means is that this file is purely for our commands: Python won't interject with its own responses as we enter the program, that is, not until we tell it to. This is called an edit window, and it is very similar to edit windows in other editors such as TextEdit or BBEdit.



What we wanted to do before was save some of the stuff we had tried out on the interpreter window. Let's do that by typing (or copy/pasting) those commands into our Program window.

Ok, we're done with copying and pasting. One big thing to notice is that we're careful to get rid of the ">>>" prompts because there's not really part of our program. The interpreter uses them just to tell us that we're in the interpreter, but now that we're editing in a separate file, we can remove the artifacts that the interpreter introduces. I have added an extra empty print statement so our output ends with a newline.



Let's save the file now. The Save command is located under the File menu:



Now that we've saved the program, how do we run the program? Use the Run All button at the top of the editing window, or the equivalent menu command Python->Run Window. The output will appear in a new window called Output Window.

By the way, one thing to notice is that I made a typo: I didn't quite copy exactly what I had entered in the interpreter window before. Does this affect things?

Ooops. Here is an example of what Python calls a "syntax error". Python sees that we made a typo, and warns us to take a much closer look at our program. The designers of Python feel that having the system point out the error is better than trying to guess at what the programmer meant. Press the Edit button and you will be brought to the trouble spot.

Python is often perceptive enough to direct us toward the problem, and in this case, it's telling us that we forgot to put something at the end of this line. In this case, we need to add an additional quotation mark. Let's add that in now.

Other errors, which usually occur later, when your program has already done something, result in a different dialog that allows you to look at variables and such in addition to only showing you where the error occurred.



Ok, let's say that we fixed that silly typo. Let's try to run the program again. This gives us a new window, the Output window, showing the output of our program:



As we play with Python, we'll find ourselves "switching modes" between the Interpreter window and the Program window. However, if we try anything more complicated than two or three lines it is often a good idea to work in an edit window, and align your edit and output window such that you can see them at the same time.

This is pretty much all we need to know about the MacPython IDE to actually do interesting things. There is a lot more to the IDE, here is a quick breakdown of things to see and explore:

  • All sorts of edit commands such as find and replace can be used in the editor windows. See the edit menu.
  • The bottom of the edit window has the scrollbar, but at the left are two navigation devices: a line number box that you can also type numbers into to quickly go to a specific place, and a popup menu that lists all classes, functions and methods in your file.
  • Above the vertical scrollbar you find another popup menu, this influences how the Run command works. You should try the debugger some time! If you do, and you wonder what the new small column on the left of your script is: you can click in it to make Python stop when it reaches this line so you can inspect things. The profiler is also nifty: it shows you where your program is spending its time.
  • The module browser (Python->Module Browser) shows you all Python modules currently loaded. You can look at the contents of the module with Browse... and (for modules written in Python) at the source with Source...
  • The Package Manager (under the File menu, also available as a separate application) allows you to easily install Python extension packages for all sorts of things: scientific computation, image processing, building user interfaces and more.
  • The Help menu gives you quick access to both the Python documentation, if you have installed it with the Package Manager, and the Apple Developer documentation.
  • The File->Save as Applet menu command saves your script as a MacOSX application. This allows you to create a script that you can drop files on, and much more. The IDE itself is such an applet, completely written in Python.
--- NEW FILE: loading_ide.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: making_new_window.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: new_ide_window.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: new_window_made.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: output_window.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: saving_edited_file.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: simple_commands.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: syntax_error.gif --- (This appears to be a binary file; contents omitted.) From jackjansen@users.sourceforge.net Tue Mar 11 23:07:12 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Tue, 11 Mar 2003 15:07:12 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSX Makefile,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSX In directory sc8-pr-cvs1:/tmp/cvs-serv26015 Modified Files: Makefile Log Message: Add a simple Apple Help book to the framework. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/OSX/Makefile,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** Makefile 25 Feb 2003 12:41:10 -0000 1.37 --- Makefile 11 Mar 2003 23:07:08 -0000 1.38 *************** *** 44,48 **** APPTEMPLATE=$(srcdir)/Mac/OSXResources/app ! APPSUBDIRS=MacOS Resources Resources/English.lproj CACHERSRC=$(srcdir)/Mac/scripts/cachersrc.py compileall=$(srcdir)/Lib/compileall.py --- 44,53 ---- APPTEMPLATE=$(srcdir)/Mac/OSXResources/app ! APPSUBDIRS=MacOS Resources Resources/English.lproj \ ! Resources/English.lproj/Documentation \ ! Resources/English.lproj/Documentation/doc \ ! Resources/English.lproj/Documentation/macpython_ide_tutorial ! DOCDIR=$(srcdir)/Mac/OSXResources/app/Resources/English.lproj/Documentation ! DOCINDEX=$(DOCDIR)/"Documentation idx" CACHERSRC=$(srcdir)/Mac/scripts/cachersrc.py compileall=$(srcdir)/Lib/compileall.py *************** *** 58,61 **** --- 63,69 ---- install_Python: + @if test ! -f $(DOCINDEX); then \ + echo WARNING: you should run Apple Help Indexing Tool on $(DOCDIR); \ + fi @for i in $(PYTHONAPPSDIR) $(APPINSTALLDIR) $(APPINSTALLDIR)/Contents; do \ if test ! -d $$i; then \ *************** *** 83,86 **** --- 91,98 ---- *.orig) ;; \ *~) ;; \ + *idx) \ + echo $(CPMAC) "$$i" $$b; \ + $(CPMAC) "$$i" $$b; \ + ;; \ *) \ if test -d $$i; then continue; fi; \ *************** *** 95,102 **** done; \ done ! $(INSTALL_PROGRAM) $(STRIPFLAG) $(BUILDPYTHON) $(APPINSTALLDIR)/Contents/MacOS/python ! # Finally create the documentation symlink ! $(LN) -fsn ../../../../English.lproj/Documentation $(APPINSTALLDIR)/Contents/Resources/English.lproj/Documentation ! install_IDE: $(INSTALLED_PYTHONW) --- 107,111 ---- done; \ done ! $(INSTALL_PROGRAM) $(STRIPFLAG) $(BUILDPYTHON) $(APPINSTALLDIR)/Contents/MacOS/python install_IDE: $(INSTALLED_PYTHONW) From bwarsaw@users.sourceforge.net Wed Mar 12 02:54:20 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 11 Mar 2003 18:54:20 -0800 Subject: [Python-checkins] python/dist/src/Lib/email _compat21.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv9438 Modified Files: _compat21.py Log Message: Python 2.1 doesn't have True and False Index: _compat21.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/_compat21.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** _compat21.py 11 Mar 2003 04:41:18 -0000 1.6 --- _compat21.py 12 Mar 2003 02:54:17 -0000 1.7 *************** *** 8,11 **** --- 8,14 ---- from types import StringType, UnicodeType + False = 0 + True = 1 + From bwarsaw@users.sourceforge.net Wed Mar 12 03:14:15 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 11 Mar 2003 19:14:15 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.44,1.45 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv15432 Modified Files: test_email.py Log Message: test_whitespace_eater_unicode(): Make this test Python 2.1 compatible. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** test_email.py 11 Mar 2003 05:04:54 -0000 1.44 --- test_email.py 12 Mar 2003 03:14:11 -0000 1.45 *************** *** 1289,1293 **** dh = decode_header(s) eq(dh, [('Andr\xe9', 'iso-8859-1'), ('Pirard ', None)]) ! hu = unicode(make_header(dh)).encode('latin-1') eq(hu, 'Andr\xe9 Pirard ') --- 1289,1296 ---- dh = decode_header(s) eq(dh, [('Andr\xe9', 'iso-8859-1'), ('Pirard ', None)]) ! # Python 2.1's unicode() builtin doesn't call the object's ! # __unicode__() method. Use the following alternative instead. ! #hu = unicode(make_header(dh)).encode('latin-1') ! hu = make_header(dh).__unicode__().encode('latin-1') eq(hu, 'Andr\xe9 Pirard ') From bwarsaw@users.sourceforge.net Wed Mar 12 03:43:12 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Tue, 11 Mar 2003 19:43:12 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib mimelib.tex,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv24071 Modified Files: mimelib.tex Log Message: Update the package version number Index: mimelib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/mimelib.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** mimelib.tex 10 Oct 2002 15:58:19 -0000 1.4 --- mimelib.tex 12 Mar 2003 03:43:09 -0000 1.5 *************** *** 13,19 **** \date{\today} ! \release{2.4.2} % software release, not documentation \setreleaseinfo{} % empty for final release ! \setshortversion{2.4} % major.minor only for software \begin{document} --- 13,19 ---- \date{\today} ! \release{2.5b1} % software release, not documentation \setreleaseinfo{} % empty for final release ! \setshortversion{2.5} % major.minor only for software \begin{document} From rhettinger@users.sourceforge.net Wed Mar 12 04:25:44 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue, 11 Mar 2003 20:25:44 -0800 Subject: [Python-checkins] python/dist/src/Objects typeobject.c,2.215,2.216 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv4713/Objects Modified Files: typeobject.c Log Message: SF bug #699934: Obscure error message Clarify error message for mro conflicts. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.215 retrieving revision 2.216 diff -C2 -d -r2.215 -r2.216 *** typeobject.c 7 Mar 2003 15:13:17 -0000 2.215 --- typeobject.c 12 Mar 2003 04:25:42 -0000 2.216 *************** *** 1077,1081 **** n = PyDict_Size(set); ! off = PyOS_snprintf(buf, sizeof(buf), "MRO conflict among bases"); i = 0; while (PyDict_Next(set, &i, &k, &v) && off < sizeof(buf)) { --- 1077,1084 ---- n = PyDict_Size(set); ! off = PyOS_snprintf(buf, sizeof(buf), "Cannot create class.\ ! The superclasses have conflicting\n\ ! inheritance trees which leave the method resolution order (MRO)\n\ ! undefined for bases"); i = 0; while (PyDict_Next(set, &i, &k, &v) && off < sizeof(buf)) { From rhettinger@users.sourceforge.net Wed Mar 12 04:25:44 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue, 11 Mar 2003 20:25:44 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_descr.py,1.186,1.187 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv4713/Lib/test Modified Files: test_descr.py Log Message: SF bug #699934: Obscure error message Clarify error message for mro conflicts. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.186 retrieving revision 1.187 diff -C2 -d -r1.186 -r1.187 *** test_descr.py 27 Feb 2003 20:04:19 -0000 1.186 --- test_descr.py 12 Mar 2003 04:25:42 -0000 1.187 *************** *** 1063,1066 **** --- 1063,1070 ---- Pane, ScrollingMixin, EditingMixin, object)) + mro_err_msg = """Cannot create class.The superclasses have conflicting + inheritance trees which leave the method resolution order (MRO) + undefined for bases """ + def mro_disagreement(): if verbose: print "Testing error messages for MRO disagreement..." *************** *** 1080,1086 **** raises(TypeError, "duplicate base class A", type, "X", (A, A), {}) ! raises(TypeError, "MRO conflict among bases ", type, "X", (A, B), {}) ! raises(TypeError, "MRO conflict among bases ", type, "X", (A, C, B), {}) # Test a slightly more complex error --- 1084,1090 ---- raises(TypeError, "duplicate base class A", type, "X", (A, A), {}) ! raises(TypeError, mro_err_msg, type, "X", (A, B), {}) ! raises(TypeError, mro_err_msg, type, "X", (A, C, B), {}) # Test a slightly more complex error *************** *** 1090,1094 **** class HVGrid(HorizontalGrid, VerticalGrid): pass class VHGrid(VerticalGrid, HorizontalGrid): pass ! raises(TypeError, "MRO conflict among bases ", type, "ConfusedGrid", (HVGrid, VHGrid), {}) --- 1094,1098 ---- class HVGrid(HorizontalGrid, VerticalGrid): pass class VHGrid(VerticalGrid, HorizontalGrid): pass ! raises(TypeError, mro_err_msg, type, "ConfusedGrid", (HVGrid, VHGrid), {}) From rhettinger@users.sourceforge.net Wed Mar 12 04:46:54 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Tue, 11 Mar 2003 20:46:54 -0800 Subject: [Python-checkins] python/dist/src/Doc/tut tut.tex,1.177,1.178 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory sc8-pr-cvs1:/tmp/cvs-serv10667 Modified Files: tut.tex Log Message: SF bug #699237: Tutorial uses omitted slice indices before explaining them Moved up the explanation of slice default arguments. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.177 retrieving revision 1.178 diff -C2 -d -r1.177 -r1.178 *** tut.tex 1 Mar 2003 03:20:39 -0000 1.177 --- tut.tex 12 Mar 2003 04:46:52 -0000 1.178 *************** *** 641,644 **** --- 641,655 ---- \end{verbatim} + Slice indices have useful defaults; an omitted first index defaults to + zero, an omitted second index defaults to the size of the string being + sliced. + + \begin{verbatim} + >>> word[:2] # The first two characters + 'He' + >>> word[2:] # All but the first two characters + 'lpA' + \end{verbatim} + Unlike a C string, Python strings cannot be changed. Assigning to an indexed position in the string results in an error: *************** *** 663,677 **** >>> 'Splat' + word[4] 'SplatA' - \end{verbatim} - - Slice indices have useful defaults; an omitted first index defaults to - zero, an omitted second index defaults to the size of the string being - sliced. - - \begin{verbatim} - >>> word[:2] # The first two characters - 'He' - >>> word[2:] # All but the first two characters - 'lpA' \end{verbatim} --- 674,677 ---- From jackjansen@users.sourceforge.net Wed Mar 12 13:47:42 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 12 Mar 2003 05:47:42 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_macfs.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv25906 Modified Files: test_macfs.py Log Message: Filter out the depracation warning for macfs. Index: test_macfs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_macfs.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_macfs.py 11 Mar 2003 21:48:55 -0000 1.4 --- test_macfs.py 12 Mar 2003 13:47:39 -0000 1.5 *************** *** 2,5 **** --- 2,7 ---- import unittest + import warnings + warnings.filterwarnings("ignore", "macfs.*", DeprecationWarning, __name__) import macfs import os From akuchling@users.sourceforge.net Wed Mar 12 14:11:02 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Wed, 12 Mar 2003 06:11:02 -0800 Subject: [Python-checkins] python/dist/src/Lib asynchat.py,1.15,1.15.22.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv3417 Modified Files: Tag: release22-maint asynchat.py Log Message: [Backport patch #649762] Fix for asynchat endless loop When the null string is used as the terminator, it used to be the same as None, meaning "collect all the data". In the current code, however, it falls into an endless loop; this change reverts to the old behavior. Index: asynchat.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asynchat.py,v retrieving revision 1.15 retrieving revision 1.15.22.1 diff -C2 -d -r1.15 -r1.15.22.1 *** asynchat.py 8 Apr 2001 07:23:44 -0000 1.15 --- asynchat.py 12 Mar 2003 14:11:00 -0000 1.15.22.1 *************** *** 95,99 **** lb = len(self.ac_in_buffer) terminator = self.get_terminator() ! if terminator is None: # no terminator, collect it all self.collect_incoming_data (self.ac_in_buffer) --- 95,99 ---- lb = len(self.ac_in_buffer) terminator = self.get_terminator() ! if terminator is None or terminator == '': # no terminator, collect it all self.collect_incoming_data (self.ac_in_buffer) From akuchling@users.sourceforge.net Wed Mar 12 14:17:41 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Wed, 12 Mar 2003 06:17:41 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.337.2.4.2.65,1.337.2.4.2.66 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv6701 Modified Files: Tag: release22-maint NEWS Log Message: Add item Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.337.2.4.2.65 retrieving revision 1.337.2.4.2.66 diff -C2 -d -r1.337.2.4.2.65 -r1.337.2.4.2.66 *** NEWS 4 Mar 2003 00:50:23 -0000 1.337.2.4.2.65 --- NEWS 12 Mar 2003 14:17:38 -0000 1.337.2.4.2.66 *************** *** 100,103 **** --- 100,106 ---- set properly in out-of-tree builds. + - SF #649762, fix infinite loop in asynchat when null string used as terminator + + What's New in Python 2.2.2 (final) ? Release date: 14-Oct-2002 From akuchling@users.sourceforge.net Wed Mar 12 14:28:24 2003 From: akuchling@users.sourceforge.net (akuchling@users.sourceforge.net) Date: Wed, 12 Mar 2003 06:28:24 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.337.2.4.2.66,1.337.2.4.2.67 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv13121 Modified Files: Tag: release22-maint NEWS Log Message: Add some more Distutil changes Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.337.2.4.2.66 retrieving revision 1.337.2.4.2.67 diff -C2 -d -r1.337.2.4.2.66 -r1.337.2.4.2.67 *** NEWS 12 Mar 2003 14:17:38 -0000 1.337.2.4.2.66 --- NEWS 12 Mar 2003 14:28:21 -0000 1.337.2.4.2.67 *************** *** 102,105 **** --- 102,114 ---- - SF #649762, fix infinite loop in asynchat when null string used as terminator + - SF #570655, fix misleading option text for bdist_rpm + + - Distutils: Allow unknown keyword arguments to the setup() function + and the Extension constructor, printing a warning about them instead + of reporting an error and stopping. + + - Distutils: Translate spaces in the machine name to underscores + (Power Macintosh -> Power_Macintosh) + What's New in Python 2.2.2 (final) ? From cliffwells18@users.sourceforge.net Wed Mar 12 18:55:46 2003 From: cliffwells18@users.sourceforge.net (cliffwells18@users.sourceforge.net) Date: Wed, 12 Mar 2003 10:55:46 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/util - New directory Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/util In directory sc8-pr-cvs1:/tmp/cvs-serv20478/util Log Message: Directory /cvsroot/python/python/nondist/sandbox/csv/util added to the repository From cliffwells18@users.sourceforge.net Wed Mar 12 18:56:50 2003 From: cliffwells18@users.sourceforge.net (cliffwells18@users.sourceforge.net) Date: Wed, 12 Mar 2003 10:56:50 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv __init__.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv20740 Added Files: __init__.py Log Message: Make cvs into a package so we can have a util package --- NEW FILE: __init__.py --- From cliffwells18@users.sourceforge.net Wed Mar 12 18:57:46 2003 From: cliffwells18@users.sourceforge.net (cliffwells18@users.sourceforge.net) Date: Wed, 12 Mar 2003 10:57:46 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/util __init__.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/util In directory sc8-pr-cvs1:/tmp/cvs-serv21281 Added Files: __init__.py Log Message: Create util package --- NEW FILE: __init__.py --- From cliffwells18@users.sourceforge.net Wed Mar 12 18:58:26 2003 From: cliffwells18@users.sourceforge.net (cliffwells18@users.sourceforge.net) Date: Wed, 12 Mar 2003 10:58:26 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/util sniffer.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/util In directory sc8-pr-cvs1:/tmp/cvs-serv21719 Added Files: sniffer.py Log Message: Initial commit of sniffer.py --- NEW FILE: sniffer.py --- """ dialect = Sniffer().sniff(file('csv/easy.csv')) print "delimiter", dialect.delimiter print "quotechar", dialect.quotechar print "skipinitialspace", dialect.skipinitialspace """ from csv import csv import re, string class Sniffer: """ "Sniffs" the format of a CSV file (i.e. delimiter, quotechar) Sniffer.dialect will be either a csv.Dialect object or None if the file format couldn't be determined. """ def __init__(self, sample = 16 * 1024): # in case there is more than one possible delimiter self.preferred = [',', '\t', ';', ' ', ':'] # amount of data (in bytes) to sample self.sample = sample def sniff(self, fileobj): """ Takes a file-like object and returns a dialect (or None) """ data = fileobj.read(self.sample) quotechar, delimiter, skipinitialspace = self._guessQuoteAndDelimiter(data) if delimiter is None: delimiter, skipinitialspace = self._guessDelimiter(data) print quotechar, delimiter, skipinitialspace class Dialect(csv.Dialect): _name = "sniffed" lineterminator = '\r\n' quoting = csv.QUOTE_MINIMAL escapechar = '' doublequote = False Dialect.delimiter = delimiter Dialect.quotechar = quotechar Dialect.skipinitialspace = skipinitialspace return Dialect() def _guessQuoteAndDelimiter(self, data): """ Looks for text enclosed between two identical quotes (the probable quotechar) which are preceded and followed by the same character (the probable delimiter). For example: ,'some text', The quote with the most wins, same with the delimiter. If there is no quotechar the delimiter can't be determined this way. """ for restr in ('(?P[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?P=delim)', # ,".*?", '(?:^|\n)(?P["\']).*?(?P=quote)(?P[^\w\n"\'])(?P ?)', # ".*?", '(?P>[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?:$|\n)', # ,".*?" '(?:^|\n)(?P["\']).*?(?P=quote)(?:$|\n)'): # ".*?" (no delim, no space) regexp = re.compile(restr, re.S | re.M) matches = regexp.findall(data) if matches: print restr print matches break if not matches: return ('', None, 0) # (quotechar, delimiter, skipinitialspace) quotes = {} delims = {} spaces = 0 for m in matches: n = regexp.groupindex['quote'] - 1 key = m[n] if key: quotes[key] = quotes.get(key, 0) + 1 try: n = regexp.groupindex['delim'] - 1 key = m[n] except KeyError: continue if key: delims[key] = delims.get(key, 0) + 1 try: n = regexp.groupindex['space'] - 1 except KeyError: continue if m[n]: spaces += 1 print "QUOTES", quotes print "DELIMS", delims quotechar = reduce(lambda a, b, quotes = quotes: (quotes[a] > quotes[b]) and a or b, quotes.keys()) if delims: delim = reduce(lambda a, b, delims = delims: (delims[a] > delims[b]) and a or b, delims.keys()) skipinitialspace = delims[delim] == spaces if delim == '\n': # most likely a file with a single column delim = None else: # there is *no* delimiter, it's a single column of quoted data delim = '' skipinitialspace = 0 return (quotechar, delim, skipinitialspace) def _guessDelimiter(self, data): """ The delimiter /should/ occur the same number of times on each row. However, due to malformed data, it may not. We don't want an all or nothing approach, so we allow for small variations in this number. 1) build a table of the frequency of each character on every line. 2) build a table of freqencies of this frequency (meta-frequency?), e.g. "x occurred 5 times in 10 rows, 6 times in 1000 rows, 7 times in 2 rows" 3) use the mode of the meta-frequency to determine the /expected/ frequency for that character 4) find out how often the character actually meets that goal 5) the character that best meets its goal is the delimiter For performance reasons, the data is evaluated in chunks, so it can try and evaluate the smallest portion of the data possible, evaluating additional chunks as necessary. """ data = filter(None, data.split('\n')) ascii = [chr(c) for c in range(127)] # 7-bit ASCII # build frequency tables chunkLength = min(10, len(data)) iteration = 0 charFrequency = {} modes = {} delims = {} start, end = 0, min(chunkLength, len(data)) while start < len(data): iteration += 1 for line in data[start:end]: for char in ascii: metafrequency = charFrequency.get(char, {}) freq = line.strip().count(char) # must count even if frequency is 0 metafrequency[freq] = metafrequency.get(freq, 0) + 1 # value is the mode charFrequency[char] = metafrequency for char in charFrequency.keys(): items = charFrequency[char].items() if len(items) == 1 and items[0][0] == 0: continue # get the mode of the frequencies if len(items) > 1: modes[char] = reduce(lambda a, b: a[1] > b[1] and a or b, items) # adjust the mode - subtract the sum of all other frequencies items.remove(modes[char]) modes[char] = (modes[char][0], modes[char][1] - reduce(lambda a, b: (0, a[1] + b[1]), items)[1]) else: modes[char] = items[0] # build a list of possible delimiters modeList = modes.items() total = float(chunkLength * iteration) consistency = 1.0 # (rows of consistent data) / (number of rows) = 100% threshold = 0.9 # minimum consistency threshold while len(delims) == 0 and consistency >= threshold: for k, v in modeList: if v[0] > 0 and v[1] > 0: if (v[1]/total) >= consistency: delims[k] = v consistency -= 0.01 if len(delims) == 1: delim = delims.keys()[0] skipinitialspace = data[0].count(delim) == data[0].count("%c " % delim) return (delim, skipinitialspace) # analyze another chunkLength lines start = end end += chunkLength if not delims: return None # if there's more than one, fall back to a 'preferred' list if len(delims) > 1: for d in self.preferred: if d in delims.keys(): skipinitialspace = data[0].count(d) == data[0].count("%c " % d) return (d, skipinitialspace) # finally, just return the first damn character in the list delim = delims.keys()[0] skipinitialspace = data[0].count(delim) == data[0].count("%c " % delim) return (delim, skipinitialspace) From cliffwells18@users.sourceforge.net Wed Mar 12 21:45:08 2003 From: cliffwells18@users.sourceforge.net (cliffwells18@users.sourceforge.net) Date: Wed, 12 Mar 2003 13:45:08 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/util sniffer.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/util In directory sc8-pr-cvs1:/tmp/cvs-serv7661 Modified Files: sniffer.py Log Message: Removed debugging statements Index: sniffer.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/util/sniffer.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** sniffer.py 12 Mar 2003 18:58:24 -0000 1.1 --- sniffer.py 12 Mar 2003 21:45:05 -0000 1.2 *************** *** 33,38 **** delimiter, skipinitialspace = self._guessDelimiter(data) - print quotechar, delimiter, skipinitialspace - class Dialect(csv.Dialect): _name = "sniffed" --- 33,36 ---- *************** *** 67,72 **** matches = regexp.findall(data) if matches: - print restr - print matches break --- 65,68 ---- *************** *** 95,101 **** if m[n]: spaces += 1 - - print "QUOTES", quotes - print "DELIMS", delims quotechar = reduce(lambda a, b, quotes = quotes: --- 91,94 ---- From mwh@users.sourceforge.net Thu Mar 13 13:56:55 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Thu, 13 Mar 2003 05:56:55 -0800 Subject: [Python-checkins] python/dist/src/Modules signalmodule.c,2.72,2.73 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv22379/Modules Modified Files: signalmodule.c Log Message: Take out my (long since disabled) POSIX signal mask handling code. I'm not going to have the time or energy to get this working x-platform -- anyone who does is welcome to the code! Index: signalmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/signalmodule.c,v retrieving revision 2.72 retrieving revision 2.73 diff -C2 -d -r2.72 -r2.73 *** signalmodule.c 19 Feb 2003 15:53:15 -0000 2.72 --- signalmodule.c 13 Mar 2003 13:56:53 -0000 2.73 *************** *** 270,420 **** anything else -- the callable Python object used as a handler"); - #ifdef HAVE_SIGPROCMASK /* we assume that having SIGPROCMASK is enough - to guarantee full POSIX signal handling */ - /* returns 0 for success, <0 for failure (with exception set) */ - static int - _signal_list_to_sigset(PyObject* seq, sigset_t* set, char* mesg) - { - int i, len, val; - - seq = PySequence_Fast(seq, mesg); - if (!seq) - return -1; - - len = PySequence_Fast_GET_SIZE(seq); - - sigemptyset(set); - - for (i = 0; i < len; i++) { - val = PyInt_AsLong(PySequence_Fast_GET_ITEM(seq, i)); - if (val == -1 && PyErr_Occurred()) { - Py_DECREF(seq); - return -1; - } - if (sigaddset(set, val) < 0) { - Py_DECREF(seq); - PyErr_SetFromErrno(PyExc_ValueError); - return -1; - } - } - - Py_DECREF(seq); - return 0; - } - - static PyObject* - _signal_sigset_to_list(sigset_t* set) - { - PyObject* ret; - PyObject* ob; - int i; - - ret = PyList_New(0); - if (!ret) - return NULL; - - for (i = 1; i < NSIG; i++) { - if (sigismember(set, i)) { - ob = PyInt_FromLong(i); - if (!ob) { - Py_DECREF(ret); - return NULL; - } - PyList_Append(ret, ob); - Py_DECREF(ob); - } - } - - return ret; - } - - static PyObject* - signal_sigprocmask(PyObject* self, PyObject* args) - { - int how; - sigset_t newset, oldset; - PyObject* seq; - - if (!PyArg_ParseTuple(args, "iO", &how, &seq)) - return NULL; - - if (_signal_list_to_sigset(seq, &newset, - "sigprocmask requires a sequence") < 0) - return NULL; - - if (sigprocmask(how, &newset, &oldset) < 0) { - return PyErr_SetFromErrno(PyExc_ValueError); - } - - if (PyErr_CheckSignals()) - return NULL; - - return _signal_sigset_to_list(&oldset); - } - - PyDoc_STRVAR(sigprocmask_doc, - "sigprocmask(how, sigset) -> sigset\n\ - \n\ - Change the list of currently blocked signals. The parameter how should be\n\ - one of SIG_BLOCK, SIG_UNBLOCK or SIG_SETMASK and sigset should be a\n\ - sequence of signal numbers. The behaviour of the call depends on the value\n\ - of how:\n\ - \n\ - SIG_BLOCK\n\ - The set of blocked signals is the union of the current set and the\n\ - sigset argument.\n\ - SIG_UNBLOCK\n\ - The signals in sigset are removed from the current set of blocked\n\ - signals. It is legal to attempt to unblock a signal which is not\n\ - blocked.\n\ - SIG_SETMASK\n\ - The set of blocked signals is set to the argument set.\n\ - \n\ - A list contating the numbers of the previously blocked signals is returned."); - - static PyObject* - signal_sigpending(PyObject* self) - { - sigset_t set; - - if (sigpending(&set) < 0) { - return PyErr_SetFromErrno(PyExc_ValueError); - } - - return _signal_sigset_to_list(&set); - } - - PyDoc_STRVAR(sigpending_doc, - "sigpending() -> sigset\n\ - \n\ - Return the set of pending signals, i.e. a list containing the numbers of\n\ - those signals that have been raised while blocked."); - - static PyObject* - signal_sigsuspend(PyObject* self, PyObject* arg) - { - sigset_t set; - - if (_signal_list_to_sigset(arg, &set, - "sigsuspend requires a sequence") < 0) - return NULL; - - Py_BEGIN_ALLOW_THREADS - sigsuspend(&set); - Py_END_ALLOW_THREADS - - if (PyErr_CheckSignals()) - return NULL; - - Py_INCREF(Py_None); - return Py_None; - } - - PyDoc_STRVAR(sigsuspend_doc, - "sigsuspend(sigset) -> None\n\ - \n\ - Temporarily replace the signal mask with sigset (which should be a sequence\n\ - of signal numbers) and suspend the process until a signal is received."); - #endif /* List of functions defined in the module */ --- 270,273 ---- *************** *** 431,442 **** {"default_int_handler", signal_default_int_handler, METH_VARARGS, default_int_handler_doc}, - #ifdef HAVE_SIGPROCMASK - {"sigprocmask", (PyCFunction)signal_sigprocmask, - METH_VARARGS, sigprocmask_doc}, - {"sigpending", (PyCFunction)signal_sigpending, - METH_NOARGS, sigpending_doc}, - {"sigsuspend", (PyCFunction)signal_sigsuspend, - METH_O, sigsuspend_doc}, - #endif {NULL, NULL} /* sentinel */ }; --- 284,287 ---- *************** *** 454,461 **** default_int_handler() -- default SIGINT handler\n\ \n\ - sigpending() |\n\ - sigprocmask() |-- posix signal mask handling [Unix only]\n\ - sigsuspend() |\n\ - \n\ Constants:\n\ \n\ --- 299,302 ---- *************** *** 706,721 **** Py_XDECREF(x); #endif - #ifdef HAVE_SIGPROCMASK - x = PyInt_FromLong(SIG_BLOCK); - PyDict_SetItemString(d, "SIG_BLOCK", x); - Py_XDECREF(x); - x = PyInt_FromLong(SIG_UNBLOCK); - PyDict_SetItemString(d, "SIG_UNBLOCK", x); - Py_XDECREF(x); - x = PyInt_FromLong(SIG_SETMASK); - PyDict_SetItemString(d, "SIG_SETMASK", x); - Py_XDECREF(x); - #endif - if (!PyErr_Occurred()) return; --- 547,550 ---- From mwh@users.sourceforge.net Thu Mar 13 13:56:55 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Thu, 13 Mar 2003 05:56:55 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_signal.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv22379/Lib/test Modified Files: test_signal.py Log Message: Take out my (long since disabled) POSIX signal mask handling code. I'm not going to have the time or energy to get this working x-platform -- anyone who does is welcome to the code! Index: test_signal.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_signal.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_signal.py 23 Jul 2002 19:04:01 -0000 1.12 --- test_signal.py 13 Mar 2003 13:56:52 -0000 1.13 *************** *** 65,127 **** print "KeyboardInterrupt (assume the alarm() went off)" - - if hasattr(signal, "sigprocmask"): - class HupDelivered(Exception): - pass - def hup(signum, frame): - raise HupDelivered - def hup2(signum, frame): - signal.signal(signal.SIGHUP, hup) - return - signal.signal(signal.SIGHUP, hup) - - if verbose: - print "blocking SIGHUP" - - defaultmask = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGHUP]) - - if verbose: - print "sending SIGHUP" - - try: - os.kill(pid, signal.SIGHUP) - except HupDelivered: - raise TestFailed, "HUP not blocked" - - if signal.SIGHUP not in signal.sigpending(): - raise TestFailed, "HUP not pending" - - if verbose: - print "unblocking SIGHUP" - - try: - signal.sigprocmask(signal.SIG_UNBLOCK, [signal.SIGHUP]) - except HupDelivered: - pass - else: - raise TestFailed, "HUP not delivered" - - if verbose: - print "testing sigsuspend" - - signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGHUP]) - signal.signal(signal.SIGHUP, hup2) - - if not os.fork(): - time.sleep(2) - os.kill(pid, signal.SIGHUP) - time.sleep(2) - os.kill(pid, signal.SIGHUP) - os._exit(0) - else: - try: - signal.sigsuspend(defaultmask) - except: - raise TestFailed, "sigsuspend erroneously raised" - - try: - signal.sigsuspend(defaultmask) - except HupDelivered: - pass - else: - raise TestFailed, "sigsupsend didn't raise" --- 65,66 ---- From mwh@users.sourceforge.net Thu Mar 13 13:56:55 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Thu, 13 Mar 2003 05:56:55 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.694,1.695 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv22379/Misc Modified Files: NEWS Log Message: Take out my (long since disabled) POSIX signal mask handling code. I'm not going to have the time or energy to get this working x-platform -- anyone who does is welcome to the code! Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.694 retrieving revision 1.695 diff -C2 -d -r1.694 -r1.695 *** NEWS 11 Mar 2003 21:43:55 -0000 1.694 --- NEWS 13 Mar 2003 13:56:50 -0000 1.695 *************** *** 983,989 **** is called. - - signal.sigpending, signal.sigprocmask and signal.sigsuspend have - been added where available. - - The sys module acquired a new attribute, api_version, which evaluates to the value of the PYTHON_API_VERSION macro with which the --- 983,986 ---- From mwh@users.sourceforge.net Thu Mar 13 13:57:22 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Thu, 13 Mar 2003 05:57:22 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libsignal.tex,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv22379/Doc/lib Modified Files: libsignal.tex Log Message: Take out my (long since disabled) POSIX signal mask handling code. I'm not going to have the time or energy to get this working x-platform -- anyone who does is welcome to the code! Index: libsignal.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsignal.tex,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** libsignal.tex 27 May 2002 15:08:24 -0000 1.24 --- libsignal.tex 13 Mar 2003 13:56:49 -0000 1.25 *************** *** 19,22 **** --- 19,26 ---- \item + There is no way to ``block'' signals temporarily from critical + sections (since this is not supported by all \UNIX{} flavors). + + \item Although Python signal handlers are called asynchronously as far as the Python user is concerned, they can only occur between the *************** *** 89,102 **** \end{datadesc} - \begin{datadesc}{SIG_BLOCK} - \end{datadesc} - \begin{datadesc}{SIG_UNBLOCK} - \end{datadesc} - \begin{datadesc}{SIG_SETMASK} - These constants are for use as the first parameter of the - \function{sigprocmask} function described below. - \end{datadesc} - - The \module{signal} module defines the following functions: --- 93,96 ---- *************** *** 149,192 **** reference manual for a description of frame objects). \obindex{frame} - \end{funcdesc} - - The following functions are supported if your platform does. Most - modern \UNIX-alikes now do. - - \begin{funcdesc}{sigpending}{} - Return the set of pending signals, i.e. a list containing the - numbers of those signals that have been raised while blocked. - \versionadded{2.3} - \end{funcdesc} - - \begin{funcdesc}{sigprocmask}{how, sigset} - Change the list of currently blocked signals. The parameter - \var{how} should be one of \constant{SIG_BLOCK}, - \constant{SIG_UNBLOCK} or \constant{SIG_SETMASK} and \var{sigset} - should be a sequence of signal numbers. The behaviour of the call - depends on the value of \var{how}: - - \begin{tableii}{l|l}{textrm}{Value of \var{how}}{Behaviour of call} - \lineii{\constant{SIG_BLOCK}} - {The set of blocked signals is the union of the current set - and \var{sigset}.} - \lineii{\constant{SIG_UNBLOCK}} - {The signals in \var{sigset} are removed from the current - set of blocked signals. It is legal to attempt to unblock - a signal which is not blocked.} - \lineii{\constant{SIG_SETMASK}} - {The set of blocked signals is set to the \var{sigset}.} - \end{tableii} - - A list contating the numbers of the previously blocked signals is - returned. - \versionadded{2.3} - \end{funcdesc} - - \begin{funcdesc}{sigsuspend}{sigset} - Temporarily replace the signal mask with \var{sigset} (which should - be a sequnce of signal numbers) and suspend the process until a - signal is received. - \versionadded{2.3} \end{funcdesc} --- 143,146 ---- From mwh@users.sourceforge.net Thu Mar 13 13:57:22 2003 From: mwh@users.sourceforge.net (mwh@users.sourceforge.net) Date: Thu, 13 Mar 2003 05:57:22 -0800 Subject: [Python-checkins] python/dist/src/Doc/whatsnew whatsnew23.tex,1.129,1.130 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/whatsnew In directory sc8-pr-cvs1:/tmp/cvs-serv22379/Doc/whatsnew Modified Files: whatsnew23.tex Log Message: Take out my (long since disabled) POSIX signal mask handling code. I'm not going to have the time or energy to get this working x-platform -- anyone who does is welcome to the code! Index: whatsnew23.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/whatsnew/whatsnew23.tex,v retrieving revision 1.129 retrieving revision 1.130 diff -C2 -d -r1.129 -r1.130 *** whatsnew23.tex 9 Mar 2003 07:19:38 -0000 1.129 --- whatsnew23.tex 13 Mar 2003 13:56:50 -0000 1.130 *************** *** 1486,1493 **** \item Support for more advanced POSIX signal handling was added ! to the \module{signal} module by adding the \function{sigpending}, ! \function{sigprocmask} and \function{sigsuspend} functions where supported ! by the platform. These functions make it possible to avoid some previously ! unavoidable race conditions with signal handling. \item The \module{socket} module now supports timeouts. You --- 1486,1491 ---- \item Support for more advanced POSIX signal handling was added ! to the \module{signal} but then removed again as it proved impossible ! to make it work reliably across platforms. \item The \module{socket} module now supports timeouts. You From rhettinger@users.sourceforge.net Fri Mar 14 01:37:44 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Thu, 13 Mar 2003 17:37:44 -0800 Subject: [Python-checkins] python/dist/src/Python ceval.c,2.353,2.354 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv32028 Modified Files: ceval.c Log Message: SF patch #701907: More use of fast_next_opcode My previous patches should have used fast_next_opcode in a few places instead of continue. Also, applied one PyInt_AS_LONG macro in a place where the type had already been checked. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.353 retrieving revision 2.354 diff -C2 -d -r2.353 -r2.354 *** ceval.c 1 Mar 2003 03:36:33 -0000 2.353 --- ceval.c 14 Mar 2003 01:37:42 -0000 2.354 *************** *** 884,888 **** SET_TOP(w); SET_SECOND(v); ! continue; case ROT_THREE: --- 884,888 ---- SET_TOP(w); SET_SECOND(v); ! goto fast_next_opcode; case ROT_THREE: *************** *** 893,897 **** SET_SECOND(x); SET_THIRD(v); ! continue; case ROT_FOUR: --- 893,897 ---- SET_SECOND(x); SET_THIRD(v); ! goto fast_next_opcode; case ROT_FOUR: *************** *** 904,908 **** SET_THIRD(x); SET_FOURTH(u); ! continue; case DUP_TOP: --- 904,908 ---- SET_THIRD(x); SET_FOURTH(u); ! goto fast_next_opcode; case DUP_TOP: *************** *** 910,914 **** Py_INCREF(v); PUSH(v); ! continue; case DUP_TOPX: --- 910,914 ---- Py_INCREF(v); PUSH(v); ! goto fast_next_opcode; case DUP_TOPX: *************** *** 1595,1599 **** v = POP(); if (PyInt_Check(v)) { ! why = (enum why_code) PyInt_AsLong(v); if (why == WHY_RETURN || why == WHY_YIELD || --- 1595,1599 ---- v = POP(); if (PyInt_Check(v)) { ! why = (enum why_code) PyInt_AS_LONG(v); if (why == WHY_RETURN || why == WHY_YIELD || *************** *** 1973,1985 **** case JUMP_FORWARD: JUMPBY(oparg); ! continue; case JUMP_IF_FALSE: w = TOP(); if (w == Py_True) ! continue; if (w == Py_False) { JUMPBY(oparg); ! continue; } err = PyObject_IsTrue(w); --- 1973,1985 ---- case JUMP_FORWARD: JUMPBY(oparg); ! goto fast_next_opcode; case JUMP_IF_FALSE: w = TOP(); if (w == Py_True) ! goto fast_next_opcode; if (w == Py_False) { JUMPBY(oparg); ! goto fast_next_opcode; } err = PyObject_IsTrue(w); *************** *** 1995,2002 **** w = TOP(); if (w == Py_False) ! continue; if (w == Py_True) { JUMPBY(oparg); ! continue; } err = PyObject_IsTrue(w); --- 1995,2002 ---- w = TOP(); if (w == Py_False) ! goto fast_next_opcode; if (w == Py_True) { JUMPBY(oparg); ! goto fast_next_opcode; } err = PyObject_IsTrue(w); *************** *** 2013,2017 **** case JUMP_ABSOLUTE: JUMPTO(oparg); ! continue; case GET_ITER: --- 2013,2017 ---- case JUMP_ABSOLUTE: JUMPTO(oparg); ! goto fast_next_opcode; case GET_ITER: From fdrake@users.sourceforge.net Fri Mar 14 16:21:59 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Fri, 14 Mar 2003 08:21:59 -0800 Subject: [Python-checkins] python/dist/src/Lib HTMLParser.py,1.11,1.12 sgmllib.py,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv20740 Modified Files: HTMLParser.py sgmllib.py Log Message: Accept commas in unquoted attribute values. This closes SF patch #669683. Index: HTMLParser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/HTMLParser.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** HTMLParser.py 14 May 2002 15:50:11 -0000 1.11 --- HTMLParser.py 14 Mar 2003 16:21:54 -0000 1.12 *************** *** 27,31 **** attrfind = re.compile( r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*' ! r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./:;+*%?!&$\(\)_#=~]*))?') locatestarttagend = re.compile(r""" --- 27,31 ---- attrfind = re.compile( r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*' ! r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~]*))?') locatestarttagend = re.compile(r""" Index: sgmllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sgmllib.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** sgmllib.py 2 Jun 2002 00:40:04 -0000 1.41 --- sgmllib.py 14 Mar 2003 16:21:55 -0000 1.42 *************** *** 35,39 **** attrfind = re.compile( r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*' ! r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./:;+*%?!&$\(\)_#=~\'"]*))?') --- 35,39 ---- attrfind = re.compile( r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*' ! r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"]*))?') From fdrake@users.sourceforge.net Fri Mar 14 16:22:01 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Fri, 14 Mar 2003 08:22:01 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_htmlparser.py,1.9,1.10 test_sgmllib.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv20740/test Modified Files: test_htmlparser.py test_sgmllib.py Log Message: Accept commas in unquoted attribute values. This closes SF patch #669683. Index: test_htmlparser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_htmlparser.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_htmlparser.py 23 Jul 2002 19:03:54 -0000 1.9 --- test_htmlparser.py 14 Mar 2003 16:21:56 -0000 1.10 *************** *** 198,201 **** --- 198,205 ---- ("starttag", "a", [("b", ""), ("c", "")]), ]) + # Regression test for SF patch #669683. + self._run_check("", [ + ("starttag", "e", [("a", "rgb(1,2,3)")]), + ]) def test_attr_entity_replacement(self): Index: test_sgmllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sgmllib.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_sgmllib.py 25 Sep 2002 16:29:17 -0000 1.4 --- test_sgmllib.py 14 Mar 2003 16:21:57 -0000 1.5 *************** *** 201,204 **** --- 201,208 ---- ("starttag", "a", [("b", ""), ("c", "")]), ]) + # Regression test for SF patch #669683. + self.check_events("", [ + ("starttag", "e", [("a", "rgb(1,2,3)")]), + ]) def test_attr_funky_names(self): From gvanrossum@users.sourceforge.net Fri Mar 14 17:21:06 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 14 Mar 2003 09:21:06 -0800 Subject: [Python-checkins] python/dist/src/Lib timeit.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv21199 Modified Files: timeit.py Log Message: Implement some recommendations from Raymond H: - Make all local variables in the template start with an underscore, to prevent name conflicts with the timed code. - Added a method to print a traceback that shows source lines from the expanded template. - Use that method in main(). Index: timeit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/timeit.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** timeit.py 7 Mar 2003 01:33:18 -0000 1.6 --- timeit.py 14 Mar 2003 17:21:00 -0000 1.7 *************** *** 59,62 **** --- 59,63 ---- __all__ = ["Timer"] + dummy_src_name = "" default_number = 1000000 default_repeat = 10 *************** *** 73,83 **** # being indented 8 spaces. template = """ ! def inner(seq, timer): %(setup)s ! t0 = timer() ! for i in seq: %(stmt)s ! t1 = timer() ! return t1-t0 """ --- 74,84 ---- # being indented 8 spaces. template = """ ! def inner(_seq, _timer): %(setup)s ! _t0 = _timer() ! for _i in _seq: %(stmt)s ! _t1 = _timer() ! return _t1 - _t0 """ *************** *** 108,116 **** setup = reindent(setup, 4) src = template % {'stmt': stmt, 'setup': setup} ! code = compile(src, "", "exec") ns = {} exec code in globals(), ns self.inner = ns["inner"] def timeit(self, number=default_number): """Time 'number' executions of the main statement. --- 109,142 ---- setup = reindent(setup, 4) src = template % {'stmt': stmt, 'setup': setup} ! self.src = src # Save for traceback display ! code = compile(src, dummy_src_name, "exec") ns = {} exec code in globals(), ns self.inner = ns["inner"] + def print_exc(self, file=None): + """Helper to print a traceback from the timed code. + + Typical use: + + t = Timer(...) # outside the try/except + try: + t.timeit(...) # or t.repeat(...) + except: + t.print_exc() + + The advantage over the standard traceback is that source lines + in the compiled template will be displayed. + + The optional file argument directs where the traceback is + sent; it defaults to sys.stderr. + """ + import linecache, traceback + linecache.cache[dummy_src_name] = (len(self.src), + None, + self.src.split("\n"), + dummy_src_name) + traceback.print_exc(file=file) + def timeit(self, number=default_number): """Time 'number' executions of the main statement. *************** *** 163,166 **** --- 189,196 ---- The return value is an exit code to be passed to sys.exit(); it may be None to indicate success. + + When an exception happens during timing, a traceback is printed to + stderr and the return value is 1. Exceptions at other times + (including the template compilation) are not caught. """ if args is None: *************** *** 202,216 **** for i in range(1, 10): number = 10**i ! x = t.timeit(number) if x >= 0.2: break ! r = t.repeat(repeat, number) best = min(r) print "%d loops," % number, usec = best * 1e6 / number if repeat > 1: ! print "best of %d: %.3f usec" % (repeat, usec) else: ! print "time: %.3f usec" % usec return None --- 232,254 ---- for i in range(1, 10): number = 10**i ! try: ! x = t.timeit(number) ! except: ! t.print_exc() ! return 1 if x >= 0.2: break ! try: ! r = t.repeat(repeat, number) ! except: ! t.print_exc() ! return 1 best = min(r) print "%d loops," % number, usec = best * 1e6 / number if repeat > 1: ! print "best of %d: %.3f usec per loop" % (repeat, usec) else: ! print "time: %.3f usec per loop" % usec return None From cliffwells18@users.sourceforge.net Fri Mar 14 21:10:34 2003 From: cliffwells18@users.sourceforge.net (cliffwells18@users.sourceforge.net) Date: Fri, 14 Mar 2003 13:10:34 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/util sniffer.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/util In directory sc8-pr-cvs1:/tmp/cvs-serv29487 Modified Files: sniffer.py Log Message: Minor bugfixes. No longer punts when there isn't a quotechar or delimiter, just returns '' instead. Index: sniffer.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/util/sniffer.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** sniffer.py 12 Mar 2003 21:45:05 -0000 1.2 --- sniffer.py 14 Mar 2003 21:10:27 -0000 1.3 *************** *** 7,17 **** from csv import csv ! import re, string class Sniffer: """ "Sniffs" the format of a CSV file (i.e. delimiter, quotechar) ! Sniffer.dialect will be either a csv.Dialect object or None ! if the file format couldn't be determined. """ def __init__(self, sample = 16 * 1024): --- 7,16 ---- from csv import csv ! import re class Sniffer: """ "Sniffs" the format of a CSV file (i.e. delimiter, quotechar) ! Returns a csv.Dialect object. """ def __init__(self, sample = 16 * 1024): *************** *** 184,188 **** if not delims: ! return None # if there's more than one, fall back to a 'preferred' list --- 183,187 ---- if not delims: ! return ('', 0) # if there's more than one, fall back to a 'preferred' list From gvanrossum@users.sourceforge.net Fri Mar 14 21:51:39 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 14 Mar 2003 13:51:39 -0800 Subject: [Python-checkins] python/dist/src/Misc ACKS,1.228,1.229 NEWS,1.695,1.696 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv14617/Misc Modified Files: ACKS NEWS Log Message: - New function time.tzset() provides access to the C library tzet() function, if supported. (SF patch #675422, by Stuart Bishop.) Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.228 retrieving revision 1.229 diff -C2 -d -r1.228 -r1.229 *** ACKS 9 Mar 2003 07:05:43 -0000 1.228 --- ACKS 14 Mar 2003 21:51:33 -0000 1.229 *************** *** 51,54 **** --- 51,55 ---- Ron Bickers Dominic Binks + Stuart Bishop Roy Bixler Martin Bless Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.695 retrieving revision 1.696 diff -C2 -d -r1.695 -r1.696 *** NEWS 13 Mar 2003 13:56:50 -0000 1.695 --- NEWS 14 Mar 2003 21:51:35 -0000 1.696 *************** *** 33,36 **** --- 33,39 ---- ----------------- + - New function time.tzset() provides access to the C library tzet() + function, if supported. (SF patch #675422.) + - Using createfilehandler, deletefilehandler, createtimerhandler functions on Tkinter.tkinter (_tkinter module) no longer crashes the interpreter. From gvanrossum@users.sourceforge.net Fri Mar 14 21:51:39 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 14 Mar 2003 13:51:39 -0800 Subject: [Python-checkins] python/dist/src/Modules timemodule.c,2.134,2.135 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv14617/Modules Modified Files: timemodule.c Log Message: - New function time.tzset() provides access to the C library tzet() function, if supported. (SF patch #675422, by Stuart Bishop.) Index: timemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/timemodule.c,v retrieving revision 2.134 retrieving revision 2.135 diff -C2 -d -r2.134 -r2.135 *** timemodule.c 19 Jan 2003 04:54:58 -0000 2.134 --- timemodule.c 14 Mar 2003 21:51:36 -0000 2.135 *************** *** 555,637 **** #endif /* HAVE_MKTIME */ ! static PyMethodDef time_methods[] = { ! {"time", time_time, METH_VARARGS, time_doc}, ! #ifdef HAVE_CLOCK ! {"clock", time_clock, METH_VARARGS, clock_doc}, ! #endif ! {"sleep", time_sleep, METH_VARARGS, sleep_doc}, ! {"gmtime", time_gmtime, METH_VARARGS, gmtime_doc}, ! {"localtime", time_localtime, METH_VARARGS, localtime_doc}, ! {"asctime", time_asctime, METH_VARARGS, asctime_doc}, ! {"ctime", time_ctime, METH_VARARGS, ctime_doc}, ! #ifdef HAVE_MKTIME ! {"mktime", time_mktime, METH_VARARGS, mktime_doc}, ! #endif ! #ifdef HAVE_STRFTIME ! {"strftime", time_strftime, METH_VARARGS, strftime_doc}, ! #endif ! {"strptime", time_strptime, METH_VARARGS, strptime_doc}, ! {NULL, NULL} /* sentinel */ ! }; ! PyDoc_STRVAR(module_doc, ! "This module provides various functions to manipulate time values.\n\ ! \n\ ! There are two standard representations of time. One is the number\n\ ! of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer\n\ ! or a floating point number (to represent fractions of seconds).\n\ ! The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\ ! The actual value can be retrieved by calling gmtime(0).\n\ ! \n\ ! The other representation is a tuple of 9 integers giving local time.\n\ ! The tuple items are:\n\ ! year (four digits, e.g. 1998)\n\ ! month (1-12)\n\ ! day (1-31)\n\ ! hours (0-23)\n\ ! minutes (0-59)\n\ ! seconds (0-59)\n\ ! weekday (0-6, Monday is 0)\n\ ! Julian day (day in the year, 1-366)\n\ ! DST (Daylight Savings Time) flag (-1, 0 or 1)\n\ ! If the DST flag is 0, the time is given in the regular time zone;\n\ ! if it is 1, the time is given in the DST time zone;\n\ ! if it is -1, mktime() should guess based on the date and time.\n\ ! \n\ ! Variables:\n\ ! \n\ ! timezone -- difference in seconds between UTC and local standard time\n\ ! altzone -- difference in seconds between UTC and local DST time\n\ ! daylight -- whether local time should reflect DST\n\ ! tzname -- tuple of (standard time zone name, DST time zone name)\n\ ! \n\ ! Functions:\n\ \n\ ! time() -- return current time in seconds since the Epoch as a float\n\ ! clock() -- return CPU time since process start as a float\n\ ! sleep() -- delay for a number of seconds given as a float\n\ ! gmtime() -- convert seconds since Epoch to UTC tuple\n\ ! localtime() -- convert seconds since Epoch to local time tuple\n\ ! asctime() -- convert time tuple to string\n\ ! ctime() -- convert time in seconds to string\n\ ! mktime() -- convert local time tuple to seconds since Epoch\n\ ! strftime() -- convert time tuple to string according to format specification\n\ ! strptime() -- parse string to time tuple according to format specification"); ! PyMODINIT_FUNC ! inittime(void) ! { ! PyObject *m; ! char *p; ! m = Py_InitModule3("time", time_methods, module_doc); ! /* Accept 2-digit dates unless PYTHONY2K is set and non-empty */ ! p = Py_GETENV("PYTHONY2K"); ! PyModule_AddIntConstant(m, "accept2dyear", (long) (!p || !*p)); ! /* Squirrel away the module's dictionary for the y2k check */ ! moddict = PyModule_GetDict(m); ! Py_INCREF(moddict); #if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__) tzset(); --- 555,615 ---- #endif /* HAVE_MKTIME */ ! #ifdef HAVE_WORKING_TZSET ! void inittimezone(PyObject *module); + static PyObject * + time_tzset(PyObject *self, PyObject *args) + { + PyObject* m; ! if (!PyArg_ParseTuple(args, ":tzset")) ! return NULL; ! ! m = PyImport_ImportModule("time"); ! if (m == NULL) { ! return NULL; ! } ! ! tzset(); ! ! /* Reset timezone, altzone, daylight and tzname */ ! inittimezone(m); ! Py_DECREF(m); ! ! Py_INCREF(Py_None); ! return Py_None; ! } ! ! PyDoc_STRVAR(tzset_doc, ! "tzset(zone)\n\ \n\ ! Initialize, or reinitialize, the local timezone to the value stored in\n\ ! os.environ['TZ']. The TZ environment variable should be specified in\n\ ! standard Uniz timezone format as documented in the tzset man page\n\ ! (eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently\n\ ! fall back to UTC. If the TZ environment variable is not set, the local\n\ ! timezone is set to the systems best guess of wallclock time.\n\ ! Changing the TZ environment variable without calling tzset *may* change\n\ ! the local timezone used by methods such as localtime, but this behaviour\n\ ! should not be relied on."); ! #endif /* HAVE_WORKING_TZSET */ + void inittimezone(PyObject *m) { + /* This code moved from inittime wholesale to allow calling it from + time_tzset. In the future, some parts of it can be moved back + (for platforms that don't HAVE_WORKING_TZSET, when we know what they + are), and the extranious calls to tzset(3) should be removed. + I havn't done this yet, as I don't want to change this code as + little as possible when introducing the time.tzset and time.tzsetwall + methods. This should simply be a method of doing the following once, + at the top of this function and removing the call to tzset() from + time_tzset(): ! #ifdef HAVE_TZSET ! tzset() ! #endif ! And I'm lazy and hate C so nyer. ! */ #if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__) tzset(); *************** *** 713,716 **** --- 691,784 ---- #endif /* __CYGWIN__ */ #endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/ + } + + + static PyMethodDef time_methods[] = { + {"time", time_time, METH_VARARGS, time_doc}, + #ifdef HAVE_CLOCK + {"clock", time_clock, METH_VARARGS, clock_doc}, + #endif + {"sleep", time_sleep, METH_VARARGS, sleep_doc}, + {"gmtime", time_gmtime, METH_VARARGS, gmtime_doc}, + {"localtime", time_localtime, METH_VARARGS, localtime_doc}, + {"asctime", time_asctime, METH_VARARGS, asctime_doc}, + {"ctime", time_ctime, METH_VARARGS, ctime_doc}, + #ifdef HAVE_MKTIME + {"mktime", time_mktime, METH_VARARGS, mktime_doc}, + #endif + #ifdef HAVE_STRFTIME + {"strftime", time_strftime, METH_VARARGS, strftime_doc}, + #endif + {"strptime", time_strptime, METH_VARARGS, strptime_doc}, + #ifdef HAVE_WORKING_TZSET + {"tzset", time_tzset, METH_VARARGS, tzset_doc}, + #endif + {NULL, NULL} /* sentinel */ + }; + + + PyDoc_STRVAR(module_doc, + "This module provides various functions to manipulate time values.\n\ + \n\ + There are two standard representations of time. One is the number\n\ + of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer\n\ + or a floating point number (to represent fractions of seconds).\n\ + The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\ + The actual value can be retrieved by calling gmtime(0).\n\ + \n\ + The other representation is a tuple of 9 integers giving local time.\n\ + The tuple items are:\n\ + year (four digits, e.g. 1998)\n\ + month (1-12)\n\ + day (1-31)\n\ + hours (0-23)\n\ + minutes (0-59)\n\ + seconds (0-59)\n\ + weekday (0-6, Monday is 0)\n\ + Julian day (day in the year, 1-366)\n\ + DST (Daylight Savings Time) flag (-1, 0 or 1)\n\ + If the DST flag is 0, the time is given in the regular time zone;\n\ + if it is 1, the time is given in the DST time zone;\n\ + if it is -1, mktime() should guess based on the date and time.\n\ + \n\ + Variables:\n\ + \n\ + timezone -- difference in seconds between UTC and local standard time\n\ + altzone -- difference in seconds between UTC and local DST time\n\ + daylight -- whether local time should reflect DST\n\ + tzname -- tuple of (standard time zone name, DST time zone name)\n\ + \n\ + Functions:\n\ + \n\ + time() -- return current time in seconds since the Epoch as a float\n\ + clock() -- return CPU time since process start as a float\n\ + sleep() -- delay for a number of seconds given as a float\n\ + gmtime() -- convert seconds since Epoch to UTC tuple\n\ + localtime() -- convert seconds since Epoch to local time tuple\n\ + asctime() -- convert time tuple to string\n\ + ctime() -- convert time in seconds to string\n\ + mktime() -- convert local time tuple to seconds since Epoch\n\ + strftime() -- convert time tuple to string according to format specification\n\ + strptime() -- parse string to time tuple according to format specification\n\ + tzset() -- change the local timezone"); + + + PyMODINIT_FUNC + inittime(void) + { + PyObject *m; + char *p; + m = Py_InitModule3("time", time_methods, module_doc); + + /* Accept 2-digit dates unless PYTHONY2K is set and non-empty */ + p = Py_GETENV("PYTHONY2K"); + PyModule_AddIntConstant(m, "accept2dyear", (long) (!p || !*p)); + /* Squirrel away the module's dictionary for the y2k check */ + moddict = PyModule_GetDict(m); + Py_INCREF(moddict); + + /* Set, or reset, module variables like time.timezone */ + inittimezone(m); + #ifdef MS_WINDOWS /* Helper to allow interrupts for Windows. *************** *** 902,903 **** --- 970,973 ---- return 0; } + + From gvanrossum@users.sourceforge.net Fri Mar 14 21:52:06 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 14 Mar 2003 13:52:06 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_time.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv14617/Lib/test Modified Files: test_time.py Log Message: - New function time.tzset() provides access to the C library tzet() function, if supported. (SF patch #675422, by Stuart Bishop.) Index: test_time.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_time.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** test_time.py 23 Jul 2002 19:04:06 -0000 1.11 --- test_time.py 14 Mar 2003 21:51:33 -0000 1.12 *************** *** 49,57 **** self.fail('conversion specifier: %r failed.' % format) - def test_asctime(self): time.asctime(time.gmtime(self.t)) self.assertRaises(TypeError, time.asctime, 0) def test_main(): --- 49,138 ---- self.fail('conversion specifier: %r failed.' % format) def test_asctime(self): time.asctime(time.gmtime(self.t)) self.assertRaises(TypeError, time.asctime, 0) + def test_tzset(self): + from os import environ + + # Epoch time of midnight Dec 25th 2002. Never DST in northern + # hemisphere. + xmas2002 = 1040774400.0 + + org_TZ = environ.get('TZ',None) + try: + + # Make sure we can switch to UTC time and results are correct + # Note that unknown timezones default to UTC. + for tz in ('UTC','GMT','Luna/Tycho'): + environ['TZ'] = 'US/Eastern' + time.tzset() + environ['TZ'] = tz + time.tzset() + self.failUnlessEqual( + time.gmtime(xmas2002),time.localtime(xmas2002) + ) + self.failUnlessEqual(time.timezone,time.altzone) + self.failUnlessEqual(time.daylight,0) + self.failUnlessEqual(time.timezone,0) + self.failUnlessEqual(time.altzone,0) + self.failUnlessEqual(time.localtime(xmas2002).tm_isdst,0) + + # Make sure we can switch to US/Eastern + environ['TZ'] = 'US/Eastern' + time.tzset() + self.failIfEqual(time.gmtime(xmas2002),time.localtime(xmas2002)) + self.failUnlessEqual(time.tzname,('EST','EDT')) + self.failUnlessEqual(len(time.tzname),2) + self.failUnlessEqual(time.daylight,1) + self.failUnlessEqual(time.timezone,18000) + self.failUnlessEqual(time.altzone,14400) + self.failUnlessEqual(time.localtime(xmas2002).tm_isdst,0) + self.failUnlessEqual(len(time.tzname),2) + + # Now go to the southern hemisphere. We want somewhere all OS's + # know about that has DST. + environ['TZ'] = 'Australia/Melbourne' + time.tzset() + self.failIfEqual(time.gmtime(xmas2002),time.localtime(xmas2002)) + self.failUnless(time.tzname[0] in ('EST','AEST')) + self.failUnless(time.tzname[1] in ('EST','EDT','AEDT')) + self.failUnlessEqual(len(time.tzname),2) + self.failUnlessEqual(time.daylight,1) + self.failUnlessEqual(time.timezone,-36000) + self.failUnlessEqual(time.altzone,-39600) + self.failUnlessEqual(time.localtime(xmas2002).tm_isdst,1) + + # Get some times from a timezone that isn't wallclock timezone + del environ['TZ'] + time.tzset() + if time.timezone == 0: + environ['TZ'] = 'US/Eastern' + else: + environ['TZ'] = 'UTC' + time.tzset() + nonlocal = time.localtime(xmas2002) + + # Then the same time in wallclock timezone + del environ['TZ'] + time.tzset() + local = time.localtime(xmas2002) + + # And make sure they arn't the same + self.failIfEqual(local,nonlocal) + + # Do some basic sanity checking after wallclock time set + self.failUnlessEqual(len(time.tzname),2) + time.daylight + time.timezone + time.altzone + finally: + # Repair TZ environment variable in case any other tests + # rely on it. + if org_TZ is not None: + environ['TZ'] = org_TZ + elif environ.has_key('TZ'): + del environ['TZ'] + def test_main(): From gvanrossum@users.sourceforge.net Fri Mar 14 21:52:06 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Fri, 14 Mar 2003 13:52:06 -0800 Subject: [Python-checkins] python/dist/src configure,1.381,1.382 configure.in,1.392,1.393 pyconfig.h.in,1.72,1.73 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv14617 Modified Files: configure configure.in pyconfig.h.in Log Message: - New function time.tzset() provides access to the C library tzet() function, if supported. (SF patch #675422, by Stuart Bishop.) Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.381 retrieving revision 1.382 diff -C2 -d -r1.381 -r1.382 *** configure 25 Feb 2003 13:14:43 -0000 1.381 --- configure 14 Mar 2003 21:51:20 -0000 1.382 *************** *** 1,4 **** #! /bin/sh ! # From configure.in Revision: 1.391 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.53 for python 2.3. --- 1,4 ---- #! /bin/sh ! # From configure.in Revision: 1.392 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.53 for python 2.3. *************** *** 16547,16550 **** --- 16547,16618 ---- cat >>confdefs.h <<\_ACEOF #define HAVE_BROKEN_NICE 1 + _ACEOF + + fi + + # tzset(3) exists and works like we expect it to + echo "$as_me:$LINENO: checking for working tzset()" >&5 + echo $ECHO_N "checking for working tzset()... $ECHO_C" >&6 + if test "${ac_cv_working_tzset+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 + else + + if test "$cross_compiling" = yes; then + ac_cv_working_tzset=no + else + cat >conftest.$ac_ext <<_ACEOF + #line $LINENO "configure" + #include "confdefs.h" + + #include + #include + int main() + { + int gmt_hour; + int eastern_hour; + time_t now; + now = time((time_t*)NULL); + putenv("TZ=GMT"); + tzset(); + gmt_hour = localtime(&now)->tm_hour; + putenv("TZ=US/Eastern"); + tzset(); + eastern_hour = localtime(&now)->tm_hour; + if (eastern_hour == gmt_hour) + exit(1); + exit(0); + } + + _ACEOF + rm -f conftest$ac_exeext + if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_working_tzset=yes + else + echo "$as_me: program exited with status $ac_status" >&5 + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ( exit $ac_status ) + ac_cv_working_tzset=no + fi + rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext + fi + fi + + echo "$as_me:$LINENO: result: $ac_cv_working_tzset" >&5 + echo "${ECHO_T}$ac_cv_working_tzset" >&6 + if test "$ac_cv_working_tzset" = yes + then + + cat >>confdefs.h <<\_ACEOF + #define HAVE_WORKING_TZSET 1 _ACEOF Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.392 retrieving revision 1.393 diff -C2 -d -r1.392 -r1.393 *** configure.in 25 Feb 2003 13:14:42 -0000 1.392 --- configure.in 14 Mar 2003 21:51:31 -0000 1.393 *************** *** 2501,2504 **** --- 2501,2537 ---- fi + # tzset(3) exists and works like we expect it to + AC_MSG_CHECKING(for working tzset()) + AC_CACHE_VAL(ac_cv_working_tzset, [ + AC_TRY_RUN([ + #include + #include + int main() + { + int gmt_hour; + int eastern_hour; + time_t now; + now = time((time_t*)NULL); + putenv("TZ=GMT"); + tzset(); + gmt_hour = localtime(&now)->tm_hour; + putenv("TZ=US/Eastern"); + tzset(); + eastern_hour = localtime(&now)->tm_hour; + if (eastern_hour == gmt_hour) + exit(1); + exit(0); + } + ], + ac_cv_working_tzset=yes, + ac_cv_working_tzset=no, + ac_cv_working_tzset=no)]) + AC_MSG_RESULT($ac_cv_working_tzset) + if test "$ac_cv_working_tzset" = yes + then + AC_DEFINE(HAVE_WORKING_TZSET, 1, + [Define if tzset() actually switches the local timezone in a meaningful way.]) + fi + # Look for subsecond timestamps in struct stat AC_MSG_CHECKING(for tv_nsec in struct stat) Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.72 retrieving revision 1.73 diff -C2 -d -r1.72 -r1.73 *** pyconfig.h.in 19 Feb 2003 15:25:10 -0000 1.72 --- pyconfig.h.in 14 Mar 2003 21:51:32 -0000 1.73 *************** *** 614,617 **** --- 614,621 ---- #undef HAVE_WCSCOLL + /* Define if tzset() actually switches the local timezone in a meaningful way. + */ + #undef HAVE_WORKING_TZSET + /* Define to 1 if you have the `_getpty' function. */ #undef HAVE__GETPTY From cliffwells18@users.sourceforge.net Sat Mar 15 00:42:49 2003 From: cliffwells18@users.sourceforge.net (cliffwells18@users.sourceforge.net) Date: Fri, 14 Mar 2003 16:42:49 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/util sniffer.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/util In directory sc8-pr-cvs1:/tmp/cvs-serv16961 Modified Files: sniffer.py Log Message: Fixed return value of delim when there's only a single column (return '' rather than None). Index: sniffer.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/util/sniffer.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** sniffer.py 14 Mar 2003 21:10:27 -0000 1.3 --- sniffer.py 15 Mar 2003 00:42:46 -0000 1.4 *************** *** 9,12 **** --- 9,13 ---- import re + # ------------------------------------------------------------------------------ class Sniffer: """ *************** *** 57,60 **** --- 58,62 ---- """ + matches = [] for restr in ('(?P[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?P=delim)', # ,".*?", '(?:^|\n)(?P["\']).*?(?P=quote)(?P[^\w\n"\'])(?P ?)', # ".*?", *************** *** 99,103 **** skipinitialspace = delims[delim] == spaces if delim == '\n': # most likely a file with a single column ! delim = None else: # there is *no* delimiter, it's a single column of quoted data --- 101,105 ---- skipinitialspace = delims[delim] == spaces if delim == '\n': # most likely a file with a single column ! delim = '' else: # there is *no* delimiter, it's a single column of quoted data *************** *** 198,201 **** --- 200,274 ---- + # ------------------------------------------------------------------------------ + def hasHeaders(data, columns = 0): + """ + PROTOTYPE: + hasHeaders(data, columns = 0) + DESCRIPTION: + Decides whether row 0 is a header row + ARGUMENTS: + - data is a list of lists of data (as returned by importDSV) + - columns is either the expected number of columns in each row or 0 + RETURNS: + - true if data has header row + """ + + # Algorithm: creates a dictionary of types of data in each column. If any column + # is of a single type (say, integers), *except* for the first row, then the first + # row is presumed to be labels. If the type can't be determined, it is assumed to + # be a string in which case the length of the string is the determining factor: if + # all of the rows except for the first are the same length, it's a header. + # Finally, a 'vote' is taken at the end for each column, adding or subtracting from + # the likelihood of the first row being a header. + + if type(data) != type([]): + raise InvalidData, "list expected." + if len(data) < 2: return 0 + + if not columns: + columns = modeOfLengths(data) + + columnTypes = {} + for i in range(columns): columnTypes[i] = None + + for row in data[1:]: + if len(row) != columns: + continue # skip rows that have irregular number of columns + for col in columnTypes.keys(): + try: + try: + # is it a built-in type (besides string)? + thisType = type(eval(row[col])) + except OverflowError: + # a long int? + thisType = type(eval(row[col] + 'L')) + thisType = type(0) # treat long ints as int + except: + # fallback to length of string + thisType = len(row[col]) + + if thisType != columnTypes[col]: + if columnTypes[col] is None: # add new column type + columnTypes[col] = thisType + else: # type is inconsistent, remove column from consideration + del columnTypes[col] + + # finally, compare results against first row and vote on whether it's a header + hasHeader = 0 + for col, colType in columnTypes.items(): + if type(colType) == type(0): # it's a length + if len(data[0][col]) != colType: + hasHeader += 1 + else: + hasHeader -= 1 + else: # attempt typecast + try: + eval("%s(%s)" % (colType.__name__, data[0][col])) + except: + hasHeader += 1 + else: + hasHeader -= 1 + + return hasHeader > 0 From cliffwells18@users.sourceforge.net Sat Mar 15 01:08:24 2003 From: cliffwells18@users.sourceforge.net (cliffwells18@users.sourceforge.net) Date: Fri, 14 Mar 2003 17:08:24 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/util sniffer.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/util In directory sc8-pr-cvs1:/tmp/cvs-serv25919 Modified Files: sniffer.py Log Message: Working but inefficient hasHeaders() function. Index: sniffer.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/util/sniffer.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** sniffer.py 15 Mar 2003 00:42:46 -0000 1.4 --- sniffer.py 15 Mar 2003 01:08:21 -0000 1.5 *************** *** 201,217 **** # ------------------------------------------------------------------------------ ! def hasHeaders(data, columns = 0): ! """ ! PROTOTYPE: ! hasHeaders(data, columns = 0) ! DESCRIPTION: ! Decides whether row 0 is a header row ! ARGUMENTS: ! - data is a list of lists of data (as returned by importDSV) ! - columns is either the expected number of columns in each row or 0 ! RETURNS: ! - true if data has header row ! """ ! # Algorithm: creates a dictionary of types of data in each column. If any column # is of a single type (say, integers), *except* for the first row, then the first --- 201,205 ---- # ------------------------------------------------------------------------------ ! def hasHeaders(fileObj, dialect): # Algorithm: creates a dictionary of types of data in each column. If any column # is of a single type (say, integers), *except* for the first row, then the first *************** *** 222,236 **** # the likelihood of the first row being a header. ! if type(data) != type([]): ! raise InvalidData, "list expected." ! if len(data) < 2: return 0 ! if not columns: ! columns = modeOfLengths(data) columnTypes = {} for i in range(columns): columnTypes[i] = None ! for row in data[1:]: if len(row) != columns: continue # skip rows that have irregular number of columns --- 210,232 ---- # the likelihood of the first row being a header. ! def seval(item): ! """ ! Strips parens from item prior to calling eval in an attempt to make it safer ! """ ! item = item.replace('(', '').replace(')', '') ! return eval(item) ! reader = csv.reader(fileObj, ! delimiter = dialect.delimiter, ! quotechar = dialect.quotechar, ! skipinitialspace = dialect.skipinitialspace) + header = reader.next() # assume first row is header + + columns = len(header) columnTypes = {} for i in range(columns): columnTypes[i] = None ! for row in reader: if len(row) != columns: continue # skip rows that have irregular number of columns *************** *** 239,246 **** try: # is it a built-in type (besides string)? ! thisType = type(eval(row[col])) except OverflowError: # a long int? ! thisType = type(eval(row[col] + 'L')) thisType = type(0) # treat long ints as int except: --- 235,242 ---- try: # is it a built-in type (besides string)? ! thisType = type(seval(row[col])) except OverflowError: # a long int? ! thisType = type(seval(row[col] + 'L')) thisType = type(0) # treat long ints as int except: *************** *** 254,262 **** del columnTypes[col] ! # finally, compare results against first row and vote on whether it's a header hasHeader = 0 for col, colType in columnTypes.items(): if type(colType) == type(0): # it's a length ! if len(data[0][col]) != colType: hasHeader += 1 else: --- 250,258 ---- del columnTypes[col] ! # finally, compare results against first row and "vote" on whether it's a header hasHeader = 0 for col, colType in columnTypes.items(): if type(colType) == type(0): # it's a length ! if len(header[col]) != colType: hasHeader += 1 else: *************** *** 264,268 **** else: # attempt typecast try: ! eval("%s(%s)" % (colType.__name__, data[0][col])) except: hasHeader += 1 --- 260,264 ---- else: # attempt typecast try: ! eval("%s(%s)" % (colType.__name__, header[col])) except: hasHeader += 1 From cliffwells18@users.sourceforge.net Sat Mar 15 01:15:05 2003 From: cliffwells18@users.sourceforge.net (cliffwells18@users.sourceforge.net) Date: Fri, 14 Mar 2003 17:15:05 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/util sniffer.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/util In directory sc8-pr-cvs1:/tmp/cvs-serv27901 Modified Files: sniffer.py Log Message: Added arbitrary limit to hasHeaders(). Index: sniffer.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/util/sniffer.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** sniffer.py 15 Mar 2003 01:08:21 -0000 1.5 --- sniffer.py 15 Mar 2003 01:15:03 -0000 1.6 *************** *** 214,219 **** Strips parens from item prior to calling eval in an attempt to make it safer """ ! item = item.replace('(', '').replace(')', '') ! return eval(item) reader = csv.reader(fileObj, --- 214,218 ---- Strips parens from item prior to calling eval in an attempt to make it safer """ ! return eval(item.replace('(', '').replace(')', '')) reader = csv.reader(fileObj, *************** *** 227,234 **** columnTypes = {} for i in range(columns): columnTypes[i] = None ! for row in reader: if len(row) != columns: continue # skip rows that have irregular number of columns for col in columnTypes.keys(): try: --- 226,239 ---- columnTypes = {} for i in range(columns): columnTypes[i] = None ! ! checked = 0 for row in reader: + if checked > 20: # arbitrary number of rows to check, to keep it sane + break + checked += 1 + if len(row) != columns: continue # skip rows that have irregular number of columns + for col in columnTypes.keys(): try: From gvanrossum@users.sourceforge.net Sat Mar 15 12:01:55 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Sat, 15 Mar 2003 04:01:55 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_time.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv28372 Modified Files: test_time.py Log Message: If time.tzset doesn't exist, don't test it. Index: test_time.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_time.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_time.py 14 Mar 2003 21:51:33 -0000 1.12 --- test_time.py 15 Mar 2003 12:01:52 -0000 1.13 *************** *** 54,57 **** --- 54,60 ---- def test_tzset(self): + if not hasattr(time, "tzset"): + return # Can't test this; don't want the test suite to fail + from os import environ From gvanrossum@users.sourceforge.net Sat Mar 15 12:25:02 2003 From: gvanrossum@users.sourceforge.net (gvanrossum@users.sourceforge.net) Date: Sat, 15 Mar 2003 04:25:02 -0800 Subject: [Python-checkins] python/dist/src/Lib timeit.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory sc8-pr-cvs1:/tmp/cvs-serv1863 Modified Files: timeit.py Log Message: Change the default number of repetitions to 3, both in the Timer class (from 10) and in main() (from 1). Add a -v option that shows the raw times. Repeating it cranks up the display precision. Always use the "best of N" form of output. Index: timeit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/timeit.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** timeit.py 14 Mar 2003 17:21:00 -0000 1.7 --- timeit.py 15 Mar 2003 12:25:00 -0000 1.8 *************** *** 12,19 **** Options: -n/--number N: how many times to execute 'statement' (default: see below) ! -r/--repeat N: how many times to repeat the timer (default 1) -s/--setup S: statement to be executed once initially (default 'pass') -t/--time: use time.time() (default on Unix) -c/--clock: use time.clock() (default on Windows) -h/--help: print this usage message and exit statement: statement to be timed (default 'pass') --- 12,20 ---- Options: -n/--number N: how many times to execute 'statement' (default: see below) ! -r/--repeat N: how many times to repeat the timer (default 3) -s/--setup S: statement to be executed once initially (default 'pass') -t/--time: use time.time() (default on Unix) -c/--clock: use time.clock() (default on Windows) + -v/--verbose: print raw timing results; repeat for more digits precision -h/--help: print this usage message and exit statement: statement to be timed (default 'pass') *************** *** 34,39 **** other processes running on the same computer may interfere with the timing. The best thing to do when accurate timing is necessary is to ! repeat the timing a few times and use the best time; the -r option is ! good for this. On Unix, you can use clock() to measure CPU time. Note: there is a certain baseline overhead associated with executing a --- 35,41 ---- other processes running on the same computer may interfere with the timing. The best thing to do when accurate timing is necessary is to ! repeat the timing a few times and use the best time. The -r option is ! good for this; the default of 3 repetitions is probably enough in most ! cases. On Unix, you can use clock() to measure CPU time. Note: there is a certain baseline overhead associated with executing a *************** *** 61,65 **** dummy_src_name = "" default_number = 1000000 ! default_repeat = 10 if sys.platform == "win32": --- 63,67 ---- dummy_src_name = "" default_number = 1000000 ! default_repeat = 3 if sys.platform == "win32": *************** *** 160,164 **** This is a convenience function that calls the timer() repeatedly, returning a list of results. The first argument ! specifies how many times to call timer(), defaulting to 10; the second argument specifies the timer argument, defaulting to one million. --- 162,166 ---- This is a convenience function that calls the timer() repeatedly, returning a list of results. The first argument ! specifies how many times to call timer(), defaulting to 3; the second argument specifies the timer argument, defaulting to one million. *************** *** 198,204 **** import getopt try: ! opts, args = getopt.getopt(args, "n:s:r:tch", ["number=", "setup=", "repeat=", ! "time", "clock", "help"]) except getopt.error, err: print err --- 200,206 ---- import getopt try: ! opts, args = getopt.getopt(args, "n:s:r:tcvh", ["number=", "setup=", "repeat=", ! "time", "clock", "verbose", "help"]) except getopt.error, err: print err *************** *** 209,213 **** number = 0 # auto-determine setup = [] ! repeat = 1 for o, a in opts: if o in ("-n", "--number"): --- 211,217 ---- number = 0 # auto-determine setup = [] ! repeat = default_repeat ! verbose = 0 ! precision = 3 for o, a in opts: if o in ("-n", "--number"): *************** *** 223,226 **** --- 227,234 ---- if o in ("-c", "--clock"): timer = time.clock + if o in ("-v", "--verbose"): + if verbose: + precision += 1 + verbose += 1 if o in ("-h", "--help"): print __doc__, *************** *** 237,240 **** --- 245,250 ---- t.print_exc() return 1 + if verbose: + print "%d loops -> %.*g secs" % (number, precision, x) if x >= 0.2: break *************** *** 245,254 **** return 1 best = min(r) print "%d loops," % number, usec = best * 1e6 / number ! if repeat > 1: ! print "best of %d: %.3f usec per loop" % (repeat, usec) ! else: ! print "time: %.3f usec per loop" % usec return None --- 255,263 ---- return 1 best = min(r) + if verbose: + print "raw times:", " ".join(["%.*g" % (precision, x) for x in r]) print "%d loops," % number, usec = best * 1e6 / number ! print "best of %d: %.*g usec per loop" % (repeat, precision, usec) return None From rhettinger@users.sourceforge.net Sun Mar 16 03:11:07 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sat, 15 Mar 2003 19:11:07 -0800 Subject: [Python-checkins] python/dist/src/Python ceval.c,2.354,2.355 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv12161 Modified Files: ceval.c Log Message: Introduced macros for a simple opcode prediction protocol. Applied to common cases: COMPARE_OP is often followed by a JUMP_IF. JUMP_IF is usually followed by POP_TOP. Shows improved timings on PyStone, PyBench, and specific tests using timeit.py: python timeit.py -s "x=1" "if x==1: pass" python timeit.py -s "x=1" "if x==2: pass" python timeit.py -s "x=1" "if x: pass" python timeit.py -s "x=100" "while x!=1: x-=1" Potential future candidates: GET_ITER predicts FOR_ITER FOR_ITER predicts STORE_FAST or UNPACK_SEQUENCE Also, applied missing goto fast_next_opcode to DUP_TOPX. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.354 retrieving revision 2.355 diff -C2 -d -r2.354 -r2.355 *** ceval.c 14 Mar 2003 01:37:42 -0000 2.354 --- ceval.c 16 Mar 2003 03:11:04 -0000 2.355 *************** *** 603,606 **** --- 603,626 ---- #define JUMPBY(x) (next_instr += (x)) + /* OpCode prediction macros + Some opcodes tend to come in pairs thus making it possible to predict + the second code when the first is run. For example, COMPARE_OP is often + followed by JUMP_IF_FALSE or JUMP_IF_TRUE. And, those opcodes are often + followed by a POP_TOP. + + Verifying the prediction costs a single high-speed test of register + variable against a constant. If the pairing was good, then the odds + processor has a high likelihood of making its own successful branch + prediction which results in a nearly zero overhead transition to the + next opcode. + + A successful prediction saves a trip through the eval-loop including + its two unpredictable branches, the HASARG test and the switch-case. + */ + + #define PREDICT(op) if (*next_instr == op) goto PRED_##op + #define PREDICTED(op) PRED_##op: next_instr++ + #define PREDICTED_WITH_ARG(op) PRED_##op: oparg = (next_instr += 3, (next_instr[-1]<<8) + next_instr[-2]) + /* Stack manipulation macros */ *************** *** 874,877 **** --- 894,898 ---- goto fast_next_opcode; + PREDICTED(POP_TOP); case POP_TOP: v = POP(); *************** *** 921,925 **** SET_TOP(x); SET_SECOND(w); ! continue; } else if (oparg == 3) { x = TOP(); --- 942,946 ---- SET_TOP(x); SET_SECOND(w); ! goto fast_next_opcode; } else if (oparg == 3) { x = TOP(); *************** *** 933,937 **** SET_SECOND(w); SET_THIRD(v); ! continue; } Py_FatalError("invalid argument to DUP_TOPX" --- 954,958 ---- SET_SECOND(w); SET_THIRD(v); ! goto fast_next_opcode; } Py_FatalError("invalid argument to DUP_TOPX" *************** *** 1919,1924 **** Py_DECREF(w); SET_TOP(x); ! if (x != NULL) continue; ! break; case IMPORT_NAME: --- 1940,1947 ---- Py_DECREF(w); SET_TOP(x); ! if (x == NULL) break; ! PREDICT(JUMP_IF_FALSE); ! PREDICT(JUMP_IF_TRUE); ! continue; case IMPORT_NAME: *************** *** 1975,1982 **** goto fast_next_opcode; case JUMP_IF_FALSE: w = TOP(); ! if (w == Py_True) goto fast_next_opcode; if (w == Py_False) { JUMPBY(oparg); --- 1998,2008 ---- goto fast_next_opcode; + PREDICTED_WITH_ARG(JUMP_IF_FALSE); case JUMP_IF_FALSE: w = TOP(); ! if (w == Py_True) { ! PREDICT(POP_TOP); goto fast_next_opcode; + } if (w == Py_False) { JUMPBY(oparg); *************** *** 1992,1999 **** continue; case JUMP_IF_TRUE: w = TOP(); ! if (w == Py_False) goto fast_next_opcode; if (w == Py_True) { JUMPBY(oparg); --- 2018,2028 ---- continue; + PREDICTED_WITH_ARG(JUMP_IF_TRUE); case JUMP_IF_TRUE: w = TOP(); ! if (w == Py_False) { ! PREDICT(POP_TOP); goto fast_next_opcode; + } if (w == Py_True) { JUMPBY(oparg); From rhettinger@users.sourceforge.net Sun Mar 16 15:41:17 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 16 Mar 2003 07:41:17 -0800 Subject: [Python-checkins] python/dist/src/Python ceval.c,2.355,2.356 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv11890 Modified Files: ceval.c Log Message: Fix comment and whitespace. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.355 retrieving revision 2.356 diff -C2 -d -r2.355 -r2.356 *** ceval.c 16 Mar 2003 03:11:04 -0000 2.355 --- ceval.c 16 Mar 2003 15:41:11 -0000 2.356 *************** *** 610,614 **** Verifying the prediction costs a single high-speed test of register ! variable against a constant. If the pairing was good, then the odds processor has a high likelihood of making its own successful branch prediction which results in a nearly zero overhead transition to the --- 610,614 ---- Verifying the prediction costs a single high-speed test of register ! variable against a constant. If the pairing was good, then the processor has a high likelihood of making its own successful branch prediction which results in a nearly zero overhead transition to the *************** *** 619,625 **** */ ! #define PREDICT(op) if (*next_instr == op) goto PRED_##op #define PREDICTED(op) PRED_##op: next_instr++ ! #define PREDICTED_WITH_ARG(op) PRED_##op: oparg = (next_instr += 3, (next_instr[-1]<<8) + next_instr[-2]) /* Stack manipulation macros */ --- 619,626 ---- */ ! #define PREDICT(op) if (*next_instr == op) goto PRED_##op #define PREDICTED(op) PRED_##op: next_instr++ ! #define PREDICTED_WITH_ARG(op) PRED_##op: oparg = (next_instr += 3, \ ! (next_instr[-1]<<8) + next_instr[-2]) /* Stack manipulation macros */ From rhettinger@users.sourceforge.net Sun Mar 16 20:14:47 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Sun, 16 Mar 2003 12:14:47 -0800 Subject: [Python-checkins] python/dist/src/Python ceval.c,2.356,2.357 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv27026 Modified Files: ceval.c Log Message: Eliminate data dependency in predict macro. Added two predictions: GET_ITER --> FOR_ITER FOR_ITER --> STORE_FAST or UNPACK_SEQUENCE Improves timings on pybench and timeit.py. Pystone results are neutral. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.356 retrieving revision 2.357 diff -C2 -d -r2.356 -r2.357 *** ceval.c 16 Mar 2003 15:41:11 -0000 2.356 --- ceval.c 16 Mar 2003 20:14:44 -0000 2.357 *************** *** 621,626 **** #define PREDICT(op) if (*next_instr == op) goto PRED_##op #define PREDICTED(op) PRED_##op: next_instr++ ! #define PREDICTED_WITH_ARG(op) PRED_##op: oparg = (next_instr += 3, \ ! (next_instr[-1]<<8) + next_instr[-2]) /* Stack manipulation macros */ --- 621,626 ---- #define PREDICT(op) if (*next_instr == op) goto PRED_##op #define PREDICTED(op) PRED_##op: next_instr++ ! #define PREDICTED_WITH_ARG(op) PRED_##op: oparg = (next_instr[2]<<8) + \ ! next_instr[1]; next_instr += 3 /* Stack manipulation macros */ *************** *** 890,893 **** --- 890,894 ---- goto fast_next_opcode; + PREDICTED_WITH_ARG(STORE_FAST); case STORE_FAST: v = POP(); *************** *** 1676,1679 **** --- 1677,1681 ---- break; + PREDICTED_WITH_ARG(UNPACK_SEQUENCE); case UNPACK_SEQUENCE: v = POP(); *************** *** 2052,2055 **** --- 2054,2058 ---- if (x != NULL) { SET_TOP(x); + PREDICT(FOR_ITER); continue; } *************** *** 2057,2060 **** --- 2060,2064 ---- break; + PREDICTED_WITH_ARG(FOR_ITER); case FOR_ITER: /* before: [iter]; after: [iter, iter()] *or* [] */ *************** *** 2063,2066 **** --- 2067,2072 ---- if (x != NULL) { PUSH(x); + PREDICT(STORE_FAST); + PREDICT(UNPACK_SEQUENCE); continue; } From jackjansen@users.sourceforge.net Sun Mar 16 20:42:02 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 16 Mar 2003 12:42:02 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation/macpython_ide_tutorial index.html,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation/macpython_ide_tutorial In directory sc8-pr-cvs1:/tmp/cvs-serv6940 Modified Files: index.html Log Message: Lots of textual changes suggested by Matthew Moelter. Index: index.html =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation/macpython_ide_tutorial/index.html,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** index.html 11 Mar 2003 22:59:17 -0000 1.1 --- index.html 16 Mar 2003 20:41:58 -0000 1.2 *************** *** 14,18 ****

This document gives a very basic introduction to the ! MacPython Integrated Development Environment on Mac OS. It was written specifically for MacPython 2.3 on Mac OS X, but most of it is applicable to MacPython-OS9 too. It is based on --- 14,18 ----

This document gives a very basic introduction to the ! MacPython Integrated Development Environment (IDE) on Mac OS. It was written specifically for MacPython 2.3 on Mac OS X, but most of it is applicable to MacPython-OS9 too. It is based on *************** *** 48,52 ****

This is the interactive window to the IDE, it allows us to enter commands directly into Python, and as soon as we enter a command, ! Python will execute it and spit out its result back to us. We'll be using this interactive window a lot when we're exploring Python: it's very nice because we get back our results immediately. If it helps, --- 48,52 ----

This is the interactive window to the IDE, it allows us to enter commands directly into Python, and as soon as we enter a command, ! Python will execute it and spit its result back to us. We'll be using this interactive window a lot when we're exploring Python: it's very nice because we get back our results immediately. If it helps, *************** *** 87,91 **** the computer to remember what we typed?

!

The solution is a little subtle: we can't directly save what's on the interpreter window, because it will include both our commands and the system's responses. What we'd like is to make a prepared file, --- 87,91 ---- the computer to remember what we typed?

!

The solution is a little subtle: we can't directly save what's in the interpreter window, because it will include both our commands and the system's responses. What we'd like is to make a prepared file, *************** *** 114,118 ****

What we wanted to do before was save some of the stuff we had tried out on the interpreter window. Let's do that by typing (or ! copy/pasting) those commands into our Program window.

--- 114,118 ----

What we wanted to do before was save some of the stuff we had tried out on the interpreter window. Let's do that by typing (or ! copy/pasting) those commands into our edit window.

*************** *** 120,124 **** One big thing to notice is that we're careful to get rid of the ">>>" ! prompts because there's not really part of our program. The interpreter uses them just to tell us that we're in the interpreter, but now that we're editing in a separate file, we can remove the --- 120,124 ---- One big thing to notice is that we're careful to get rid of the ">>>" ! prompts because they're not really part of our program. The interpreter uses them just to tell us that we're in the interpreter, but now that we're editing in a separate file, we can remove the *************** *** 130,134 ****

!

Let's save the file now. The Save command is located under the File menu:

--- 130,134 ----

!

Let's save the file now. The Save command is located under the File menu:

*************** *** 156,165 ****

Python is often perceptive enough to direct us toward the problem, and in this case, it's telling us that we forgot to put something at ! the end of this line. In this case, we need to add an additional ! quotation mark. Let's add that in now.

Other errors, which usually occur later, when your program has already done something, result in a different dialog that allows you ! to look at variables and such in addition to only showing you where the error occurred.

--- 156,165 ----

Python is often perceptive enough to direct us toward the problem, and in this case, it's telling us that we forgot to put something at ! the end of this line. In this case, we need to add a ! quotation mark at the end. Let's add that in now.

Other errors, which usually occur later, when your program has already done something, result in a different dialog that allows you ! to look at variables and such in addition to showing you where the error occurred.

*************** *** 174,180 ****

As we play with Python, we'll find ourselves "switching modes" ! between the Interpreter window and the Program window. However, if we try anything more complicated than two or three lines it ! is often a good idea to work in an edit window, and align your edit and output window such that you can see them at the same time.

--- 174,180 ----

As we play with Python, we'll find ourselves "switching modes" ! between the Interpreter window and the edit window. However, if we try anything more complicated than two or three lines it ! is often a good idea to work in an edit window. Align your edit and output window such that you can see them at the same time.

*************** *** 185,192 ****
  • All sorts of edit commands such as find and replace can be ! used in the editor windows. See the edit menu.
  • The bottom of the edit window has the scrollbar, but at the ! left are two navigation devices: a line number box that you can also type numbers into to quickly go to a specific place, and a popup menu that lists all classes, functions and methods in your file.
  • --- 185,192 ----
    • All sorts of edit commands such as find and replace can be ! used in the editor windows. See the Edit menu.
    • The bottom of the edit window has the scrollbar, but at the ! left are two navigation devices: a line number box that you can type numbers into to quickly go to a specific place, and a popup menu that lists all classes, functions and methods in your file.
    • From jackjansen@users.sourceforge.net Sun Mar 16 21:04:55 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 16 Mar 2003 13:04:55 -0800 Subject: [Python-checkins] python/dist/src/Mac/Tools/IDE PackageManager.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory sc8-pr-cvs1:/tmp/cvs-serv15759 Modified Files: PackageManager.py Log Message: - Don't ask for bring-to-front when quitting through an appleevent. - Changed checkbox labels as suggested by Kevin Ollivier. Index: PackageManager.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PackageManager.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** PackageManager.py 28 Feb 2003 15:19:51 -0000 1.4 --- PackageManager.py 16 Mar 2003 21:04:50 -0000 1.5 *************** *** 111,116 **** def quitevent(self, theAppleEvent, theReply): - from Carbon import AE - AE.AEInteractWithUser(50000000) self._quit() --- 111,114 ---- *************** *** 273,277 **** def setupwidgets(self): ! self.w = W.Window((580, 400), "Python Install Manager", minsize = (300, 200), tabbable = 0) ## self.w.divline = W.HorizontalLine((0, 20, 0, 0)) self.w.titlebar = W.TextBox((4, 4, 40, 12), 'Packages:') --- 271,275 ---- def setupwidgets(self): ! self.w = W.Window((580, 400), "Python Install Manager", minsize = (400, 200), tabbable = 0) ## self.w.divline = W.HorizontalLine((0, 20, 0, 0)) self.w.titlebar = W.TextBox((4, 4, 40, 12), 'Packages:') *************** *** 283,290 **** self.w.message = W.TextBox((64, -48, 0, 12), '') self.w.homepage_button = W.Button((4, -28, 96, 18), 'View homepage', self.do_homepage) ! self.w.verbose_button = W.CheckBox((-288, -26, 60, 18), 'Verbose') ! self.w.recursive_button = W.CheckBox((-224, -26, 80, 18), 'Recursive', self.updatestatus) self.w.recursive_button.set(1) ! self.w.force_button = W.CheckBox((-140, -26, 60, 18), 'Force', self.updatestatus) self.w.install_button = W.Button((-76, -28, 56, 18), 'Install', self.do_install) self.w.open() --- 281,288 ---- self.w.message = W.TextBox((64, -48, 0, 12), '') self.w.homepage_button = W.Button((4, -28, 96, 18), 'View homepage', self.do_homepage) ! self.w.verbose_button = W.CheckBox((-358, -26, 60, 18), 'Verbose') ! self.w.recursive_button = W.CheckBox((-284, -26, 140, 18), 'Install dependencies', self.updatestatus) self.w.recursive_button.set(1) ! self.w.force_button = W.CheckBox((-160, -26, 80, 18), 'Overwrite', self.updatestatus) self.w.install_button = W.Button((-76, -28, 56, 18), 'Install', self.do_install) self.w.open() From jackjansen@users.sourceforge.net Sun Mar 16 22:09:24 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 16 Mar 2003 14:09:24 -0800 Subject: [Python-checkins] python/dist/src/Mac/Tools/IDE PythonIDEMain.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory sc8-pr-cvs1:/tmp/cvs-serv9930/Mac/Tools/IDE Modified Files: PythonIDEMain.py Log Message: The MacPython introductory help is now called MacPython Help, and the optional full documentation Python Documentation. Index: PythonIDEMain.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PythonIDEMain.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** PythonIDEMain.py 3 Mar 2003 12:28:04 -0000 1.31 --- PythonIDEMain.py 16 Mar 2003 22:09:21 -0000 1.32 *************** *** 354,363 **** def makehelpmenu(self): ! docs = self.installdocumentation() self.helpmenu = m = self.gethelpmenu() docitem = FrameWork.MenuItem(m, "Python Documentation", None, self.domenu_localdocs) ! docitem.enable(docs) finditem = FrameWork.MenuItem(m, "Lookup in Python Documentation", None, 'lookuppython') ! finditem.enable(docs) if runningOnOSX(): FrameWork.Separator(m) --- 354,365 ---- def makehelpmenu(self): ! hashelp, hasdocs = self.installdocumentation() self.helpmenu = m = self.gethelpmenu() + helpitem = FrameWork.MenuItem(m, "MacPython Help", None, self.domenu_localhelp) + helpitem.enable(hashelp) docitem = FrameWork.MenuItem(m, "Python Documentation", None, self.domenu_localdocs) ! docitem.enable(hasdocs) finditem = FrameWork.MenuItem(m, "Lookup in Python Documentation", None, 'lookuppython') ! finditem.enable(hasdocs) if runningOnOSX(): FrameWork.Separator(m) *************** *** 371,375 **** def domenu_localdocs(self, *args): from Carbon import AH ! AH.AHGotoPage("Python Help", None, None) def domenu_appledocs(self, *args): --- 373,381 ---- def domenu_localdocs(self, *args): from Carbon import AH ! AH.AHGotoPage("Python Documentation", None, None) ! ! def domenu_localhelp(self, *args): ! from Carbon import AH ! AH.AHGotoPage("MacPython Help", None, None) def domenu_appledocs(self, *args): *************** *** 389,393 **** return try: ! AH.AHSearch("Python Help", searchstring) except AH.Error, arg: W.Message("AppleHelp Error: %s" % `arg`) --- 395,399 ---- return try: ! AH.AHSearch("Python Documentation", searchstring) except AH.Error, arg: W.Message("AppleHelp Error: %s" % `arg`) *************** *** 442,455 **** # the plist file) we refer it to Python.app python_app = os.path.join(sys.prefix, 'Resources/Python.app') ! doc_source = os.path.join(python_app, 'Contents/Resources/English.lproj/Documentation') ! if not os.path.isdir(doc_source): ! return 0 ! try: ! from Carbon import AH ! AH.AHRegisterHelpBook(python_app) ! except (ImportError, MacOS.Error), arg: ! W.Message("Cannot register Python documentation: %s" % `arg`) ! return 0 ! return 1 --- 448,462 ---- # the plist file) we refer it to Python.app python_app = os.path.join(sys.prefix, 'Resources/Python.app') ! help_source = os.path.join(python_app, 'Contents/Resources/English.lproj/Documentation') ! doc_source = os.path.join(python_app, 'Contents/Resources/English.lproj/PythonDocumentation') ! has_help = os.path.isdir(help_source) ! has_doc = os.path.isdir(doc_source) ! if has_help or has_doc: ! try: ! from Carbon import AH ! AH.AHRegisterHelpBook(python_app) ! except (ImportError, MacOS.Error), arg: ! pass # W.Message("Cannot register Python Documentation: %s" % str(arg)) ! return has_help, has_doc From jackjansen@users.sourceforge.net Sun Mar 16 22:09:24 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 16 Mar 2003 14:09:24 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSXResources/app Info.plist,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app In directory sc8-pr-cvs1:/tmp/cvs-serv9930/Mac/OSXResources/app Modified Files: Info.plist Log Message: The MacPython introductory help is now called MacPython Help, and the optional full documentation Python Documentation. Index: Info.plist =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/OSXResources/app/Info.plist,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** Info.plist 5 Mar 2003 16:13:19 -0000 1.9 --- Info.plist 16 Mar 2003 22:09:22 -0000 1.10 *************** *** 33,39 **** Documentation CFBundleHelpBookName ! Python Help CFBundleHelpTOCFile index.html --- 33,40 ---- Documentation + PythonDocumentation CFBundleHelpBookName ! MacPython Help CFBundleHelpTOCFile index.html From jackjansen@users.sourceforge.net Sun Mar 16 22:09:24 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 16 Mar 2003 14:09:24 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation index.html,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation In directory sc8-pr-cvs1:/tmp/cvs-serv9930/Mac/OSXResources/app/Resources/English.lproj/Documentation Modified Files: index.html Log Message: The MacPython introductory help is now called MacPython Help, and the optional full documentation Python Documentation. Index: index.html =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj/Documentation/index.html,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** index.html 11 Mar 2003 22:59:16 -0000 1.1 --- index.html 16 Mar 2003 22:09:22 -0000 1.2 *************** *** 8,12 **** ! --- 8,12 ---- ! From jackjansen@users.sourceforge.net Sun Mar 16 22:09:25 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Sun, 16 Mar 2003 14:09:25 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSX/Doc setup.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSX/Doc In directory sc8-pr-cvs1:/tmp/cvs-serv9930/Mac/OSX/Doc Modified Files: setup.py Log Message: The MacPython introductory help is now called MacPython Help, and the optional full documentation Python Documentation. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/OSX/Doc/setup.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** setup.py 14 Feb 2003 23:46:22 -0000 1.1 --- setup.py 16 Mar 2003 22:09:22 -0000 1.2 *************** *** 33,37 **** self.build_dest = None self.download = 1 ! self.doc_version = '2.2.1' def finalize_options(self): --- 33,37 ---- self.build_dest = None self.download = 1 ! self.doc_version = '2.2.2' def finalize_options(self): *************** *** 47,57 **** def downloadDocs(self): workdir = os.getcwd() ! self.mkpath(self.build_html) os.chdir(self.build_base) ! self.spawn('curl','-O', 'http://www.python.org/ftp/python/doc/%s/html-%s.tgz' % (self.doc_version,self.doc_version)) ! os.chdir(workdir) ! os.chdir(self.build_html) ! self.spawn('tar', '-xzf', '../html-%s.tgz' % self.doc_version) os.chdir(workdir) def buildDocsFromSource(self): --- 47,64 ---- def downloadDocs(self): workdir = os.getcwd() ! url = 'http://www.python.org/ftp/python/doc/%s/html-%s.tgz' % \ ! (self.doc_version,self.doc_version) os.chdir(self.build_base) ! self.spawn('curl','-O', url) os.chdir(workdir) + tarfile = 'html-%s.tgz' % self.doc_version + ## This no longer works due to name changes + ## self.mkpath(self.build_html) + ## os.chdir(self.build_html) + ## self.spawn('tar', '-xzf', '../' + tarfile) + ## os.chdir(workdir) + print "** Please unpack %s" % os.path.join(self.build_base, tarfile) + print "** Unpack the files into %s" % self.build_html + raise RuntimeError, "You need to unpack the docs manually" def buildDocsFromSource(self): *************** *** 76,80 **** origIndex = file(os.path.join(self.build_html,ind_html)) r = re.compile('', re.DOTALL) ! hackedIndex.write(r.sub('',origIndex.read())) def hackFile(self,d,f): --- 83,87 ---- origIndex = file(os.path.join(self.build_html,ind_html)) r = re.compile('', re.DOTALL) ! hackedIndex.write(r.sub('',origIndex.read())) def hackFile(self,d,f): *************** *** 108,111 **** --- 115,119 ---- def run(self): self.ensure_finalized() + self.mkpath(self.build_base) self.ensureHtml() if not os.path.isdir(self.build_html): *************** *** 143,147 **** self.build_dest = build_cmd.build_dest if self.install_doc == None: ! self.install_doc = os.path.join(self.prefix, 'Resources/English.lproj/Documentation') print 'INSTALL', self.build_dest, '->', self.install_doc --- 151,155 ---- self.build_dest = build_cmd.build_dest if self.install_doc == None: ! self.install_doc = os.path.join(self.prefix, 'Resources/Python.app/Contents/Resources/English.lproj/PythonDocumentation') print 'INSTALL', self.build_dest, '->', self.install_doc From rhettinger@users.sourceforge.net Mon Mar 17 08:22:58 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 17 Mar 2003 00:22:58 -0800 Subject: [Python-checkins] python/dist/src/Include object.h,2.113,2.114 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv29413/Include Modified Files: object.h Log Message: Created PyObject_GenericGetIter(). Factors out the common case of returning self. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.113 retrieving revision 2.114 diff -C2 -d -r2.113 -r2.114 *** object.h 7 Mar 2003 15:13:16 -0000 2.113 --- object.h 17 Mar 2003 08:22:55 -0000 2.114 *************** *** 386,389 **** --- 386,390 ---- PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); + PyAPI_FUNC(PyObject *) PyObject_GenericGetIter(PyObject *); PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, From rhettinger@users.sourceforge.net Mon Mar 17 08:22:59 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 17 Mar 2003 00:22:59 -0800 Subject: [Python-checkins] python/dist/src/Objects object.c,2.199,2.200 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv29413/Objects Modified Files: object.c Log Message: Created PyObject_GenericGetIter(). Factors out the common case of returning self. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.199 retrieving revision 2.200 diff -C2 -d -r2.199 -r2.200 *** object.c 19 Feb 2003 03:19:29 -0000 2.199 --- object.c 17 Mar 2003 08:22:56 -0000 2.200 *************** *** 1302,1305 **** --- 1302,1312 ---- PyObject * + PyObject_GenericGetIter(PyObject *obj) + { + Py_INCREF(obj); + return obj; + } + + PyObject * PyObject_GenericGetAttr(PyObject *obj, PyObject *name) { From rhettinger@users.sourceforge.net Mon Mar 17 08:23:00 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 17 Mar 2003 00:23:00 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.696,1.697 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv29413/Misc Modified Files: NEWS Log Message: Created PyObject_GenericGetIter(). Factors out the common case of returning self. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.696 retrieving revision 1.697 diff -C2 -d -r1.696 -r1.697 *** NEWS 14 Mar 2003 21:51:35 -0000 1.696 --- NEWS 17 Mar 2003 08:22:57 -0000 1.697 *************** *** 87,90 **** --- 87,93 ---- ----- + - Added PyObject_GenericGetIter() to fill the tp_iter slot for the + typical case where the method returns its self argument. + - The extended type structure used for heap types (new-style classes defined by Python code using a class statement) is now From rhettinger@users.sourceforge.net Mon Mar 17 08:22:59 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 17 Mar 2003 00:22:59 -0800 Subject: [Python-checkins] python/dist/src/Modules itertoolsmodule.c,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv29413/Modules Modified Files: itertoolsmodule.c Log Message: Created PyObject_GenericGetIter(). Factors out the common case of returning self. Index: itertoolsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/itertoolsmodule.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** itertoolsmodule.c 1 Mar 2003 01:48:24 -0000 1.7 --- itertoolsmodule.c 17 Mar 2003 08:22:57 -0000 1.8 *************** *** 106,116 **** } - static PyObject * - cycle_getiter(PyObject *lz) - { - Py_INCREF(lz); - return lz; - } - PyDoc_STRVAR(cycle_doc, "cycle(iterable) --> cycle object\n\ --- 106,109 ---- *************** *** 148,152 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)cycle_getiter, /* tp_iter */ (iternextfunc)cycle_next, /* tp_iternext */ 0, /* tp_methods */ --- 141,145 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)cycle_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 262,272 **** } - static PyObject * - dropwhile_getiter(PyObject *lz) - { - Py_INCREF(lz); - return lz; - } - PyDoc_STRVAR(dropwhile_doc, "dropwhile(predicate, iterable) --> dropwhile object\n\ --- 255,258 ---- *************** *** 304,308 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)dropwhile_getiter, /* tp_iter */ (iternextfunc)dropwhile_next, /* tp_iternext */ 0, /* tp_methods */ --- 290,294 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)dropwhile_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 417,427 **** } - static PyObject * - takewhile_getiter(PyObject *lz) - { - Py_INCREF(lz); - return lz; - } - PyDoc_STRVAR(takewhile_doc, "takewhile(predicate, iterable) --> takewhile object\n\ --- 403,406 ---- *************** *** 459,463 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)takewhile_getiter, /* tp_iter */ (iternextfunc)takewhile_next, /* tp_iternext */ 0, /* tp_methods */ --- 438,442 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)takewhile_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 590,600 **** } - static PyObject * - islice_getiter(PyObject *lz) - { - Py_INCREF(lz); - return lz; - } - PyDoc_STRVAR(islice_doc, "islice(iterable, [start,] stop [, step]) --> islice object\n\ --- 569,572 ---- *************** *** 636,640 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)islice_getiter, /* tp_iter */ (iternextfunc)islice_next, /* tp_iternext */ 0, /* tp_methods */ --- 608,612 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)islice_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 740,750 **** } - static PyObject * - starmap_getiter(PyObject *lz) - { - Py_INCREF(lz); - return lz; - } - PyDoc_STRVAR(starmap_doc, "starmap(function, sequence) --> starmap object\n\ --- 712,715 ---- *************** *** 782,786 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)starmap_getiter, /* tp_iter */ (iternextfunc)starmap_next, /* tp_iternext */ 0, /* tp_methods */ --- 747,751 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)starmap_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 931,941 **** } - static PyObject * - imap_getiter(PyObject *lz) - { - Py_INCREF(lz); - return lz; - } - PyDoc_STRVAR(imap_doc, "imap(func, *iterables) --> imap object\n\ --- 896,899 ---- *************** *** 976,980 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)imap_getiter, /* tp_iter */ (iternextfunc)imap_next, /* tp_iternext */ 0, /* tp_methods */ --- 934,938 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)imap_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 1075,1085 **** } - static PyObject * - chain_getiter(PyObject *lz) - { - Py_INCREF(lz); - return lz; - } - PyDoc_STRVAR(chain_doc, "chain(*iterables) --> chain object\n\ --- 1033,1036 ---- *************** *** 1118,1122 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)chain_getiter, /* tp_iter */ (iternextfunc)chain_next, /* tp_iternext */ 0, /* tp_methods */ --- 1069,1073 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)chain_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 1232,1242 **** } - static PyObject * - ifilter_getiter(PyObject *lz) - { - Py_INCREF(lz); - return lz; - } - PyDoc_STRVAR(ifilter_doc, "ifilter(function or None, sequence) --> ifilter object\n\ --- 1183,1186 ---- *************** *** 1274,1278 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)ifilter_getiter, /* tp_iter */ (iternextfunc)ifilter_next, /* tp_iternext */ 0, /* tp_methods */ --- 1218,1222 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)ifilter_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 1388,1398 **** } - static PyObject * - ifilterfalse_getiter(PyObject *lz) - { - Py_INCREF(lz); - return lz; - } - PyDoc_STRVAR(ifilterfalse_doc, "ifilterfalse(function or None, sequence) --> ifilterfalse object\n\ --- 1332,1335 ---- *************** *** 1430,1434 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)ifilterfalse_getiter, /* tp_iter */ (iternextfunc)ifilterfalse_next, /* tp_iternext */ 0, /* tp_methods */ --- 1367,1371 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)ifilterfalse_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 1480,1490 **** } - static PyObject * - count_getiter(PyObject *lz) - { - Py_INCREF(lz); - return lz; - } - PyDoc_STRVAR(count_doc, "count([firstval]) --> count object\n\ --- 1417,1420 ---- *************** *** 1521,1525 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)count_getiter, /* tp_iter */ (iternextfunc)count_next, /* tp_iternext */ 0, /* tp_methods */ --- 1451,1455 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)count_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 1666,1676 **** } - static PyObject * - izip_getiter(PyObject *lz) - { - Py_INCREF(lz); - return lz; - } - PyDoc_STRVAR(izip_doc, "izip(iter1 [,iter2 [...]]) --> izip object\n\ --- 1596,1599 ---- *************** *** 1712,1716 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)izip_getiter, /* tp_iter */ (iternextfunc)izip_next, /* tp_iternext */ 0, /* tp_methods */ --- 1635,1639 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)izip_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 1785,1795 **** } - static PyObject * - repeat_getiter(PyObject *ro) - { - Py_INCREF(ro); - return ro; - } - PyDoc_STRVAR(repeat_doc, "repeat(element [,times]) -> create an iterator which returns the element\n\ --- 1708,1711 ---- *************** *** 1826,1830 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)repeat_getiter, /* tp_iter */ (iternextfunc)repeat_next, /* tp_iternext */ 0, /* tp_methods */ --- 1742,1746 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)repeat_next, /* tp_iternext */ 0, /* tp_methods */ From rhettinger@users.sourceforge.net Mon Mar 17 08:24:37 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 17 Mar 2003 00:24:37 -0800 Subject: [Python-checkins] python/dist/src/Objects dictobject.c,2.141,2.142 enumobject.c,1.3,1.4 iterobject.c,1.13,1.14 listobject.c,2.145,2.146 rangeobject.c,2.46,2.47 tupleobject.c,2.76,2.77 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv31085 Modified Files: dictobject.c enumobject.c iterobject.c listobject.c rangeobject.c tupleobject.c Log Message: Created PyObject_GenericGetIter(). Factors out the common case of returning self. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.141 retrieving revision 2.142 diff -C2 -d -r2.141 -r2.142 *** dictobject.c 6 Mar 2003 23:54:28 -0000 2.141 --- dictobject.c 17 Mar 2003 08:24:34 -0000 2.142 *************** *** 2014,2024 **** } - static PyObject * - dictiter_getiter(PyObject *it) - { - Py_INCREF(it); - return it; - } - static PyObject *dictiter_iternext(dictiterobject *di) { --- 2014,2017 ---- *************** *** 2070,2074 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)dictiter_getiter, /* tp_iter */ (iternextfunc)dictiter_iternext, /* tp_iternext */ 0, /* tp_methods */ --- 2063,2067 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)dictiter_iternext, /* tp_iternext */ 0, /* tp_methods */ Index: enumobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/enumobject.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** enumobject.c 16 Jul 2002 21:02:42 -0000 1.3 --- enumobject.c 17 Mar 2003 08:24:34 -0000 1.4 *************** *** 79,89 **** } - static PyObject * - enum_getiter(PyObject *en) - { - Py_INCREF(en); - return en; - } - PyDoc_STRVAR(enum_doc, "enumerate(iterable) -> create an enumerating-iterator"); --- 79,82 ---- *************** *** 118,122 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)enum_getiter, /* tp_iter */ (iternextfunc)enum_next, /* tp_iternext */ 0, /* tp_methods */ --- 111,115 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)enum_next, /* tp_iternext */ 0, /* tp_methods */ Index: iterobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/iterobject.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** iterobject.c 16 Aug 2002 17:01:08 -0000 1.13 --- iterobject.c 17 Mar 2003 08:24:34 -0000 1.14 *************** *** 45,55 **** static PyObject * - iter_getiter(PyObject *it) - { - Py_INCREF(it); - return it; - } - - static PyObject * iter_iternext(PyObject *iterator) { --- 45,48 ---- *************** *** 107,111 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)iter_getiter, /* tp_iter */ (iternextfunc)iter_iternext, /* tp_iternext */ 0, /* tp_methods */ --- 100,104 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)iter_iternext, /* tp_iternext */ 0, /* tp_methods */ *************** *** 224,228 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)iter_getiter, /* tp_iter */ (iternextfunc)calliter_iternext, /* tp_iternext */ 0, /* tp_methods */ --- 217,221 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)calliter_iternext, /* tp_iternext */ 0, /* tp_methods */ Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.145 retrieving revision 2.146 diff -C2 -d -r2.145 -r2.146 *** listobject.c 2 Jan 2003 20:51:08 -0000 2.145 --- listobject.c 17 Mar 2003 08:24:34 -0000 2.146 *************** *** 2399,2410 **** } - - static PyObject * - listiter_getiter(PyObject *it) - { - Py_INCREF(it); - return it; - } - static PyObject * listiter_next(listiterobject *it) --- 2399,2402 ---- *************** *** 2459,2463 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)listiter_getiter, /* tp_iter */ (iternextfunc)listiter_next, /* tp_iternext */ 0, /* tp_methods */ --- 2451,2455 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)listiter_next, /* tp_iternext */ 0, /* tp_methods */ Index: rangeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/rangeobject.c,v retrieving revision 2.46 retrieving revision 2.47 diff -C2 -d -r2.46 -r2.47 *** rangeobject.c 11 Dec 2002 07:14:02 -0000 2.46 --- rangeobject.c 17 Mar 2003 08:24:34 -0000 2.47 *************** *** 247,257 **** static PyObject * - rangeiter_getiter(PyObject *it) - { - Py_INCREF(it); - return it; - } - - static PyObject * rangeiter_next(rangeiterobject *r) { --- 247,250 ---- *************** *** 289,293 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)rangeiter_getiter, /* tp_iter */ (iternextfunc)rangeiter_next, /* tp_iternext */ 0, /* tp_methods */ --- 282,286 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)rangeiter_next, /* tp_iternext */ 0, /* tp_methods */ Index: tupleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.76 retrieving revision 2.77 diff -C2 -d -r2.76 -r2.77 *** tupleobject.c 29 Jan 2003 17:58:45 -0000 2.76 --- tupleobject.c 17 Mar 2003 08:24:35 -0000 2.77 *************** *** 780,791 **** } - - static PyObject * - tupleiter_getiter(PyObject *it) - { - Py_INCREF(it); - return it; - } - static PyObject * tupleiter_next(tupleiterobject *it) --- 780,783 ---- *************** *** 840,844 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)tupleiter_getiter, /* tp_iter */ (iternextfunc)tupleiter_next, /* tp_iternext */ }; --- 832,836 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)tupleiter_next, /* tp_iternext */ }; From rhettinger@users.sourceforge.net Mon Mar 17 08:35:54 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 17 Mar 2003 00:35:54 -0800 Subject: [Python-checkins] python/dist/src/Modules _hotshot.c,1.32,1.33 arraymodule.c,2.84,2.85 xreadlinesmodule.c,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv4768 Modified Files: _hotshot.c arraymodule.c xreadlinesmodule.c Log Message: Created PyObject_GenericGetIter(). Factors out the common case of returning self. Index: _hotshot.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_hotshot.c,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** _hotshot.c 6 Jan 2003 12:41:25 -0000 1.32 --- _hotshot.c 17 Mar 2003 08:35:49 -0000 1.33 *************** *** 142,152 **** } - static PyObject * - logreader_tp_iter(LogReaderObject *self) - { - Py_INCREF(self); - return (PyObject *) self; - } - /* Log File Format --- 142,145 ---- *************** *** 1353,1357 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)logreader_tp_iter, /* tp_iter */ (iternextfunc)logreader_tp_iternext,/* tp_iternext */ logreader_methods, /* tp_methods */ --- 1346,1350 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)logreader_tp_iternext,/* tp_iternext */ logreader_methods, /* tp_methods */ Index: arraymodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/arraymodule.c,v retrieving revision 2.84 retrieving revision 2.85 diff -C2 -d -r2.84 -r2.85 *** arraymodule.c 24 Feb 2003 02:08:42 -0000 2.84 --- arraymodule.c 17 Mar 2003 08:35:49 -0000 2.85 *************** *** 1963,1973 **** static PyObject * - arrayiter_getiter(PyObject *it) - { - Py_INCREF(it); - return it; - } - - static PyObject * arrayiter_next(arrayiterobject *it) { --- 1963,1966 ---- *************** *** 2022,2026 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)arrayiter_getiter, /* tp_iter */ (iternextfunc)arrayiter_next, /* tp_iternext */ 0, /* tp_methods */ --- 2015,2019 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)arrayiter_next, /* tp_iternext */ 0, /* tp_methods */ Index: xreadlinesmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/xreadlinesmodule.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** xreadlinesmodule.c 6 Aug 2002 17:14:04 -0000 1.13 --- xreadlinesmodule.c 17 Mar 2003 08:35:49 -0000 1.14 *************** *** 83,93 **** static PyObject * - xreadlines_getiter(PyXReadlinesObject *a) - { - Py_INCREF(a); - return (PyObject *)a; - } - - static PyObject * xreadlines_iternext(PyXReadlinesObject *a) { --- 83,86 ---- *************** *** 160,164 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! (getiterfunc)xreadlines_getiter, /* tp_iter */ (iternextfunc)xreadlines_iternext, /* tp_iternext */ }; --- 153,157 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)xreadlines_iternext, /* tp_iternext */ }; From jackjansen@users.sourceforge.net Mon Mar 17 10:54:44 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Mon, 17 Mar 2003 02:54:44 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac pimp.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv4420/Lib/plat-mac Modified Files: pimp.py Log Message: Capturing the exit status for the build process didn't work. Using popen2.Popen4() makes it work. Fixes #702180. Index: pimp.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/pimp.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** pimp.py 11 Mar 2003 14:37:19 -0000 1.13 --- pimp.py 17 Mar 2003 10:54:41 -0000 1.14 *************** *** 15,18 **** --- 15,19 ---- import sys import os + import popen2 import urllib import urllib2 *************** *** 396,409 **** if NO_EXECUTE: return 0 ! dummy, fp = os.popen4(cmd, "r") ! dummy.close() while 1: ! line = fp.readline() if not line: break if output: output.write(line) ! rv = fp.close() ! return rv def downloadPackageOnly(self, output=None): --- 397,409 ---- if NO_EXECUTE: return 0 ! child = popen2.Popen4(cmd) ! child.tochild.close() while 1: ! line = child.fromchild.readline() if not line: break if output: output.write(line) ! return child.wait() def downloadPackageOnly(self, output=None): *************** *** 589,593 **** installcmd = '"%s" setup.py install' % sys.executable if self._cmd(output, self._buildDirname, installcmd): ! return "install %s: running \"%s\" failed" % self.fullname() self.afterInstall() --- 589,594 ---- installcmd = '"%s" setup.py install' % sys.executable if self._cmd(output, self._buildDirname, installcmd): ! return "install %s: running \"%s\" failed" % \ ! (self.fullname(), installcmd) self.afterInstall() From twouters@users.sourceforge.net Mon Mar 17 11:24:32 2003 From: twouters@users.sourceforge.net (twouters@users.sourceforge.net) Date: Mon, 17 Mar 2003 03:24:32 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_binascii.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv14143/Lib/test Modified Files: test_binascii.py Log Message: binascii_a2b_base64: Properly return an empty string if the input was all invalid, rather than returning a string of random garbage of the estimated result length. Closes SF patch #703471 by Hye-Shik Chang. Will backport to 2.2-maint (consider it done.) Index: test_binascii.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_binascii.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** test_binascii.py 30 Jul 2002 23:26:01 -0000 1.15 --- test_binascii.py 17 Mar 2003 11:24:29 -0000 1.16 *************** *** 70,73 **** --- 70,77 ---- verify(res == testdata) + # Test base64 with just invalid characters, which should return + # empty strings. TBD: shouldn't it raise an exception instead ? + verify(binascii.a2b_base64(fillers) == '') + # Test uu print "uu test" From twouters@users.sourceforge.net Mon Mar 17 11:24:32 2003 From: twouters@users.sourceforge.net (twouters@users.sourceforge.net) Date: Mon, 17 Mar 2003 03:24:32 -0800 Subject: [Python-checkins] python/dist/src/Modules binascii.c,2.38,2.39 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv14143/Modules Modified Files: binascii.c Log Message: binascii_a2b_base64: Properly return an empty string if the input was all invalid, rather than returning a string of random garbage of the estimated result length. Closes SF patch #703471 by Hye-Shik Chang. Will backport to 2.2-maint (consider it done.) Index: binascii.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/binascii.c,v retrieving revision 2.38 retrieving revision 2.39 diff -C2 -d -r2.38 -r2.39 *** binascii.c 15 Aug 2002 22:14:24 -0000 2.38 --- binascii.c 17 Mar 2003 11:24:29 -0000 2.39 *************** *** 409,415 **** } ! /* and set string size correctly */ if (bin_len > 0) _PyString_Resize(&rv, bin_len); return rv; } --- 409,422 ---- } ! /* And set string size correctly. If the result string is empty ! ** (because the input was all invalid) return the shared empty ! ** string instead; _PyString_Resize() won't do this for us. ! */ if (bin_len > 0) _PyString_Resize(&rv, bin_len); + else { + Py_DECREF(rv); + rv = PyString_FromString(""); + } return rv; } From twouters@users.sourceforge.net Mon Mar 17 11:34:04 2003 From: twouters@users.sourceforge.net (twouters@users.sourceforge.net) Date: Mon, 17 Mar 2003 03:34:04 -0800 Subject: [Python-checkins] python/dist/src/Misc ACKS,1.229,1.230 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv17766/Misc Modified Files: ACKS Log Message: Add Hye-Shik Chang for SF patch/bugreport #703471. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.229 retrieving revision 1.230 diff -C2 -d -r1.229 -r1.230 *** ACKS 14 Mar 2003 21:51:33 -0000 1.229 --- ACKS 17 Mar 2003 11:34:01 -0000 1.230 *************** *** 90,93 **** --- 90,94 ---- Per Cederqvist Octavian Cerna + Hye-Shik Chang Jeffrey Chang Brad Chapman From twouters@users.sourceforge.net Mon Mar 17 11:34:45 2003 From: twouters@users.sourceforge.net (twouters@users.sourceforge.net) Date: Mon, 17 Mar 2003 03:34:45 -0800 Subject: [Python-checkins] python/dist/src/Modules binascii.c,2.33.4.3,2.33.4.4 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv18224/Modules Modified Files: Tag: release22-maint binascii.c Log Message: binascii_a2b_base64: Properly return an empty string if the input was all invalid, rather than returning a string of random garbage of the estimated result length. Closes SF patch #703471 by Hye-Shik Chang. Backport from 2.3. Index: binascii.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/binascii.c,v retrieving revision 2.33.4.3 retrieving revision 2.33.4.4 diff -C2 -d -r2.33.4.3 -r2.33.4.4 *** binascii.c 25 Sep 2002 10:25:14 -0000 2.33.4.3 --- binascii.c 17 Mar 2003 11:34:43 -0000 2.33.4.4 *************** *** 412,415 **** --- 412,419 ---- if (bin_len > 0) _PyString_Resize(&rv, bin_len); + else { + Py_DECREF(rv); + return PyString_FromString(""); + } return rv; } From twouters@users.sourceforge.net Mon Mar 17 11:34:45 2003 From: twouters@users.sourceforge.net (twouters@users.sourceforge.net) Date: Mon, 17 Mar 2003 03:34:45 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_binascii.py,1.11,1.11.10.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv18224/Lib/test Modified Files: Tag: release22-maint test_binascii.py Log Message: binascii_a2b_base64: Properly return an empty string if the input was all invalid, rather than returning a string of random garbage of the estimated result length. Closes SF patch #703471 by Hye-Shik Chang. Backport from 2.3. Index: test_binascii.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_binascii.py,v retrieving revision 1.11 retrieving revision 1.11.10.1 diff -C2 -d -r1.11 -r1.11.10.1 *** test_binascii.py 18 Oct 2001 21:57:37 -0000 1.11 --- test_binascii.py 17 Mar 2003 11:34:43 -0000 1.11.10.1 *************** *** 70,73 **** --- 70,77 ---- verify(res == testdata) + # Test base64 with just invalid characters, which should return + # empty strings. + verify(binascii.a2b_base64(fillers) == '') + # Test uu print "uu test" From jackjansen@users.sourceforge.net Mon Mar 17 15:43:37 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Mon, 17 Mar 2003 07:43:37 -0800 Subject: [Python-checkins] python/dist/src/Modules Setup.dist,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv7873/Modules Modified Files: Setup.dist Log Message: Added a define EXTRAMACHDEPPATH which can be used to add sys.path items for specific platforms. Use this to add plat-mac and plat-mac/lib-scriptpackages on MacOSX. Also tested for not having adverse effects on Linux, and I think this code isn't used on Windows anyway. Fixes #661521. Index: Setup.dist =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Setup.dist,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** Setup.dist 26 Jan 2003 11:48:19 -0000 1.36 --- Setup.dist 17 Mar 2003 15:43:34 -0000 1.37 *************** *** 93,96 **** --- 93,97 ---- # Path components for machine- or system-dependent modules and shared libraries MACHDEPPATH=:plat-$(MACHDEP) + EXTRAMACHDEPPATH= # Path component for the Tkinter-related modules *************** *** 98,102 **** TKPATH=:lib-tk ! COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(TKPATH) PYTHONPATH=$(COREPYTHONPATH) --- 99,103 ---- TKPATH=:lib-tk ! COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH)$(TKPATH) PYTHONPATH=$(COREPYTHONPATH) From jackjansen@users.sourceforge.net Mon Mar 17 15:43:37 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Mon, 17 Mar 2003 07:43:37 -0800 Subject: [Python-checkins] python/dist/src Makefile.pre.in,1.116,1.117 configure.in,1.393,1.394 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv7873 Modified Files: Makefile.pre.in configure.in Log Message: Added a define EXTRAMACHDEPPATH which can be used to add sys.path items for specific platforms. Use this to add plat-mac and plat-mac/lib-scriptpackages on MacOSX. Also tested for not having adverse effects on Linux, and I think this code isn't used on Windows anyway. Fixes #661521. Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.116 retrieving revision 1.117 diff -C2 -d -r1.116 -r1.117 *** Makefile.pre.in 4 Mar 2003 10:52:39 -0000 1.116 --- Makefile.pre.in 17 Mar 2003 15:43:32 -0000 1.117 *************** *** 613,616 **** --- 613,617 ---- PLATDIR= plat-$(MACHDEP) EXTRAPLATDIR= @EXTRAPLATDIR@ + EXTRAMACHDEPPATH=@EXTRAMACHDEPPATH@ MACHDEPS= $(PLATDIR) $(EXTRAPLATDIR) XMLLIBSUBDIRS= xml xml/dom xml/parsers xml/sax *************** *** 623,626 **** --- 624,628 ---- plat-mac/lib-scriptpackages/StdSuites \ plat-mac/lib-scriptpackages/Terminal + PLATMACPATH=:plat-mac:plat-mac/lib-scriptpackages LIBSUBDIRS= lib-old lib-tk site-packages test test/output test/data \ encodings email email/test email/test/data compiler hotshot \ Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.393 retrieving revision 1.394 diff -C2 -d -r1.393 -r1.394 *** configure.in 14 Mar 2003 21:51:31 -0000 1.393 --- configure.in 17 Mar 2003 15:43:34 -0000 1.394 *************** *** 158,167 **** # And add extra plat-mac for darwin AC_SUBST(EXTRAPLATDIR) AC_MSG_CHECKING(EXTRAPLATDIR) if test -z "$EXTRAPLATDIR" then case $MACHDEP in ! darwin) EXTRAPLATDIR="\$(PLATMACDIRS)";; ! *) EXTRAPLATDIR="";; esac fi --- 158,174 ---- # And add extra plat-mac for darwin AC_SUBST(EXTRAPLATDIR) + AC_SUBST(EXTRAMACHDEPPATH) AC_MSG_CHECKING(EXTRAPLATDIR) if test -z "$EXTRAPLATDIR" then case $MACHDEP in ! darwin) ! EXTRAPLATDIR="\$(PLATMACDIRS)" ! EXTRAMACHDEPPATH="\$(PLATMACPATH)" ! ;; ! *) ! EXTRAPLATDIR="" ! EXTRAMACHDEPPATH="" ! ;; esac fi From jackjansen@users.sourceforge.net Mon Mar 17 15:44:27 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Mon, 17 Mar 2003 07:44:27 -0800 Subject: [Python-checkins] python/dist/src configure,1.382,1.383 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv9055 Modified Files: configure Log Message: Added a define EXTRAMACHDEPPATH which can be used to add sys.path items for specific platforms. Use this to add plat-mac and plat-mac/lib-scriptpackages on MacOSX. Also tested for not having adverse effects on Linux, and I think this code isn't used on Windows anyway. Fixes #661521. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.382 retrieving revision 1.383 diff -C2 -d -r1.382 -r1.383 *** configure 14 Mar 2003 21:51:20 -0000 1.382 --- configure 17 Mar 2003 15:44:10 -0000 1.383 *************** *** 1,4 **** #! /bin/sh ! # From configure.in Revision: 1.392 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.53 for python 2.3. --- 1,4 ---- #! /bin/sh ! # From configure.in Revision: 1.393 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.53 for python 2.3. *************** *** 1391,1394 **** --- 1391,1395 ---- # And add extra plat-mac for darwin + echo "$as_me:$LINENO: checking EXTRAPLATDIR" >&5 echo $ECHO_N "checking EXTRAPLATDIR... $ECHO_C" >&6 *************** *** 1396,1401 **** then case $MACHDEP in ! darwin) EXTRAPLATDIR="\$(PLATMACDIRS)";; ! *) EXTRAPLATDIR="";; esac fi --- 1397,1408 ---- then case $MACHDEP in ! darwin) ! EXTRAPLATDIR="\$(PLATMACDIRS)" ! EXTRAMACHDEPPATH="\$(PLATMACPATH)" ! ;; ! *) ! EXTRAPLATDIR="" ! EXTRAMACHDEPPATH="" ! ;; esac fi *************** *** 17469,17472 **** --- 17476,17480 ---- s,@SGI_ABI@,$SGI_ABI,;t t s,@EXTRAPLATDIR@,$EXTRAPLATDIR,;t t + s,@EXTRAMACHDEPPATH@,$EXTRAMACHDEPPATH,;t t s,@CXX@,$CXX,;t t s,@MAINOBJ@,$MAINOBJ,;t t From jackjansen@users.sourceforge.net Mon Mar 17 15:45:42 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Mon, 17 Mar 2003 07:45:42 -0800 Subject: [Python-checkins] python/dist/src/Mac/OSX Makefile,1.38,1.39 Mac.pth,1.2,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSX In directory sc8-pr-cvs1:/tmp/cvs-serv9508 Modified Files: Makefile Removed Files: Mac.pth Log Message: Get rid of Mac.pth: plat-mac is now added through the normal mechanism. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/OSX/Makefile,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** Makefile 11 Mar 2003 23:07:08 -0000 1.38 --- Makefile 17 Mar 2003 15:45:38 -0000 1.39 *************** *** 16,20 **** PYTHONAPPSDIR=$(dstroot)$(PYTHONAPPSPATH) APPINSTALLDIR=$(prefix)/Resources/Python.app - PTHFILE=$(srcdir)/Mac/OSX/Mac.pth # Variables for installing the "normal" unix binaries --- 16,19 ---- *************** *** 215,219 **** done - $(INSTALL_DATA) $(PTHFILE) $(LIBDEST)/site-packages/ $(BUILDPYTHON) $(CACHERSRC) -v $(MACLIBDEST) $(MACTOOLSDEST) --- 214,217 ---- --- Mac.pth DELETED --- From loewis@users.sourceforge.net Mon Mar 17 18:30:20 2003 From: loewis@users.sourceforge.net (loewis@users.sourceforge.net) Date: Mon, 17 Mar 2003 10:30:20 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_unicode_file.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv26562/Lib/test Modified Files: test_unicode_file.py Log Message: Test for UnicodeError instead of ImportError to determine whether the test file name can be encoded. Index: test_unicode_file.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode_file.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_unicode_file.py 8 Mar 2003 10:25:31 -0000 1.7 --- test_unicode_file.py 17 Mar 2003 18:30:15 -0000 1.8 *************** *** 8,12 **** try: TESTFN_ENCODED = TESTFN_UNICODE.encode(TESTFN_ENCODING) ! except (ImportError, TypeError): # Either the file system encoding is None, or the file name # cannot be encoded in the file system encoding. --- 8,12 ---- try: TESTFN_ENCODED = TESTFN_UNICODE.encode(TESTFN_ENCODING) ! except (UnicodeError, TypeError): # Either the file system encoding is None, or the file name # cannot be encoded in the file system encoding. From bwarsaw@users.sourceforge.net Mon Mar 17 18:36:40 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 17 Mar 2003 10:36:40 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.45,1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv29965 Modified Files: test_email.py Log Message: test_getaddresses_nasty(): A test for mimelib SF bug # 697641. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** test_email.py 12 Mar 2003 03:14:11 -0000 1.45 --- test_email.py 17 Mar 2003 18:36:37 -0000 1.46 *************** *** 1927,1930 **** --- 1927,1940 ---- ('Bud Person', 'bperson@dom.ain')]) + def test_getaddresses_nasty(self): + eq = self.assertEqual + eq(Utils.getaddresses(['foo: ;']), [('', '')]) + eq(Utils.getaddresses( + ['[]*-- =~$']), + [('', ''), ('', ''), ('', '*--')]) + eq(Utils.getaddresses( + ['foo: ;', '"Jason R. Mastaler" ']), + [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]) + def test_utils_quote_unquote(self): eq = self.assertEqual From bwarsaw@users.sourceforge.net Mon Mar 17 18:35:46 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 17 Mar 2003 10:35:46 -0800 Subject: [Python-checkins] python/dist/src/Lib/email _parseaddr.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv29522 Modified Files: _parseaddr.py Log Message: getaddrlist(): Make sure this consumes all the data, and if there is no address there (perhaps because of invalid characters, it appends ('', '') to the result set. Closes mimelib SF bug # 697641. Index: _parseaddr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/_parseaddr.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** _parseaddr.py 30 Dec 2002 17:21:36 -0000 1.4 --- _parseaddr.py 17 Mar 2003 18:35:42 -0000 1.5 *************** *** 197,206 **** """ result = [] ! while True: ad = self.getaddress() if ad: result += ad else: ! break return result --- 197,206 ---- """ result = [] ! while self.pos < len(self.field): ad = self.getaddress() if ad: result += ad else: ! result.append(('', '')) return result From rhettinger@users.sourceforge.net Mon Mar 17 19:46:15 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 17 Mar 2003 11:46:15 -0800 Subject: [Python-checkins] python/dist/src/Objects dictobject.c,2.142,2.143 enumobject.c,1.4,1.5 iterobject.c,1.14,1.15 listobject.c,2.146,2.147 object.c,2.200,2.201 rangeobject.c,2.47,2.48 tupleobject.c,2.77,2.78 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv29904/Objects Modified Files: dictobject.c enumobject.c iterobject.c listobject.c object.c rangeobject.c tupleobject.c Log Message: Renamed PyObject_GenericGetIter to PyObject_SelfIter to more accurately describe what the function does. Suggested by Thomas Wouters. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.142 retrieving revision 2.143 diff -C2 -d -r2.142 -r2.143 *** dictobject.c 17 Mar 2003 08:24:34 -0000 2.142 --- dictobject.c 17 Mar 2003 19:46:09 -0000 2.143 *************** *** 2063,2067 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)dictiter_iternext, /* tp_iternext */ 0, /* tp_methods */ --- 2063,2067 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)dictiter_iternext, /* tp_iternext */ 0, /* tp_methods */ Index: enumobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/enumobject.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** enumobject.c 17 Mar 2003 08:24:34 -0000 1.4 --- enumobject.c 17 Mar 2003 19:46:09 -0000 1.5 *************** *** 111,115 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)enum_next, /* tp_iternext */ 0, /* tp_methods */ --- 111,115 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)enum_next, /* tp_iternext */ 0, /* tp_methods */ Index: iterobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/iterobject.c,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** iterobject.c 17 Mar 2003 08:24:34 -0000 1.14 --- iterobject.c 17 Mar 2003 19:46:10 -0000 1.15 *************** *** 100,104 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)iter_iternext, /* tp_iternext */ 0, /* tp_methods */ --- 100,104 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)iter_iternext, /* tp_iternext */ 0, /* tp_methods */ *************** *** 217,221 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)calliter_iternext, /* tp_iternext */ 0, /* tp_methods */ --- 217,221 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)calliter_iternext, /* tp_iternext */ 0, /* tp_methods */ Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.146 retrieving revision 2.147 diff -C2 -d -r2.146 -r2.147 *** listobject.c 17 Mar 2003 08:24:34 -0000 2.146 --- listobject.c 17 Mar 2003 19:46:10 -0000 2.147 *************** *** 2451,2455 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)listiter_next, /* tp_iternext */ 0, /* tp_methods */ --- 2451,2455 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)listiter_next, /* tp_iternext */ 0, /* tp_methods */ Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.200 retrieving revision 2.201 diff -C2 -d -r2.200 -r2.201 *** object.c 17 Mar 2003 08:22:56 -0000 2.200 --- object.c 17 Mar 2003 19:46:11 -0000 2.201 *************** *** 1302,1306 **** PyObject * ! PyObject_GenericGetIter(PyObject *obj) { Py_INCREF(obj); --- 1302,1306 ---- PyObject * ! PyObject_SelfIter(PyObject *obj) { Py_INCREF(obj); Index: rangeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/rangeobject.c,v retrieving revision 2.47 retrieving revision 2.48 diff -C2 -d -r2.47 -r2.48 *** rangeobject.c 17 Mar 2003 08:24:34 -0000 2.47 --- rangeobject.c 17 Mar 2003 19:46:11 -0000 2.48 *************** *** 282,286 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)rangeiter_next, /* tp_iternext */ 0, /* tp_methods */ --- 282,286 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)rangeiter_next, /* tp_iternext */ 0, /* tp_methods */ Index: tupleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.77 retrieving revision 2.78 diff -C2 -d -r2.77 -r2.78 *** tupleobject.c 17 Mar 2003 08:24:35 -0000 2.77 --- tupleobject.c 17 Mar 2003 19:46:11 -0000 2.78 *************** *** 832,836 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)tupleiter_next, /* tp_iternext */ }; --- 832,836 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)tupleiter_next, /* tp_iternext */ }; From rhettinger@users.sourceforge.net Mon Mar 17 19:46:35 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 17 Mar 2003 11:46:35 -0800 Subject: [Python-checkins] python/dist/src/Include object.h,2.114,2.115 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv29904/Include Modified Files: object.h Log Message: Renamed PyObject_GenericGetIter to PyObject_SelfIter to more accurately describe what the function does. Suggested by Thomas Wouters. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.114 retrieving revision 2.115 diff -C2 -d -r2.114 -r2.115 *** object.h 17 Mar 2003 08:22:55 -0000 2.114 --- object.h 17 Mar 2003 19:45:59 -0000 2.115 *************** *** 386,390 **** PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); ! PyAPI_FUNC(PyObject *) PyObject_GenericGetIter(PyObject *); PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, --- 386,390 ---- PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); ! PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *); PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, From rhettinger@users.sourceforge.net Mon Mar 17 19:46:43 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 17 Mar 2003 11:46:43 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.697,1.698 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv29904/Misc Modified Files: NEWS Log Message: Renamed PyObject_GenericGetIter to PyObject_SelfIter to more accurately describe what the function does. Suggested by Thomas Wouters. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.697 retrieving revision 1.698 diff -C2 -d -r1.697 -r1.698 *** NEWS 17 Mar 2003 08:22:57 -0000 1.697 --- NEWS 17 Mar 2003 19:46:03 -0000 1.698 *************** *** 87,91 **** ----- ! - Added PyObject_GenericGetIter() to fill the tp_iter slot for the typical case where the method returns its self argument. --- 87,91 ---- ----- ! - Added PyObject_SelfIter() to fill the tp_iter slot for the typical case where the method returns its self argument. From rhettinger@users.sourceforge.net Mon Mar 17 19:46:44 2003 From: rhettinger@users.sourceforge.net (rhettinger@users.sourceforge.net) Date: Mon, 17 Mar 2003 11:46:44 -0800 Subject: [Python-checkins] python/dist/src/Modules _hotshot.c,1.33,1.34 arraymodule.c,2.85,2.86 itertoolsmodule.c,1.8,1.9 xreadlinesmodule.c,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv29904/Modules Modified Files: _hotshot.c arraymodule.c itertoolsmodule.c xreadlinesmodule.c Log Message: Renamed PyObject_GenericGetIter to PyObject_SelfIter to more accurately describe what the function does. Suggested by Thomas Wouters. Index: _hotshot.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_hotshot.c,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** _hotshot.c 17 Mar 2003 08:35:49 -0000 1.33 --- _hotshot.c 17 Mar 2003 19:46:07 -0000 1.34 *************** *** 1346,1350 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)logreader_tp_iternext,/* tp_iternext */ logreader_methods, /* tp_methods */ --- 1346,1350 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)logreader_tp_iternext,/* tp_iternext */ logreader_methods, /* tp_methods */ Index: arraymodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/arraymodule.c,v retrieving revision 2.85 retrieving revision 2.86 diff -C2 -d -r2.85 -r2.86 *** arraymodule.c 17 Mar 2003 08:35:49 -0000 2.85 --- arraymodule.c 17 Mar 2003 19:46:07 -0000 2.86 *************** *** 2015,2019 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)arrayiter_next, /* tp_iternext */ 0, /* tp_methods */ --- 2015,2019 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)arrayiter_next, /* tp_iternext */ 0, /* tp_methods */ Index: itertoolsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/itertoolsmodule.c,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** itertoolsmodule.c 17 Mar 2003 08:22:57 -0000 1.8 --- itertoolsmodule.c 17 Mar 2003 19:46:08 -0000 1.9 *************** *** 141,145 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)cycle_next, /* tp_iternext */ 0, /* tp_methods */ --- 141,145 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)cycle_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 290,294 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)dropwhile_next, /* tp_iternext */ 0, /* tp_methods */ --- 290,294 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)dropwhile_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 438,442 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)takewhile_next, /* tp_iternext */ 0, /* tp_methods */ --- 438,442 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)takewhile_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 608,612 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)islice_next, /* tp_iternext */ 0, /* tp_methods */ --- 608,612 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)islice_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 747,751 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)starmap_next, /* tp_iternext */ 0, /* tp_methods */ --- 747,751 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)starmap_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 934,938 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)imap_next, /* tp_iternext */ 0, /* tp_methods */ --- 934,938 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)imap_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 1069,1073 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)chain_next, /* tp_iternext */ 0, /* tp_methods */ --- 1069,1073 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)chain_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 1218,1222 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)ifilter_next, /* tp_iternext */ 0, /* tp_methods */ --- 1218,1222 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)ifilter_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 1367,1371 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)ifilterfalse_next, /* tp_iternext */ 0, /* tp_methods */ --- 1367,1371 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)ifilterfalse_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 1451,1455 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)count_next, /* tp_iternext */ 0, /* tp_methods */ --- 1451,1455 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)count_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 1635,1639 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)izip_next, /* tp_iternext */ 0, /* tp_methods */ --- 1635,1639 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)izip_next, /* tp_iternext */ 0, /* tp_methods */ *************** *** 1742,1746 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)repeat_next, /* tp_iternext */ 0, /* tp_methods */ --- 1742,1746 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)repeat_next, /* tp_iternext */ 0, /* tp_methods */ Index: xreadlinesmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/xreadlinesmodule.c,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** xreadlinesmodule.c 17 Mar 2003 08:35:49 -0000 1.14 --- xreadlinesmodule.c 17 Mar 2003 19:46:08 -0000 1.15 *************** *** 153,157 **** 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_GenericGetIter, /* tp_iter */ (iternextfunc)xreadlines_iternext, /* tp_iternext */ }; --- 153,157 ---- 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ ! PyObject_SelfIter, /* tp_iter */ (iternextfunc)xreadlines_iternext, /* tp_iternext */ }; From bwarsaw@users.sourceforge.net Mon Mar 17 20:35:20 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 17 Mar 2003 12:35:20 -0800 Subject: [Python-checkins] python/dist/src/Lib/email/test test_email.py,1.46,1.47 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email/test In directory sc8-pr-cvs1:/tmp/cvs-serv21771 Modified Files: test_email.py Log Message: test_long_lines_with_different_header(): Another test from Jason. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/test/test_email.py,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -d -r1.46 -r1.47 *** test_email.py 17 Mar 2003 18:36:37 -0000 1.46 --- test_email.py 17 Mar 2003 20:35:14 -0000 1.47 *************** *** 842,845 **** --- 842,861 ---- ''') + def test_long_lines_with_different_header(self): + eq = self.ndiffAssertEqual + h = """\ + List-Unsubscribe: , + """ + msg = Message() + msg['List'] = h + msg['List'] = Header(h, header_name='List') + eq(msg.as_string(), """\ + List: List-Unsubscribe: , + + List: List-Unsubscribe: , + + + """) + From bwarsaw@users.sourceforge.net Mon Mar 17 20:36:30 2003 From: bwarsaw@users.sourceforge.net (bwarsaw@users.sourceforge.net) Date: Mon, 17 Mar 2003 12:36:30 -0800 Subject: [Python-checkins] python/dist/src/Lib/email Header.py,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory sc8-pr-cvs1:/tmp/cvs-serv22307 Modified Files: Header.py Log Message: _encode_chunks(): Throw out empty chunks. Index: Header.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Header.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** Header.py 10 Mar 2003 15:14:08 -0000 1.25 --- Header.py 17 Mar 2003 20:36:20 -0000 1.26 *************** *** 362,365 **** --- 362,367 ---- chunks = [] for header, charset in newchunks: + if not header: + continue if charset is None or charset.header_encoding is None: s = header From nnorwitz@users.sourceforge.net Tue Mar 18 13:30:18 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Tue, 18 Mar 2003 05:30:18 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_posix.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv15534/Lib/test Modified Files: test_posix.py Log Message: Fix SF bug #697556, test_posix fails: getlogin getlogin() can fail for too many reasons, so remove the test Index: test_posix.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_posix.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_posix.py 23 Feb 2003 22:12:24 -0000 1.4 --- test_posix.py 18 Mar 2003 13:30:14 -0000 1.5 *************** *** 34,43 **** "getpid", "getpgrp", "getppid", "getuid", ] - # getlogin() only works when run from a tty (terminal) - try: - if os.isatty(sys.stdin.fileno()): - NO_ARG_FUNCTIONS.append("getlogin") - except: - pass for name in NO_ARG_FUNCTIONS: --- 34,37 ---- From jvr@users.sourceforge.net Tue Mar 18 18:48:20 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Tue, 18 Mar 2003 10:48:20 -0800 Subject: [Python-checkins] python/dist/src/Tools/freeze freeze.py,1.43,1.44 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/freeze In directory sc8-pr-cvs1:/tmp/cvs-serv21968/Tools/freeze Modified Files: freeze.py Log Message: replace obsolete 'exceptions' implicit by 'warnings' Index: freeze.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/freeze/freeze.py,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** freeze.py 8 Mar 2003 19:50:38 -0000 1.43 --- freeze.py 18 Mar 2003 18:48:17 -0000 1.44 *************** *** 202,206 **** # modules that are imported by the Python runtime implicits = [] ! for module in ('site', 'exceptions',): if module not in exclude: implicits.append(module) --- 202,206 ---- # modules that are imported by the Python runtime implicits = [] ! for module in ('site', 'warnings',): if module not in exclude: implicits.append(module) From cliffwells18@users.sourceforge.net Tue Mar 18 21:18:16 2003 From: cliffwells18@users.sourceforge.net (cliffwells18@users.sourceforge.net) Date: Tue, 18 Mar 2003 13:18:16 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv setup.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv27210 Modified Files: setup.py Log Message: Now installs package correctly. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/setup.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** setup.py 29 Jan 2003 11:44:55 -0000 1.3 --- setup.py 18 Mar 2003 21:18:14 -0000 1.4 *************** *** 4,8 **** setup(name = "_csv", description = "Fast CSV Parser", ! py_modules = ['csv'], ext_modules = [ Extension('_csv', --- 4,9 ---- setup(name = "_csv", description = "Fast CSV Parser", ! package_dir = {'csv': '.', 'csv/util': './util'}, ! packages = ['csv', 'csv/util'], ext_modules = [ Extension('_csv', From cliffwells18@users.sourceforge.net Tue Mar 18 21:19:03 2003 From: cliffwells18@users.sourceforge.net (cliffwells18@users.sourceforge.net) Date: Tue, 18 Mar 2003 13:19:03 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.34,1.35 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv27642 Modified Files: csv.py Log Message: Fixed excel dialect to initialize escapechar='' Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** csv.py 26 Feb 2003 22:33:48 -0000 1.34 --- csv.py 18 Mar 2003 21:19:00 -0000 1.35 *************** *** 69,72 **** --- 69,73 ---- delimiter = ',' quotechar = '"' + escapechar = '' doublequote = True skipinitialspace = False From montanaro@users.sourceforge.net Tue Mar 18 21:48:02 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue, 18 Mar 2003 13:48:02 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.35,1.36 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv11045 Modified Files: test_csv.py Log Message: work with new csv package structure Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** test_csv.py 26 Feb 2003 20:59:29 -0000 1.35 --- test_csv.py 18 Mar 2003 21:47:57 -0000 1.36 *************** *** 5,9 **** import unittest from StringIO import StringIO ! import csv import gc --- 5,9 ---- import unittest from StringIO import StringIO ! from csv import csv import gc From montanaro@users.sourceforge.net Tue Mar 18 21:49:03 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue, 18 Mar 2003 13:49:03 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv csv.py,1.35,1.36 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv In directory sc8-pr-cvs1:/tmp/cvs-serv11512 Modified Files: csv.py Log Message: correct _validate() test of escapechar. When quoting is not QUOTE_NONE we don't care what the value of escapechar is. Index: csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/csv.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** csv.py 18 Mar 2003 21:19:00 -0000 1.35 --- csv.py 18 Mar 2003 21:48:58 -0000 1.36 *************** *** 57,67 **** errors.append("skipinitialspace parameter must be True or False") - if (not isinstance(self.escapechar, str) or - len(self.escapechar) > 1): - errors.append("escapechar must be one-character string") - if self.quoting is None: errors.append("quoting parameter not set") return errors --- 57,68 ---- errors.append("skipinitialspace parameter must be True or False") if self.quoting is None: errors.append("quoting parameter not set") + if self.quoting is QUOTE_NONE: + if (not isinstance(self.escapechar, (unicode, str)) or + len(self.escapechar) > 1): + errors.append("escapechar must be a one-character string or unicode object") + return errors *************** *** 69,73 **** delimiter = ',' quotechar = '"' - escapechar = '' doublequote = True skipinitialspace = False --- 70,73 ---- From montanaro@users.sourceforge.net Tue Mar 18 23:07:04 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Tue, 18 Mar 2003 15:07:04 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/test test_csv.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/test In directory sc8-pr-cvs1:/tmp/cvs-serv15057 Modified Files: test_csv.py Log Message: add test using a space character as the delimiter (based upon problems Andrew Dalke had) Index: test_csv.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/test/test_csv.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** test_csv.py 18 Mar 2003 21:47:57 -0000 1.36 --- test_csv.py 18 Mar 2003 23:07:00 -0000 1.37 *************** *** 194,197 **** --- 194,208 ---- self.assertRaises(csv.Error, myexceltsv) + def test_space_dialect(self): + class space(csv.excel): + delimiter = " " + quoting = csv.QUOTE_NONE + escapechar = "\\" + + s = StringIO("abc def\nc1ccccc1 benzene\n") + rdr = csv.reader(s, dialect=space()) + self.assertEqual(rdr.next(), ["abc", "def"]) + self.assertEqual(rdr.next(), ["c1ccccc1", "benzene"]) + def test_dialect_apply(self): class testA(csv.excel): From cliffwells18@users.sourceforge.net Wed Mar 19 00:29:14 2003 From: cliffwells18@users.sourceforge.net (cliffwells18@users.sourceforge.net) Date: Tue, 18 Mar 2003 16:29:14 -0800 Subject: [Python-checkins] python/nondist/sandbox/csv/util sniffer.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/csv/util In directory sc8-pr-cvs1:/tmp/cvs-serv11486 Modified Files: sniffer.py Log Message: Made hasHeaders() a method of Sniffer class. Changed Sniffer.sniff to return a class rather than a class instance, to be compatible with csv.register_dialect(). Index: sniffer.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/csv/util/sniffer.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** sniffer.py 15 Mar 2003 01:15:03 -0000 1.6 --- sniffer.py 19 Mar 2003 00:29:12 -0000 1.7 *************** *** 27,30 **** --- 27,33 ---- Takes a file-like object and returns a dialect (or None) """ + + self.fileobj = fileobj + data = fileobj.read(self.sample) *************** *** 37,41 **** lineterminator = '\r\n' quoting = csv.QUOTE_MINIMAL ! escapechar = '' doublequote = False Dialect.delimiter = delimiter --- 40,44 ---- lineterminator = '\r\n' quoting = csv.QUOTE_MINIMAL ! # escapechar = '' doublequote = False Dialect.delimiter = delimiter *************** *** 43,49 **** Dialect.skipinitialspace = skipinitialspace ! return Dialect() def _guessQuoteAndDelimiter(self, data): """ --- 46,61 ---- Dialect.skipinitialspace = skipinitialspace ! self.dialect = Dialect ! return self.dialect + def hasHeaders(self): + return self._hasHeaders(self.fileobj, self.dialect) + + + def register_dialect(self, name = 'sniffed'): + csv.register_dialect(name, self.dialect) + + def _guessQuoteAndDelimiter(self, data): """ *************** *** 200,276 **** ! # ------------------------------------------------------------------------------ ! def hasHeaders(fileObj, dialect): ! # Algorithm: creates a dictionary of types of data in each column. If any column ! # is of a single type (say, integers), *except* for the first row, then the first ! # row is presumed to be labels. If the type can't be determined, it is assumed to ! # be a string in which case the length of the string is the determining factor: if ! # all of the rows except for the first are the same length, it's a header. ! # Finally, a 'vote' is taken at the end for each column, adding or subtracting from ! # the likelihood of the first row being a header. ! def seval(item): ! """ ! Strips parens from item prior to calling eval in an attempt to make it safer ! """ ! return eval(item.replace('(', '').replace(')', '')) ! reader = csv.reader(fileObj, ! delimiter = dialect.delimiter, ! quotechar = dialect.quotechar, ! skipinitialspace = dialect.skipinitialspace) ! header = reader.next() # assume first row is header ! columns = len(header) ! columnTypes = {} ! for i in range(columns): columnTypes[i] = None ! checked = 0 ! for row in reader: ! if checked > 20: # arbitrary number of rows to check, to keep it sane ! break ! checked += 1 ! ! if len(row) != columns: ! continue # skip rows that have irregular number of columns ! ! for col in columnTypes.keys(): ! try: try: ! # is it a built-in type (besides string)? ! thisType = type(seval(row[col])) ! except OverflowError: ! # a long int? ! thisType = type(seval(row[col] + 'L')) ! thisType = type(0) # treat long ints as int ! except: ! # fallback to length of string ! thisType = len(row[col]) ! if thisType != columnTypes[col]: ! if columnTypes[col] is None: # add new column type ! columnTypes[col] = thisType ! else: # type is inconsistent, remove column from consideration ! del columnTypes[col] ! ! # finally, compare results against first row and "vote" on whether it's a header ! hasHeader = 0 ! for col, colType in columnTypes.items(): ! if type(colType) == type(0): # it's a length ! if len(header[col]) != colType: ! hasHeader += 1 ! else: ! hasHeader -= 1 ! else: # attempt typecast ! try: ! eval("%s(%s)" % (colType.__name__, header[col])) ! except: ! hasHeader += 1 ! else: ! hasHeader -= 1 - return hasHeader > 0 - --- 212,289 ---- ! def _hasHeaders(self, fileobj, dialect): ! # Creates a dictionary of types of data in each column. If any column ! # is of a single type (say, integers), *except* for the first row, then the first ! # row is presumed to be labels. If the type can't be determined, it is assumed to ! # be a string in which case the length of the string is the determining factor: if ! # all of the rows except for the first are the same length, it's a header. ! # Finally, a 'vote' is taken at the end for each column, adding or subtracting from ! # the likelihood of the first row being a header. ! def seval(item): ! """ ! Strips parens from item prior to calling eval in an attempt to make it safer ! """ ! return eval(item.replace('(', '').replace(')', '')) ! fileobj.seek(0) # rewind the fileobj - this might not work for some file-like objects... ! reader = csv.reader(fileobj, ! delimiter = dialect.delimiter, ! quotechar = dialect.quotechar, ! skipinitialspace = dialect.skipinitialspace) ! header = reader.next() # assume first row is header ! columns = len(header) ! columnTypes = {} ! for i in range(columns): columnTypes[i] = None ! ! checked = 0 ! for row in reader: ! if checked > 20: # arbitrary number of rows to check, to keep it sane ! break ! checked += 1 ! ! if len(row) != columns: ! continue # skip rows that have irregular number of columns ! ! for col in columnTypes.keys(): try: ! try: ! # is it a built-in type (besides string)? ! thisType = type(seval(row[col])) ! except OverflowError: ! # a long int? ! thisType = type(seval(row[col] + 'L')) ! thisType = type(0) # treat long ints as int ! except: ! # fallback to length of string ! thisType = len(row[col]) ! if thisType != columnTypes[col]: ! if columnTypes[col] is None: # add new column type ! columnTypes[col] = thisType ! else: # type is inconsistent, remove column from consideration ! del columnTypes[col] ! ! # finally, compare results against first row and "vote" on whether it's a header ! hasHeader = 0 ! for col, colType in columnTypes.items(): ! if type(colType) == type(0): # it's a length ! if len(header[col]) != colType: ! hasHeader += 1 ! else: ! hasHeader -= 1 ! else: # attempt typecast ! try: ! eval("%s(%s)" % (colType.__name__, header[col])) ! except: ! hasHeader += 1 ! else: ! hasHeader -= 1 ! ! return hasHeader > 0 From niemeyer@users.sourceforge.net Wed Mar 19 00:35:37 2003 From: niemeyer@users.sourceforge.net (niemeyer@users.sourceforge.net) Date: Tue, 18 Mar 2003 16:35:37 -0800 Subject: [Python-checkins] python/dist/src/Include pystate.h,2.22,2.23 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv14162/Include Modified Files: pystate.h Log Message: Fixed SF bug #663074. The codec system was using global static variables to store internal data. As a result, any atempts to use the unicode system with multiple active interpreters, or successive interpreter executions, would fail. Now that information is stored into members of the PyInterpreterState structure. Index: pystate.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pystate.h,v retrieving revision 2.22 retrieving revision 2.23 diff -C2 -d -r2.22 -r2.23 *** pystate.h 19 Feb 2003 15:53:14 -0000 2.22 --- pystate.h 19 Mar 2003 00:35:35 -0000 2.23 *************** *** 23,26 **** --- 23,30 ---- PyObject *builtins; + PyObject *codec_search_path; + PyObject *codec_search_cache; + PyObject *codec_error_registry; + #ifdef HAVE_DLOPEN int dlopenflags; From niemeyer@users.sourceforge.net Wed Mar 19 00:35:38 2003 From: niemeyer@users.sourceforge.net (niemeyer@users.sourceforge.net) Date: Tue, 18 Mar 2003 16:35:38 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.698,1.699 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv14162/Misc Modified Files: NEWS Log Message: Fixed SF bug #663074. The codec system was using global static variables to store internal data. As a result, any atempts to use the unicode system with multiple active interpreters, or successive interpreter executions, would fail. Now that information is stored into members of the PyInterpreterState structure. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.698 retrieving revision 1.699 diff -C2 -d -r1.698 -r1.699 *** NEWS 17 Mar 2003 19:46:03 -0000 1.698 --- NEWS 19 Mar 2003 00:35:35 -0000 1.699 *************** *** 30,33 **** --- 30,38 ---- if the key value was larger than 2**32. See SF bug #689659. + - Fixed SF bug #663074. The codec system was using global static + variables to store internal data. As a result, any atempts to use the + unicode system with multiple active interpreters, or successive + interpreter executions, would fail. + Extension modules ----------------- From niemeyer@users.sourceforge.net Wed Mar 19 00:35:38 2003 From: niemeyer@users.sourceforge.net (niemeyer@users.sourceforge.net) Date: Tue, 18 Mar 2003 16:35:38 -0800 Subject: [Python-checkins] python/dist/src/Python codecs.c,2.20,2.21 pystate.c,2.23,2.24 pythonrun.c,2.181,2.182 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory sc8-pr-cvs1:/tmp/cvs-serv14162/Python Modified Files: codecs.c pystate.c pythonrun.c Log Message: Fixed SF bug #663074. The codec system was using global static variables to store internal data. As a result, any atempts to use the unicode system with multiple active interpreters, or successive interpreter executions, would fail. Now that information is stored into members of the PyInterpreterState structure. Index: codecs.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/codecs.c,v retrieving revision 2.20 retrieving revision 2.21 diff -C2 -d -r2.20 -r2.21 *** codecs.c 14 Feb 2003 20:25:56 -0000 2.20 --- codecs.c 19 Mar 2003 00:35:35 -0000 2.21 *************** *** 12,23 **** #include - /* --- Globals ------------------------------------------------------------ */ - - static PyObject *_PyCodec_SearchPath; - static PyObject *_PyCodec_SearchCache; - - /* Flag used for lazy import of the standard encodings package */ - static int import_encodings_called = 0; - /* --- Codec Registry ----------------------------------------------------- */ --- 12,15 ---- *************** *** 33,65 **** */ ! static ! int import_encodings(void) ! { ! PyObject *mod; ! ! import_encodings_called = 1; ! mod = PyImport_ImportModuleEx("encodings", NULL, NULL, NULL); ! if (mod == NULL) { ! if (PyErr_ExceptionMatches(PyExc_ImportError)) { ! /* Ignore ImportErrors... this is done so that ! distributions can disable the encodings package. Note ! that other errors are not masked, e.g. SystemErrors ! raised to inform the user of an error in the Python ! configuration are still reported back to the user. */ ! PyErr_Clear(); ! return 0; ! } ! return -1; ! } ! Py_DECREF(mod); ! return 0; ! } int PyCodec_Register(PyObject *search_function) { ! if (!import_encodings_called) { ! if (import_encodings()) ! goto onError; ! } if (search_function == NULL) { PyErr_BadArgument(); --- 25,35 ---- */ ! static int _PyCodecRegistry_Init(void); /* Forward */ int PyCodec_Register(PyObject *search_function) { ! PyInterpreterState *interp = PyThreadState_Get()->interp; ! if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) ! goto onError; if (search_function == NULL) { PyErr_BadArgument(); *************** *** 71,75 **** goto onError; } ! return PyList_Append(_PyCodec_SearchPath, search_function); onError: --- 41,45 ---- goto onError; } ! return PyList_Append(interp->codec_search_path, search_function); onError: *************** *** 125,128 **** --- 95,99 ---- PyObject *_PyCodec_Lookup(const char *encoding) { + PyInterpreterState *interp; PyObject *result, *args = NULL, *v; int i, len; *************** *** 132,145 **** goto onError; } ! if (_PyCodec_SearchCache == NULL || ! _PyCodec_SearchPath == NULL) { ! PyErr_SetString(PyExc_SystemError, ! "codec module not properly initialized"); goto onError; - } - if (!import_encodings_called) { - if (import_encodings()) - goto onError; - } /* Convert the encoding to a normalized Python string: all --- 103,110 ---- goto onError; } ! ! interp = PyThreadState_Get()->interp; ! if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) goto onError; /* Convert the encoding to a normalized Python string: all *************** *** 152,156 **** /* First, try to lookup the name in the registry dictionary */ ! result = PyDict_GetItem(_PyCodec_SearchCache, v); if (result != NULL) { Py_INCREF(result); --- 117,121 ---- /* First, try to lookup the name in the registry dictionary */ ! result = PyDict_GetItem(interp->codec_search_cache, v); if (result != NULL) { Py_INCREF(result); *************** *** 165,169 **** PyTuple_SET_ITEM(args,0,v); ! len = PyList_Size(_PyCodec_SearchPath); if (len < 0) goto onError; --- 130,134 ---- PyTuple_SET_ITEM(args,0,v); ! len = PyList_Size(interp->codec_search_path); if (len < 0) goto onError; *************** *** 178,182 **** PyObject *func; ! func = PyList_GetItem(_PyCodec_SearchPath, i); if (func == NULL) goto onError; --- 143,147 ---- PyObject *func; ! func = PyList_GetItem(interp->codec_search_path, i); if (func == NULL) goto onError; *************** *** 204,208 **** /* Cache and return the result */ ! PyDict_SetItem(_PyCodec_SearchCache, v, result); Py_DECREF(args); return result; --- 169,173 ---- /* Cache and return the result */ ! PyDict_SetItem(interp->codec_search_cache, v, result); Py_DECREF(args); return result; *************** *** 423,428 **** } - static PyObject *_PyCodec_ErrorRegistry; - /* Register the error handling callback function error under the name name. This function will be called by the codec when it encounters --- 388,391 ---- *************** *** 433,441 **** int PyCodec_RegisterError(const char *name, PyObject *error) { if (!PyCallable_Check(error)) { PyErr_SetString(PyExc_TypeError, "handler must be callable"); return -1; } ! return PyDict_SetItemString( _PyCodec_ErrorRegistry, (char *)name, error); } --- 396,408 ---- int PyCodec_RegisterError(const char *name, PyObject *error) { + PyInterpreterState *interp = PyThreadState_Get()->interp; + if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) + return -1; if (!PyCallable_Check(error)) { PyErr_SetString(PyExc_TypeError, "handler must be callable"); return -1; } ! return PyDict_SetItemString(interp->codec_error_registry, ! (char *)name, error); } *************** *** 447,453 **** PyObject *handler = NULL; if (name==NULL) name = "strict"; ! handler = PyDict_GetItemString(_PyCodec_ErrorRegistry, (char *)name); if (!handler) PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name); --- 414,424 ---- PyObject *handler = NULL; + PyInterpreterState *interp = PyThreadState_Get()->interp; + if (interp->codec_search_path == NULL && _PyCodecRegistry_Init()) + return NULL; + if (name==NULL) name = "strict"; ! handler = PyDict_GetItemString(interp->codec_error_registry, (char *)name); if (!handler) PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name); *************** *** 763,768 **** #endif ! ! void _PyCodecRegistry_Init(void) { static struct { --- 734,738 ---- #endif ! static int _PyCodecRegistry_Init(void) { static struct { *************** *** 814,850 **** #endif }; - if (_PyCodec_SearchPath == NULL) - _PyCodec_SearchPath = PyList_New(0); - if (_PyCodec_SearchCache == NULL) - _PyCodec_SearchCache = PyDict_New(); - if (_PyCodec_ErrorRegistry == NULL) { - int i; - _PyCodec_ErrorRegistry = PyDict_New(); ! if (_PyCodec_ErrorRegistry) { ! for (i = 0; i < sizeof(methods)/sizeof(methods[0]); ++i) { ! PyObject *func = PyCFunction_New(&methods[i].def, NULL); ! int res; ! if (!func) ! Py_FatalError("can't initialize codec error registry"); ! res = PyCodec_RegisterError(methods[i].name, func); ! Py_DECREF(func); ! if (res) ! Py_FatalError("can't initialize codec error registry"); ! } } } ! if (_PyCodec_SearchPath == NULL || ! _PyCodec_SearchCache == NULL) Py_FatalError("can't initialize codec registry"); - } ! void _PyCodecRegistry_Fini(void) ! { ! Py_XDECREF(_PyCodec_SearchPath); ! _PyCodec_SearchPath = NULL; ! Py_XDECREF(_PyCodec_SearchCache); ! _PyCodec_SearchCache = NULL; ! Py_XDECREF(_PyCodec_ErrorRegistry); ! _PyCodec_ErrorRegistry = NULL; } --- 784,831 ---- #endif }; ! PyInterpreterState *interp = PyThreadState_Get()->interp; ! PyObject *mod; ! int i; ! ! if (interp->codec_search_path != NULL) ! return 0; ! ! interp->codec_search_path = PyList_New(0); ! interp->codec_search_cache = PyDict_New(); ! interp->codec_error_registry = PyDict_New(); ! ! if (interp->codec_error_registry) { ! for (i = 0; i < sizeof(methods)/sizeof(methods[0]); ++i) { ! PyObject *func = PyCFunction_New(&methods[i].def, NULL); ! int res; ! if (!func) ! Py_FatalError("can't initialize codec error registry"); ! res = PyCodec_RegisterError(methods[i].name, func); ! Py_DECREF(func); ! if (res) ! Py_FatalError("can't initialize codec error registry"); } } ! ! if (interp->codec_search_path == NULL || ! interp->codec_search_cache == NULL || ! interp->codec_error_registry == NULL) Py_FatalError("can't initialize codec registry"); ! mod = PyImport_ImportModuleEx("encodings", NULL, NULL, NULL); ! if (mod == NULL) { ! if (PyErr_ExceptionMatches(PyExc_ImportError)) { ! /* Ignore ImportErrors... this is done so that ! distributions can disable the encodings package. Note ! that other errors are not masked, e.g. SystemErrors ! raised to inform the user of an error in the Python ! configuration are still reported back to the user. */ ! PyErr_Clear(); ! return 0; ! } ! return -1; ! } ! Py_DECREF(mod); ! return 0; } Index: pystate.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pystate.c,v retrieving revision 2.23 retrieving revision 2.24 diff -C2 -d -r2.23 -r2.24 *** pystate.c 19 Feb 2003 15:53:17 -0000 2.23 --- pystate.c 19 Mar 2003 00:35:36 -0000 2.24 *************** *** 50,53 **** --- 50,56 ---- interp->builtins = NULL; interp->tstate_head = NULL; + interp->codec_search_path = NULL; + interp->codec_search_cache = NULL; + interp->codec_error_registry = NULL; #ifdef HAVE_DLOPEN #ifdef RTLD_NOW *************** *** 76,79 **** --- 79,85 ---- PyThreadState_Clear(p); HEAD_UNLOCK(); + ZAP(interp->codec_search_path); + ZAP(interp->codec_search_cache); + ZAP(interp->codec_error_registry); ZAP(interp->modules); ZAP(interp->sysdict); Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.181 retrieving revision 2.182 diff -C2 -d -r2.181 -r2.182 *** pythonrun.c 5 Mar 2003 17:31:21 -0000 2.181 --- pythonrun.c 19 Mar 2003 00:35:36 -0000 2.182 *************** *** 50,55 **** extern void _PyUnicode_Init(void); extern void _PyUnicode_Fini(void); - extern void _PyCodecRegistry_Init(void); - extern void _PyCodecRegistry_Fini(void); int Py_DebugFlag; /* Needed by parser.c */ --- 50,53 ---- *************** *** 145,151 **** Py_FatalError("Py_Initialize: can't make modules dictionary"); - /* Init codec registry */ - _PyCodecRegistry_Init(); - #ifdef Py_USING_UNICODE /* Init Unicode implementation; relies on the codec registry */ --- 143,146 ---- *************** *** 257,263 **** /* Disable signal handling */ PyOS_FiniInterrupts(); - - /* Cleanup Codec registry */ - _PyCodecRegistry_Fini(); /* drop module references we saved */ --- 252,255 ---- From jackjansen@users.sourceforge.net Wed Mar 19 22:51:45 2003 From: jackjansen@users.sourceforge.net (jackjansen@users.sourceforge.net) Date: Wed, 19 Mar 2003 14:51:45 -0800 Subject: [Python-checkins] python/dist/src/Mac/Modules macosmodule.c,1.65,1.66 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv27647 Modified Files: macosmodule.c Log Message: GetCreatorAndType and SetCreatorAndType have been undeprecated. Spotted by Just. Index: macosmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/macosmodule.c,v retrieving revision 1.65 retrieving revision 1.66 diff -C2 -d -r1.65 -r1.66 *** macosmodule.c 23 Feb 2003 23:23:47 -0000 1.65 --- macosmodule.c 19 Mar 2003 22:51:42 -0000 1.66 *************** *** 305,309 **** /* Miscellaneous File System Operations */ ! static char getcrtp_doc[] = "Obsolete, use macfs module"; static PyObject * --- 305,309 ---- /* Miscellaneous File System Operations */ ! static char getcrtp_doc[] = "Get MacOS 4-char creator and type for a file"; static PyObject * *************** *** 327,331 **** } ! static char setcrtp_doc[] = "Obsolete, use macfs module"; static PyObject * --- 327,331 ---- } ! static char setcrtp_doc[] = "Set MacOS 4-char creator and type for a file"; static PyObject * From nnorwitz@users.sourceforge.net Thu Mar 20 04:33:19 2003 From: nnorwitz@users.sourceforge.net (nnorwitz@users.sourceforge.net) Date: Wed, 19 Mar 2003 20:33:19 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_ioctl.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv11301/Lib/test Modified Files: test_ioctl.py Log Message: Skip the ioctl test if we can't open /dev/tty. This happens on Solaris (and probably other Unixes) when run without a terminal (eg, from cron or at). Index: test_ioctl.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_ioctl.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_ioctl.py 3 Mar 2003 12:29:42 -0000 1.1 --- test_ioctl.py 20 Mar 2003 04:33:16 -0000 1.2 *************** *** 9,12 **** --- 9,18 ---- raise TestSkipped("termios module doesn't have TIOCGPGRP") + try: + tty = open("/dev/tty", "r") + tty.close() + except IOError: + raise TestSkipped("Unable to open /dev/tty") + class IoctlTests(unittest.TestCase): def test_ioctl(self): From fdrake@users.sourceforge.net Thu Mar 20 17:39:42 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Thu, 20 Mar 2003 09:39:42 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libos.tex,1.115,1.116 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv10101 Modified Files: libos.tex Log Message: - explain what a UNC path is in the makedirs() description, since they're actually mentioned there - remove some extraneous paragraph separations - \versionadded --> \versionchanged in one place Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.115 retrieving revision 1.116 diff -C2 -d -r1.115 -r1.116 *** libos.tex 3 Mar 2003 17:32:12 -0000 1.115 --- libos.tex 20 Mar 2003 17:39:38 -0000 1.116 *************** *** 712,716 **** Availability: Macintosh, \UNIX, Windows. ! \versionadded[On Windows NT/2k/XP and Unix, if \var{path} is a Unicode object, the result will be a list of Unicode objects.]{2.3} \end{funcdesc} --- 712,716 ---- Availability: Macintosh, \UNIX, Windows. ! \versionchanged[On Windows NT/2k/XP and Unix, if \var{path} is a Unicode object, the result will be a list of Unicode objects.]{2.3} \end{funcdesc} *************** *** 743,747 **** defines the newly created device special file (probably using \function{os.makedev()}), otherwise it is ignored. - \versionadded{2.3} \end{funcdesc} --- 743,746 ---- *************** *** 749,753 **** \begin{funcdesc}{major}{device} Extracts a device major number from a raw device number. - \versionadded{2.3} \end{funcdesc} --- 748,751 ---- *************** *** 755,759 **** \begin{funcdesc}{minor}{device} Extracts a device minor number from a raw device number. - \versionadded{2.3} \end{funcdesc} --- 753,756 ---- *************** *** 761,765 **** \begin{funcdesc}{makedev}{major, minor} Composes a raw device number from the major and minor device numbers. - \versionadded{2.3} \end{funcdesc} --- 758,761 ---- *************** *** 774,784 **** \begin{funcdesc}{makedirs}{path\optional{, mode}} ! \index{directory!creating} ! Recursive directory creation function. Like \function{mkdir()}, but makes all intermediate-level directories needed to contain the leaf directory. Throws an \exception{error} exception if the leaf directory already exists or cannot be created. The default \var{mode} is \code{0777} (octal). This function does not properly handle UNC ! paths (only relevant on Windows systems). \versionadded{1.5.2} \end{funcdesc} --- 770,782 ---- \begin{funcdesc}{makedirs}{path\optional{, mode}} ! Recursive directory creation function.\index{directory!creating} ! \index{UNC paths!and \function{os.makedirs()}} ! Like \function{mkdir()}, but makes all intermediate-level directories needed to contain the leaf directory. Throws an \exception{error} exception if the leaf directory already exists or cannot be created. The default \var{mode} is \code{0777} (octal). This function does not properly handle UNC ! paths (only relevant on Windows systems; Universal Naming Convention ! paths are those that use the `\code{\e\e host\e path}' syntax). \versionadded{1.5.2} \end{funcdesc} From fdrake@users.sourceforge.net Thu Mar 20 17:42:54 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Thu, 20 Mar 2003 09:42:54 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libos.tex,1.74.2.1.2.12,1.74.2.1.2.13 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv11734 Modified Files: Tag: release22-maint libos.tex Log Message: - explain what a UNC path is in the makedirs() description, since they're actually mentioned there Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.74.2.1.2.12 retrieving revision 1.74.2.1.2.13 diff -C2 -d -r1.74.2.1.2.12 -r1.74.2.1.2.13 *** libos.tex 14 Feb 2003 06:46:24 -0000 1.74.2.1.2.12 --- libos.tex 20 Mar 2003 17:42:48 -0000 1.74.2.1.2.13 *************** *** 673,682 **** \begin{funcdesc}{makedirs}{path\optional{, mode}} \index{directory!creating} ! Recursive directory creation function. Like \function{mkdir()}, but makes all intermediate-level directories needed to contain the leaf directory. Throws an \exception{error} exception if the leaf directory already exists or cannot be created. The default \var{mode} is \code{0777} (octal). This function does not properly handle UNC ! paths (only relevant on Windows systems). \versionadded{1.5.2} \end{funcdesc} --- 673,685 ---- \begin{funcdesc}{makedirs}{path\optional{, mode}} \index{directory!creating} ! Recursive directory creation function.\index{directory!creating} ! \index{UNC paths!and \function{os.makedirs()}} ! Like \function{mkdir()}, but makes all intermediate-level directories needed to contain the leaf directory. Throws an \exception{error} exception if the leaf directory already exists or cannot be created. The default \var{mode} is \code{0777} (octal). This function does not properly handle UNC ! paths (only relevant on Windows systems; Universal Naming Convention ! paths are those that use the `\code{\e\e host\e path}' syntax). \versionadded{1.5.2} \end{funcdesc} From montanaro@users.sourceforge.net Thu Mar 20 17:58:16 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 20 Mar 2003 09:58:16 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libsocket.tex,1.68,1.69 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv19874 Modified Files: libsocket.tex Log Message: add descriptions of {get,set}defaulttimeout. Index: libsocket.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsocket.tex,v retrieving revision 1.68 retrieving revision 1.69 diff -C2 -d -r1.68 -r1.69 *** libsocket.tex 13 Jun 2002 15:07:43 -0000 1.68 --- libsocket.tex 20 Mar 2003 17:58:12 -0000 1.69 *************** *** 350,353 **** --- 350,367 ---- \end{funcdesc} + \begin{funcdesc}{getdefaulttimeout}{} + Return the default timeout in floating seconds for new socket objects. + A value of \code{None} indicates that new socket objects have no timeout. + When the socket module is first imported, the default is \code{None}. + \versionadded{2.3} + \end{funcdesc} + + \begin{funcdesc}{setdefaulttimeout}{timeout} + Set the default timeout in floating seconds for new socket objects. + A value of \code{None} indicates that new socket objects have no timeout. + When the socket module is first imported, the default is \code{None}. + \versionadded{2.3} + \end{funcdesc} + \begin{datadesc}{SocketType} This is a Python type object that represents the socket object type. From fdrake@users.sourceforge.net Thu Mar 20 18:17:19 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Thu, 20 Mar 2003 10:17:19 -0800 Subject: [Python-checkins] python/dist/src/Doc/ref ref3.tex,1.101,1.102 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1:/tmp/cvs-serv32744 Modified Files: ref3.tex Log Message: - apply SF patch #700798: fixes and cleanups for descriptor info - use a TeX "tie" to prevent word-wrapping in "section x.y"-like text Index: ref3.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v retrieving revision 1.101 retrieving revision 1.102 diff -C2 -d -r1.101 -r1.102 *** ref3.tex 5 Mar 2003 14:20:58 -0000 1.101 --- ref3.tex 20 Mar 2003 18:17:16 -0000 1.102 *************** *** 408,412 **** Dictionaries are mutable; they can be created by the ! \code{\{...\}} notation (see section \ref{dict}, ``Dictionary Displays''). --- 408,412 ---- Dictionaries are mutable; they can be created by the ! \code{\{...\}} notation (see section~\ref{dict}, ``Dictionary Displays''). *************** *** 419,423 **** \item[Callable types] These\obindex{callable} are the types to which the function call ! operation (see section \ref{calls}, ``Calls'') can be applied: \indexii{function}{call} \index{invocation} --- 419,423 ---- \item[Callable types] These\obindex{callable} are the types to which the function call ! operation (see section~\ref{calls}, ``Calls'') can be applied: \indexii{function}{call} \index{invocation} *************** *** 428,432 **** \item[User-defined functions] A user-defined function object is created by a function definition ! (see section \ref{function}, ``Function definitions''). It should be called with an argument list containing the same number of items as the function's formal --- 428,432 ---- \item[User-defined functions] A user-defined function object is created by a function definition ! (see section~\ref{function}, ``Function definitions''). It should be called with an argument list containing the same number of items as the function's formal *************** *** 602,607 **** \item[Modules] ! Modules are imported by the \keyword{import} statement (see section ! \ref{import}, ``The \keyword{import} statement''). A module object has a namespace implemented by a dictionary object (this is the dictionary referenced by the func_globals attribute of --- 602,607 ---- \item[Modules] ! Modules are imported by the \keyword{import} statement (see ! section~\ref{import}, ``The \keyword{import} statement''). A module object has a namespace implemented by a dictionary object (this is the dictionary referenced by the func_globals attribute of *************** *** 638,643 **** \item[Classes] ! Class objects are created by class definitions (see section ! \ref{class}, ``Class definitions''). A class has a namespace implemented by a dictionary object. Class attribute references are translated to --- 638,643 ---- \item[Classes] ! Class objects are created by class definitions (see ! section~\ref{class}, ``Class definitions''). A class has a namespace implemented by a dictionary object. Class attribute references are translated to *************** *** 709,713 **** Class instances can pretend to be numbers, sequences, or mappings if they have methods with certain special names. See ! section \ref{specialnames}, ``Special method names.'' \obindex{numeric} \obindex{sequence} --- 709,713 ---- Class instances can pretend to be numbers, sequences, or mappings if they have methods with certain special names. See ! section~\ref{specialnames}, ``Special method names.'' \obindex{numeric} \obindex{sequence} *************** *** 866,870 **** traceback. When an exception handler is entered, the stack trace is made available to the program. ! (See section \ref{try}, ``The \code{try} statement.'') It is accessible as \code{sys.exc_traceback}, and also as the third item of the tuple returned by \code{sys.exc_info()}. The latter is --- 866,870 ---- traceback. When an exception handler is entered, the stack trace is made available to the program. ! (See section~\ref{try}, ``The \code{try} statement.'') It is accessible as \code{sys.exc_traceback}, and also as the third item of the tuple returned by \code{sys.exc_info()}. The latter is *************** *** 1212,1216 **** In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same ! name to access any attributes it needs to access, for example, \samp{object.__getattribute__(self, name)}. \end{methoddesc} --- 1212,1216 ---- In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same ! name to access any attributes it needs, for example, \samp{object.__getattribute__(self, name)}. \end{methoddesc} *************** *** 1219,1230 **** The following methods only apply when an instance of the class ! containing the method (a so-called \emph{descriptor} class) is in the class dictionary of another new-style class, known as the \emph{owner} class. In the examples below, ``the attribute'' refers to ! the attribute whose name is the key of the property in the accessed class' \code{__dict__}. \begin{methoddesc}[object]{__get__}{self, instance, owner} ! Called to get the attribute of the owner class (class attribute acess) or of an instance of that class (instance attribute acces). \var{owner} is always the owner class, while \var{instance} is the --- 1219,1230 ---- The following methods only apply when an instance of the class ! containing the method (a so-called \emph{descriptor} class) appears in the class dictionary of another new-style class, known as the \emph{owner} class. In the examples below, ``the attribute'' refers to ! the attribute whose name is the key of the property in the owner class' \code{__dict__}. \begin{methoddesc}[object]{__get__}{self, instance, owner} ! Called to get the attribute of the owner class (class attribute access) or of an instance of that class (instance attribute acces). \var{owner} is always the owner class, while \var{instance} is the From fdrake@users.sourceforge.net Thu Mar 20 18:22:53 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Thu, 20 Mar 2003 10:22:53 -0800 Subject: [Python-checkins] python/dist/src/Doc/ref ref3.tex,1.82.4.7,1.82.4.8 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory sc8-pr-cvs1:/tmp/cvs-serv3723 Modified Files: Tag: release22-maint ref3.tex Log Message: - backport portions of SF patch #700798: fixes and cleanups for descriptor info - use a TeX "tie" to prevent word-wrapping in "section x.y"-like text Index: ref3.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v retrieving revision 1.82.4.7 retrieving revision 1.82.4.8 diff -C2 -d -r1.82.4.7 -r1.82.4.8 *** ref3.tex 19 Jan 2003 14:54:08 -0000 1.82.4.7 --- ref3.tex 20 Mar 2003 18:22:50 -0000 1.82.4.8 *************** *** 389,393 **** Dictionaries are mutable; they can be created by the ! \code{\{...\}} notation (see section \ref{dict}, ``Dictionary Displays''). --- 389,393 ---- Dictionaries are mutable; they can be created by the ! \code{\{...\}} notation (see section~\ref{dict}, ``Dictionary Displays''). *************** *** 400,404 **** \item[Callable types] These\obindex{callable} are the types to which the function call ! operation (see section \ref{calls}, ``Calls'') can be applied: \indexii{function}{call} \index{invocation} --- 400,404 ---- \item[Callable types] These\obindex{callable} are the types to which the function call ! operation (see section~\ref{calls}, ``Calls'') can be applied: \indexii{function}{call} \index{invocation} *************** *** 409,413 **** \item[User-defined functions] A user-defined function object is created by a function definition ! (see section \ref{function}, ``Function definitions''). It should be called with an argument list containing the same number of items as the function's formal --- 409,413 ---- \item[User-defined functions] A user-defined function object is created by a function definition ! (see section~\ref{function}, ``Function definitions''). It should be called with an argument list containing the same number of items as the function's formal *************** *** 577,582 **** \item[Modules] ! Modules are imported by the \keyword{import} statement (see section ! \ref{import}, ``The \keyword{import} statement''). A module object has a namespace implemented by a dictionary object (this is the dictionary referenced by the func_globals attribute of --- 577,582 ---- \item[Modules] ! Modules are imported by the \keyword{import} statement (see ! section~\ref{import}, ``The \keyword{import} statement''). A module object has a namespace implemented by a dictionary object (this is the dictionary referenced by the func_globals attribute of *************** *** 613,618 **** \item[Classes] ! Class objects are created by class definitions (see section ! \ref{class}, ``Class definitions''). A class has a namespace implemented by a dictionary object. Class attribute references are translated to --- 613,618 ---- \item[Classes] ! Class objects are created by class definitions (see ! section~\ref{class}, ``Class definitions''). A class has a namespace implemented by a dictionary object. Class attribute references are translated to *************** *** 684,688 **** Class instances can pretend to be numbers, sequences, or mappings if they have methods with certain special names. See ! section \ref{specialnames}, ``Special method names.'' \obindex{numeric} \obindex{sequence} --- 684,688 ---- Class instances can pretend to be numbers, sequences, or mappings if they have methods with certain special names. See ! section~\ref{specialnames}, ``Special method names.'' \obindex{numeric} \obindex{sequence} *************** *** 834,838 **** traceback. When an exception handler is entered, the stack trace is made available to the program. ! (See section \ref{try}, ``The \code{try} statement.'') It is accessible as \code{sys.exc_traceback}, and also as the third item of the tuple returned by \code{sys.exc_info()}. The latter is --- 834,838 ---- traceback. When an exception handler is entered, the stack trace is made available to the program. ! (See section~\ref{try}, ``The \code{try} statement.'') It is accessible as \code{sys.exc_traceback}, and also as the third item of the tuple returned by \code{sys.exc_info()}. The latter is From tim_one@users.sourceforge.net Thu Mar 20 18:31:30 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 20 Mar 2003 10:31:30 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_struct.py,1.14,1.14.12.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv6172/Lib/test Modified Files: Tag: release22-maint test_struct.py Log Message: SF bug 705836: struct.pack of floats in non-native endian order pack_float, pack_double, save_float: All the routines for creating IEEE-format packed representations of floats and doubles simply ignored that rounding can (in rare cases) propagate out of a long string of 1 bits. At worst, the end-off carry can (by mistake) interfere with the exponent value, and then unpacking yields a result wrong by a factor of 2. In less severe cases, it can end up losing more low-order bits than intended, or fail to catch overflow *caused* by rounding. Index: test_struct.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_struct.py,v retrieving revision 1.14 retrieving revision 1.14.12.1 diff -C2 -d -r1.14 -r1.14.12.1 *** test_struct.py 15 Sep 2001 02:35:15 -0000 1.14 --- test_struct.py 20 Mar 2003 18:30:52 -0000 1.14.12.1 *************** *** 394,395 **** --- 394,441 ---- test_p_code() + + + ########################################################################### + # SF bug 705836. "f" had a severe rounding bug, where a carry + # from the low-order discarded bits could propagate into the exponent + # field, causing the result to be wrong by a factor of 2. + + def test_705836(): + import math + + for base in range(1, 33): + # smaller <- largest representable float less than base. + delta = 0.5 + while base - delta / 2.0 != base: + delta /= 2.0 + smaller = base - delta + # Packing this rounds away a solid string of trailing 1 bits. + packed = struct.pack("f", smaller) + verify(bigpacked == string_reverse(packed), + ">f pack should be byte-reversal of f", bigpacked)[0] + verify(base == unpacked) + + # Largest finite IEEE single. + big = (1 << 24) - 1 + big = math.ldexp(big, 127 - 23) + packed = struct.pack(">f", big) + unpacked = struct.unpack(">f", packed)[0] + verify(big == unpacked) + + # The same, but tack on a 1 bit so it rounds up to infinity. + big = (1 << 25) - 1 + big = math.ldexp(big, 127 - 24) + try: + packed = struct.pack(">f", big) + except OverflowError: + pass + else: + TestFailed("expected OverflowError") + + test_705836() From tim_one@users.sourceforge.net Thu Mar 20 18:31:30 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 20 Mar 2003 10:31:30 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.73.2.1.2.3,2.73.2.1.2.4 structmodule.c,2.51.8.1,2.51.8.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv6172/Modules Modified Files: Tag: release22-maint cPickle.c structmodule.c Log Message: SF bug 705836: struct.pack of floats in non-native endian order pack_float, pack_double, save_float: All the routines for creating IEEE-format packed representations of floats and doubles simply ignored that rounding can (in rare cases) propagate out of a long string of 1 bits. At worst, the end-off carry can (by mistake) interfere with the exponent value, and then unpacking yields a result wrong by a factor of 2. In less severe cases, it can end up losing more low-order bits than intended, or fail to catch overflow *caused* by rounding. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.73.2.1.2.3 retrieving revision 2.73.2.1.2.4 diff -C2 -d -r2.73.2.1.2.3 -r2.73.2.1.2.4 *** cPickle.c 24 Sep 2002 11:53:34 -0000 2.73.2.1.2.3 --- cPickle.c 20 Mar 2003 18:31:13 -0000 2.73.2.1.2.4 *************** *** 706,710 **** static int put(Picklerobject *self, PyObject *ob) { ! if (ob->ob_refcnt < 2 || self->fast) return 0; --- 706,710 ---- static int put(Picklerobject *self, PyObject *ob) { ! if (ob->ob_refcnt < 2 || self->fast) return 0; *************** *** 922,926 **** } ! int fast_save_leave(Picklerobject *self, PyObject *obj) { --- 922,926 ---- } ! int fast_save_leave(Picklerobject *self, PyObject *obj) { *************** *** 1065,1074 **** } ! if (e >= 1024) { ! /* XXX 1024 itself is reserved for Inf/NaN */ ! PyErr_SetString(PyExc_OverflowError, ! "float too large to pack with d format"); ! return -1; ! } else if (e < -1022) { /* Gradual underflow */ --- 1065,1070 ---- } ! if (e >= 1024) ! goto Overflow; else if (e < -1022) { /* Gradual underflow */ *************** *** 1084,1090 **** --- 1080,1103 ---- f *= 268435456.0; /* 2**28 */ fhi = (long) floor(f); /* Truncate */ + assert(fhi < 268435456); + f -= (double)fhi; f *= 16777216.0; /* 2**24 */ flo = (long) floor(f + 0.5); /* Round */ + assert(flo <= 16777216); + if (flo >> 24) { + /* The carry propagated out of a string of 24 1 bits. */ + flo = 0; + ++fhi; + if (fhi >> 28) { + /* And it also progagated out of the next + * 28 bits. + */ + fhi = 0; + ++e; + if (e >= 2047) + goto Overflow; + } + } /* First byte */ *************** *** 1132,1135 **** --- 1145,1153 ---- return 0; + + Overflow: + PyErr_SetString(PyExc_OverflowError, + "float too large to pack with d format"); + return -1; } *************** *** 2104,2110 **** 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); --- 2122,2128 ---- 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); *************** *** 2121,2125 **** /* Can be called by Python code or C code */ ! if (args && !PyArg_ParseTuple(args, "|i:getvalue", &clear)) return NULL; --- 2139,2143 ---- /* Can be called by Python code or C code */ ! if (args && !PyArg_ParseTuple(args, "|i:getvalue", &clear)) return NULL; *************** *** 2483,2487 **** 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}, --- 2501,2505 ---- 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}, Index: structmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v retrieving revision 2.51.8.1 retrieving revision 2.51.8.2 diff -C2 -d -r2.51.8.1 -r2.51.8.2 *** structmodule.c 23 Sep 2002 20:54:04 -0000 2.51.8.1 --- structmodule.c 20 Mar 2003 18:31:20 -0000 2.51.8.2 *************** *** 226,235 **** } ! if (e >= 128) { ! /* XXX 128 itself is reserved for Inf/NaN */ ! PyErr_SetString(PyExc_OverflowError, ! "float too large to pack with f format"); ! return -1; ! } else if (e < -126) { /* Gradual underflow */ --- 226,231 ---- } ! if (e >= 128) ! goto Overflow; else if (e < -126) { /* Gradual underflow */ *************** *** 244,247 **** --- 240,251 ---- f *= 8388608.0; /* 2**23 */ fbits = (long) floor(f + 0.5); /* Round */ + assert(fbits <= 8388608); + if (fbits >> 23) { + /* The carry propagated out of a string of 23 1 bits. */ + fbits = 0; + ++e; + if (e >= 255) + goto Overflow; + } /* First byte */ *************** *** 262,265 **** --- 266,274 ---- /* Done */ return 0; + + Overflow: + PyErr_SetString(PyExc_OverflowError, + "float too large to pack with f format"); + return -1; } *************** *** 297,306 **** } ! if (e >= 1024) { ! /* XXX 1024 itself is reserved for Inf/NaN */ ! PyErr_SetString(PyExc_OverflowError, ! "float too large to pack with d format"); ! return -1; ! } else if (e < -1022) { /* Gradual underflow */ --- 306,311 ---- } ! if (e >= 1024) ! goto Overflow; else if (e < -1022) { /* Gradual underflow */ *************** *** 316,322 **** --- 321,342 ---- f *= 268435456.0; /* 2**28 */ fhi = (long) floor(f); /* Truncate */ + assert(fhi < 268435456); + f -= (double)fhi; f *= 16777216.0; /* 2**24 */ flo = (long) floor(f + 0.5); /* Round */ + assert(flo <= 16777216); + if (flo >> 24) { + /* The carry propagated out of a string of 24 1 bits. */ + flo = 0; + ++fhi; + if (fhi >> 28) { + /* And it also progagated out of the next 28 bits. */ + fhi = 0; + ++e; + if (e >= 2047) + goto Overflow; + } + } /* First byte */ *************** *** 354,357 **** --- 374,382 ---- /* Done */ return 0; + + Overflow: + PyErr_SetString(PyExc_OverflowError, + "float too large to pack with d format"); + return -1; } From tim_one@users.sourceforge.net Thu Mar 20 18:31:45 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 20 Mar 2003 10:31:45 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.337.2.4.2.67,1.337.2.4.2.68 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv6172/Misc Modified Files: Tag: release22-maint NEWS Log Message: SF bug 705836: struct.pack of floats in non-native endian order pack_float, pack_double, save_float: All the routines for creating IEEE-format packed representations of floats and doubles simply ignored that rounding can (in rare cases) propagate out of a long string of 1 bits. At worst, the end-off carry can (by mistake) interfere with the exponent value, and then unpacking yields a result wrong by a factor of 2. In less severe cases, it can end up losing more low-order bits than intended, or fail to catch overflow *caused* by rounding. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.337.2.4.2.67 retrieving revision 1.337.2.4.2.68 diff -C2 -d -r1.337.2.4.2.67 -r1.337.2.4.2.68 *** NEWS 12 Mar 2003 14:28:21 -0000 1.337.2.4.2.67 --- NEWS 20 Mar 2003 18:30:55 -0000 1.337.2.4.2.68 *************** *** 3,6 **** --- 3,14 ---- ============================ + - SF #705836: The platform-independent routines for packing floats in + IEEE formats (struct.pack's f, d codes; pickle and + cPickle's protocol 1 pickling of floats) ignored that rounding can + cause a carry to propagate. The worst consequence was that, in rare + cases, f could produce strings that, when unpacked again, + were a factor of 2 away from the original float. This has been + fixed. + - Backported SF patch #676342: after using pdb, the readline command completion was botched. *************** *** 32,36 **** 2.2.3 and 2.3. (SF #660455) ! - SF bug #678518: fix some bugs in the parser module. - Bastion.py and rexec.py are disabled. These modules are not safe in --- 40,44 ---- 2.2.3 and 2.3. (SF #660455) ! - SF bug #678518: fix some bugs in the parser module. - Bastion.py and rexec.py are disabled. These modules are not safe in *************** *** 104,108 **** - SF #570655, fix misleading option text for bdist_rpm ! - Distutils: Allow unknown keyword arguments to the setup() function and the Extension constructor, printing a warning about them instead of reporting an error and stopping. --- 112,116 ---- - SF #570655, fix misleading option text for bdist_rpm ! - Distutils: Allow unknown keyword arguments to the setup() function and the Extension constructor, printing a warning about them instead of reporting an error and stopping. *************** *** 420,424 **** - The randint() method is rehabilitated (i.e. no longer deprecated). ! - In copy.py: when an object is copied through its __reduce__ method, there was no check for a __setstate__ method on the result [SF --- 428,432 ---- - The randint() method is rehabilitated (i.e. no longer deprecated). ! - In copy.py: when an object is copied through its __reduce__ method, there was no check for a __setstate__ method on the result [SF From tim_one@users.sourceforge.net Thu Mar 20 18:32:39 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 20 Mar 2003 10:32:39 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_struct.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv9471/Lib/test Modified Files: test_struct.py Log Message: SF bug 705836: struct.pack of floats in non-native endian order pack_float, pack_double, save_float: All the routines for creating IEEE-format packed representations of floats and doubles simply ignored that rounding can (in rare cases) propagate out of a long string of 1 bits. At worst, the end-off carry can (by mistake) interfere with the exponent value, and then unpacking yields a result wrong by a factor of 2. In less severe cases, it can end up losing more low-order bits than intended, or fail to catch overflow *caused* by rounding. Bugfix candidate, but I already backported this to 2.2. In 2.3, this code remains in severe need of refactoring. Index: test_struct.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_struct.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** test_struct.py 27 Feb 2003 20:14:50 -0000 1.16 --- test_struct.py 20 Mar 2003 18:31:59 -0000 1.17 *************** *** 391,392 **** --- 391,438 ---- test_p_code() + + + ########################################################################### + # SF bug 705836. "f" had a severe rounding bug, where a carry + # from the low-order discarded bits could propagate into the exponent + # field, causing the result to be wrong by a factor of 2. + + def test_705836(): + import math + + for base in range(1, 33): + # smaller <- largest representable float less than base. + delta = 0.5 + while base - delta / 2.0 != base: + delta /= 2.0 + smaller = base - delta + # Packing this rounds away a solid string of trailing 1 bits. + packed = struct.pack("f", smaller) + verify(bigpacked == string_reverse(packed), + ">f pack should be byte-reversal of f", bigpacked)[0] + verify(base == unpacked) + + # Largest finite IEEE single. + big = (1 << 24) - 1 + big = math.ldexp(big, 127 - 23) + packed = struct.pack(">f", big) + unpacked = struct.unpack(">f", packed)[0] + verify(big == unpacked) + + # The same, but tack on a 1 bit so it rounds up to infinity. + big = (1 << 25) - 1 + big = math.ldexp(big, 127 - 24) + try: + packed = struct.pack(">f", big) + except OverflowError: + pass + else: + TestFailed("expected OverflowError") + + test_705836() From tim_one@users.sourceforge.net Thu Mar 20 18:32:51 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 20 Mar 2003 10:32:51 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.699,1.700 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv9471/Misc Modified Files: NEWS Log Message: SF bug 705836: struct.pack of floats in non-native endian order pack_float, pack_double, save_float: All the routines for creating IEEE-format packed representations of floats and doubles simply ignored that rounding can (in rare cases) propagate out of a long string of 1 bits. At worst, the end-off carry can (by mistake) interfere with the exponent value, and then unpacking yields a result wrong by a factor of 2. In less severe cases, it can end up losing more low-order bits than intended, or fail to catch overflow *caused* by rounding. Bugfix candidate, but I already backported this to 2.2. In 2.3, this code remains in severe need of refactoring. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.699 retrieving revision 1.700 diff -C2 -d -r1.699 -r1.700 *** NEWS 19 Mar 2003 00:35:35 -0000 1.699 --- NEWS 20 Mar 2003 18:32:03 -0000 1.700 *************** *** 38,41 **** --- 38,49 ---- ----------------- + - The platform-independent routines for packing floats in IEEE formats + (struct.pack's f, d codes; pickle and cPickle's protocol 1 + pickling of floats) ignored that rounding can cause a carry to + propagate. The worst consequence was that, in rare cases, f + could produce strings that, when unpacked again, were a factor of 2 + away from the original float. This has been fixed. See SF bug + #705836. + - New function time.tzset() provides access to the C library tzet() function, if supported. (SF patch #675422.) From tim_one@users.sourceforge.net Thu Mar 20 18:32:18 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 20 Mar 2003 10:32:18 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.140,2.141 structmodule.c,2.57,2.58 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv9471/Modules Modified Files: cPickle.c structmodule.c Log Message: SF bug 705836: struct.pack of floats in non-native endian order pack_float, pack_double, save_float: All the routines for creating IEEE-format packed representations of floats and doubles simply ignored that rounding can (in rare cases) propagate out of a long string of 1 bits. At worst, the end-off carry can (by mistake) interfere with the exponent value, and then unpacking yields a result wrong by a factor of 2. In less severe cases, it can end up losing more low-order bits than intended, or fail to catch overflow *caused* by rounding. Bugfix candidate, but I already backported this to 2.2. In 2.3, this code remains in severe need of refactoring. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.140 retrieving revision 2.141 diff -C2 -d -r2.140 -r2.141 *** cPickle.c 19 Feb 2003 01:45:13 -0000 2.140 --- cPickle.c 20 Mar 2003 18:32:08 -0000 2.141 *************** *** 1157,1166 **** } ! if (e >= 1024) { ! /* XXX 1024 itself is reserved for Inf/NaN */ ! PyErr_SetString(PyExc_OverflowError, ! "float too large to pack with d format"); ! return -1; ! } else if (e < -1022) { /* Gradual underflow */ --- 1157,1162 ---- } ! if (e >= 1024) ! goto Overflow; else if (e < -1022) { /* Gradual underflow */ *************** *** 1177,1183 **** --- 1173,1196 ---- f *= 268435456.0; /* 2**28 */ fhi = (long) floor(f); /* Truncate */ + assert(fhi < 268435456); + f -= (double)fhi; f *= 16777216.0; /* 2**24 */ flo = (long) floor(f + 0.5); /* Round */ + assert(flo <= 16777216); + if (flo >> 24) { + /* The carry propagated out of a string of 24 1 bits. */ + flo = 0; + ++fhi; + if (fhi >> 28) { + /* And it also progagated out of the next + * 28 bits. + */ + fhi = 0; + ++e; + if (e >= 2047) + goto Overflow; + } + } /* First byte */ *************** *** 1225,1228 **** --- 1238,1246 ---- return 0; + + Overflow: + PyErr_SetString(PyExc_OverflowError, + "float too large to pack with d format"); + return -1; } Index: structmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v retrieving revision 2.57 retrieving revision 2.58 diff -C2 -d -r2.57 -r2.58 *** structmodule.c 3 Sep 2002 18:42:21 -0000 2.57 --- structmodule.c 20 Mar 2003 18:32:13 -0000 2.58 *************** *** 225,234 **** } ! if (e >= 128) { ! /* XXX 128 itself is reserved for Inf/NaN */ ! PyErr_SetString(PyExc_OverflowError, ! "float too large to pack with f format"); ! return -1; ! } else if (e < -126) { /* Gradual underflow */ --- 225,230 ---- } ! if (e >= 128) ! goto Overflow; else if (e < -126) { /* Gradual underflow */ *************** *** 243,246 **** --- 239,250 ---- f *= 8388608.0; /* 2**23 */ fbits = (long) floor(f + 0.5); /* Round */ + assert(fbits <= 8388608); + if (fbits >> 23) { + /* The carry propagated out of a string of 23 1 bits. */ + fbits = 0; + ++e; + if (e >= 255) + goto Overflow; + } /* First byte */ *************** *** 261,264 **** --- 265,273 ---- /* Done */ return 0; + + Overflow: + PyErr_SetString(PyExc_OverflowError, + "float too large to pack with f format"); + return -1; } *************** *** 296,305 **** } ! if (e >= 1024) { ! /* XXX 1024 itself is reserved for Inf/NaN */ ! PyErr_SetString(PyExc_OverflowError, ! "float too large to pack with d format"); ! return -1; ! } else if (e < -1022) { /* Gradual underflow */ --- 305,310 ---- } ! if (e >= 1024) ! goto Overflow; else if (e < -1022) { /* Gradual underflow */ *************** *** 315,321 **** --- 320,341 ---- f *= 268435456.0; /* 2**28 */ fhi = (long) floor(f); /* Truncate */ + assert(fhi < 268435456); + f -= (double)fhi; f *= 16777216.0; /* 2**24 */ flo = (long) floor(f + 0.5); /* Round */ + assert(flo <= 16777216); + if (flo >> 24) { + /* The carry propagated out of a string of 24 1 bits. */ + flo = 0; + ++fhi; + if (fhi >> 28) { + /* And it also progagated out of the next 28 bits. */ + fhi = 0; + ++e; + if (e >= 2047) + goto Overflow; + } + } /* First byte */ *************** *** 353,356 **** --- 373,381 ---- /* Done */ return 0; + + Overflow: + PyErr_SetString(PyExc_OverflowError, + "float too large to pack with d format"); + return -1; } From tim_one@users.sourceforge.net Thu Mar 20 20:54:03 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 20 Mar 2003 12:54:03 -0800 Subject: [Python-checkins] python/dist/src/Include floatobject.h,2.21,2.22 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory sc8-pr-cvs1:/tmp/cvs-serv6732/python/Include Modified Files: floatobject.h Log Message: New private API functions _PyFloat_{Pack,Unpack}(4,8}. This is a refactoring to get all the duplicates of this delicate code out of the cPickle and struct modules. Index: floatobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/floatobject.h,v retrieving revision 2.21 retrieving revision 2.22 diff -C2 -d -r2.21 -r2.22 *** floatobject.h 12 Aug 2002 07:21:56 -0000 2.21 --- floatobject.h 20 Mar 2003 20:53:29 -0000 2.22 *************** *** 48,51 **** --- 48,93 ---- PyAPI_FUNC(void) PyFloat_AsString(char*, PyFloatObject *v); + /* _PyFloat_{Pack,Unpack}{4,8} + * + * The struct and pickle (at least) modules need an efficient platform- + * independent way to store floating-point values as byte strings. + * The Pack routines produce a string from a C double, and the Unpack + * routines produce a C double from such a string. The suffix (4 or 8) + * specifies the number of bytes in the string. + * + * Excepting NaNs and infinities (which aren't handled correctly), the 4- + * byte format is identical to the IEEE-754 single precision format, and + * the 8-byte format to the IEEE-754 double precision format. On non- + * IEEE platforms with more precision, or larger dynamic range, than + * 754 supports, not all values can be packed; on non-IEEE platforms with + * less precision, or smaller dynamic range, not all values can be + * unpacked. What happens in such cases is partly accidental (alas). + */ + + /* The pack routines write 4 or 8 bytes, starting at p. le is a bool + * argument, true if you want the string in little-endian format (exponent + * last, at p+3 or p+7), false if you want big-endian format (exponent + * first, at p). + * Return value: 0 if all is OK, -1 if error (and an exception is + * set, most likely OverflowError). + * Bug: What this does is undefined if x is a NaN or infinity. + * Bug: -0.0 and +0.0 produce the same string. + */ + PyAPI_FUNC(int) _PyFloat_Pack4(double x, unsigned char *p, int le); + PyAPI_FUNC(int) _PyFloat_Pack8(double x, unsigned char *p, int le); + + /* The unpack routines read 4 or 8 bytes, starting at p. le is a bool + * argument, true if the string is in little-endian format (exponent + * last, at p+3 or p+7), false if big-endian (exponent first, at p). + * Return value: The unpacked double. On error, this is -1.0 and + * PyErr_Occurred() is true (and an exception is set, most likely + * OverflowError). + * Bug: What this does is undefined if the string represents a NaN or + * infinity. + */ + PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le); + PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le); + + #ifdef __cplusplus } From tim_one@users.sourceforge.net Thu Mar 20 20:53:34 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 20 Mar 2003 12:53:34 -0800 Subject: [Python-checkins] python/dist/src/Modules cPickle.c,2.141,2.142 structmodule.c,2.58,2.59 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv6732/python/Modules Modified Files: cPickle.c structmodule.c Log Message: New private API functions _PyFloat_{Pack,Unpack}(4,8}. This is a refactoring to get all the duplicates of this delicate code out of the cPickle and struct modules. Index: cPickle.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v retrieving revision 2.141 retrieving revision 2.142 diff -C2 -d -r2.141 -r2.142 *** cPickle.c 20 Mar 2003 18:32:08 -0000 2.141 --- cPickle.c 20 Mar 2003 20:53:30 -0000 2.142 *************** *** 1125,1228 **** if (self->bin) { - int s, e; - double f; - long fhi, flo; char str[9]; ! unsigned char *p = (unsigned char *)str; ! ! *p = BINFLOAT; ! p++; ! ! if (x < 0) { ! s = 1; ! x = -x; ! } ! else ! s = 0; ! ! f = frexp(x, &e); ! ! /* Normalize f to be in the range [1.0, 2.0) */ ! if (0.5 <= f && f < 1.0) { ! f *= 2.0; ! e--; ! } ! else if (f == 0.0) { ! e = 0; ! } ! else { ! PyErr_SetString(PyExc_SystemError, ! "frexp() result out of range"); return -1; - } - - if (e >= 1024) - goto Overflow; - else if (e < -1022) { - /* Gradual underflow */ - f = ldexp(f, 1022 + e); - e = 0; - } - else if (!(e == 0 && f == 0.0)) { - e += 1023; - f -= 1.0; /* Get rid of leading 1 */ - } - - /* fhi receives the high 28 bits; - flo the low 24 bits (== 52 bits) */ - f *= 268435456.0; /* 2**28 */ - fhi = (long) floor(f); /* Truncate */ - assert(fhi < 268435456); - - f -= (double)fhi; - f *= 16777216.0; /* 2**24 */ - flo = (long) floor(f + 0.5); /* Round */ - assert(flo <= 16777216); - if (flo >> 24) { - /* The carry propagated out of a string of 24 1 bits. */ - flo = 0; - ++fhi; - if (fhi >> 28) { - /* And it also progagated out of the next - * 28 bits. - */ - fhi = 0; - ++e; - if (e >= 2047) - goto Overflow; - } - } - - /* First byte */ - *p = (s<<7) | (e>>4); - p++; - - /* Second byte */ - *p = (unsigned char) (((e&0xF)<<4) | (fhi>>24)); - p++; - - /* Third byte */ - *p = (unsigned char) ((fhi>>16) & 0xFF); - p++; - - /* Fourth byte */ - *p = (unsigned char) ((fhi>>8) & 0xFF); - p++; - - /* Fifth byte */ - *p = (unsigned char) (fhi & 0xFF); - p++; - - /* Sixth byte */ - *p = (unsigned char) ((flo>>16) & 0xFF); - p++; - - /* Seventh byte */ - *p = (unsigned char) ((flo>>8) & 0xFF); - p++; - - /* Eighth byte */ - *p = (unsigned char) (flo & 0xFF); - if (self->write_func(self, str, 9) < 0) return -1; --- 1125,1132 ---- if (self->bin) { char str[9]; ! str[0] = BINFLOAT; ! if (_PyFloat_Pack8(x, (unsigned char *)&str[1], 0) < 0) return -1; if (self->write_func(self, str, 9) < 0) return -1; *************** *** 1238,1246 **** return 0; - - Overflow: - PyErr_SetString(PyExc_OverflowError, - "float too large to pack with d format"); - return -1; } --- 1142,1145 ---- *************** *** 3373,3379 **** load_binfloat(Unpicklerobject *self) { ! PyObject *py_float = 0; ! int s, e; ! long fhi, flo; double x; char *p; --- 3272,3276 ---- load_binfloat(Unpicklerobject *self) { ! PyObject *py_float; double x; char *p; *************** *** 3382,3434 **** return -1; ! /* First byte */ ! s = (*p>>7) & 1; ! e = (*p & 0x7F) << 4; ! p++; ! ! /* Second byte */ ! e |= (*p>>4) & 0xF; ! fhi = (*p & 0xF) << 24; ! p++; ! ! /* Third byte */ ! fhi |= (*p & 0xFF) << 16; ! p++; ! ! /* Fourth byte */ ! fhi |= (*p & 0xFF) << 8; ! p++; ! ! /* Fifth byte */ ! fhi |= *p & 0xFF; ! p++; ! ! /* Sixth byte */ ! flo = (*p & 0xFF) << 16; ! p++; ! ! /* Seventh byte */ ! flo |= (*p & 0xFF) << 8; ! p++; ! ! /* Eighth byte */ ! flo |= *p & 0xFF; ! ! x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */ ! x /= 268435456.0; /* 2**28 */ ! ! /* XXX This sadly ignores Inf/NaN */ ! if (e == 0) ! e = -1022; ! else { ! x += 1.0; ! e -= 1023; ! } ! x = ldexp(x, e); ! ! if (s) ! x = -x; ! if (!( py_float = PyFloat_FromDouble(x))) return -1; PDATA_PUSH(self->stack, py_float, -1); --- 3279,3289 ---- return -1; ! x = _PyFloat_Unpack8((unsigned char *)p, 0); ! if (x == -1.0 && PyErr_Occurred()) ! return -1; ! py_float = PyFloat_FromDouble(x); ! if (py_float == NULL) ! return -1; PDATA_PUSH(self->stack, py_float, -1); Index: structmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v retrieving revision 2.58 retrieving revision 2.59 diff -C2 -d -r2.58 -r2.59 *** structmodule.c 20 Mar 2003 18:32:13 -0000 2.58 --- structmodule.c 20 Mar 2003 20:53:31 -0000 2.59 *************** *** 186,484 **** /* Floating point helpers */ - /* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating - Point Arithmetic). See the following URL: - http://www.psc.edu/general/software/packages/ieee/ieee.html */ - - /* XXX Inf/NaN are not handled quite right (but underflow is!) */ - - static int - pack_float(double x, /* The number to pack */ - char *p, /* Where to pack the high order byte */ - int incr) /* 1 for big-endian; -1 for little-endian */ - { - int s; - int e; - double f; - long fbits; - - if (x < 0) { - s = 1; - x = -x; - } - else - s = 0; - - f = frexp(x, &e); - - /* Normalize f to be in the range [1.0, 2.0) */ - if (0.5 <= f && f < 1.0) { - f *= 2.0; - e--; - } - else if (f == 0.0) { - e = 0; - } - else { - PyErr_SetString(PyExc_SystemError, - "frexp() result out of range"); - return -1; - } - - if (e >= 128) - goto Overflow; - else if (e < -126) { - /* Gradual underflow */ - f = ldexp(f, 126 + e); - e = 0; - } - else if (!(e == 0 && f == 0.0)) { - e += 127; - f -= 1.0; /* Get rid of leading 1 */ - } - - f *= 8388608.0; /* 2**23 */ - fbits = (long) floor(f + 0.5); /* Round */ - assert(fbits <= 8388608); - if (fbits >> 23) { - /* The carry propagated out of a string of 23 1 bits. */ - fbits = 0; - ++e; - if (e >= 255) - goto Overflow; - } - - /* First byte */ - *p = (s<<7) | (e>>1); - p += incr; - - /* Second byte */ - *p = (char) (((e&1)<<7) | (fbits>>16)); - p += incr; - - /* Third byte */ - *p = (fbits>>8) & 0xFF; - p += incr; - - /* Fourth byte */ - *p = fbits&0xFF; - - /* Done */ - return 0; - - Overflow: - PyErr_SetString(PyExc_OverflowError, - "float too large to pack with f format"); - return -1; - } - - static int - pack_double(double x, /* The number to pack */ - char *p, /* Where to pack the high order byte */ - int incr) /* 1 for big-endian; -1 for little-endian */ - { - int s; - int e; - double f; - long fhi, flo; - - if (x < 0) { - s = 1; - x = -x; - } - else - s = 0; - - f = frexp(x, &e); - - /* Normalize f to be in the range [1.0, 2.0) */ - if (0.5 <= f && f < 1.0) { - f *= 2.0; - e--; - } - else if (f == 0.0) { - e = 0; - } - else { - PyErr_SetString(PyExc_SystemError, - "frexp() result out of range"); - return -1; - } - - if (e >= 1024) - goto Overflow; - else if (e < -1022) { - /* Gradual underflow */ - f = ldexp(f, 1022 + e); - e = 0; - } - else if (!(e == 0 && f == 0.0)) { - e += 1023; - f -= 1.0; /* Get rid of leading 1 */ - } - - /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */ - f *= 268435456.0; /* 2**28 */ - fhi = (long) floor(f); /* Truncate */ - assert(fhi < 268435456); - - f -= (double)fhi; - f *= 16777216.0; /* 2**24 */ - flo = (long) floor(f + 0.5); /* Round */ - assert(flo <= 16777216); - if (flo >> 24) { - /* The carry propagated out of a string of 24 1 bits. */ - flo = 0; - ++fhi; - if (fhi >> 28) { - /* And it also progagated out of the next 28 bits. */ - fhi = 0; - ++e; - if (e >= 2047) - goto Overflow; - } - } - - /* First byte */ - *p = (s<<7) | (e>>4); - p += incr; - - /* Second byte */ - *p = (char) (((e&0xF)<<4) | (fhi>>24)); - p += incr; - - /* Third byte */ - *p = (fhi>>16) & 0xFF; - p += incr; - - /* Fourth byte */ - *p = (fhi>>8) & 0xFF; - p += incr; - - /* Fifth byte */ - *p = fhi & 0xFF; - p += incr; - - /* Sixth byte */ - *p = (flo>>16) & 0xFF; - p += incr; - - /* Seventh byte */ - *p = (flo>>8) & 0xFF; - p += incr; - - /* Eighth byte */ - *p = flo & 0xFF; - p += incr; - - /* Done */ - return 0; - - Overflow: - PyErr_SetString(PyExc_OverflowError, - "float too large to pack with d format"); - return -1; - } - static PyObject * ! unpack_float(const char *p, /* Where the high order byte is */ ! int incr) /* 1 for big-endian; -1 for little-endian */ { - int s; - int e; - long f; double x; ! /* First byte */ ! s = (*p>>7) & 1; ! e = (*p & 0x7F) << 1; ! p += incr; ! ! /* Second byte */ ! e |= (*p>>7) & 1; ! f = (*p & 0x7F) << 16; ! p += incr; ! ! /* Third byte */ ! f |= (*p & 0xFF) << 8; ! p += incr; ! ! /* Fourth byte */ ! f |= *p & 0xFF; ! ! x = (double)f / 8388608.0; ! ! /* XXX This sadly ignores Inf/NaN issues */ ! if (e == 0) ! e = -126; ! else { ! x += 1.0; ! e -= 127; ! } ! x = ldexp(x, e); ! ! if (s) ! x = -x; ! return PyFloat_FromDouble(x); } static PyObject * ! unpack_double(const char *p, /* Where the high order byte is */ ! int incr) /* 1 for big-endian; -1 for little-endian */ { - int s; - int e; - long fhi, flo; double x; ! /* First byte */ ! s = (*p>>7) & 1; ! e = (*p & 0x7F) << 4; ! p += incr; ! ! /* Second byte */ ! e |= (*p>>4) & 0xF; ! fhi = (*p & 0xF) << 24; ! p += incr; ! ! /* Third byte */ ! fhi |= (*p & 0xFF) << 16; ! p += incr; ! ! /* Fourth byte */ ! fhi |= (*p & 0xFF) << 8; ! p += incr; ! ! /* Fifth byte */ ! fhi |= *p & 0xFF; ! p += incr; ! ! /* Sixth byte */ ! flo = (*p & 0xFF) << 16; ! p += incr; ! ! /* Seventh byte */ ! flo |= (*p & 0xFF) << 8; ! p += incr; ! ! /* Eighth byte */ ! flo |= *p & 0xFF; ! p += incr; ! ! x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */ ! x /= 268435456.0; /* 2**28 */ ! ! /* XXX This sadly ignores Inf/NaN */ ! if (e == 0) ! e = -1022; ! else { ! x += 1.0; ! e -= 1023; ! } ! x = ldexp(x, e); ! ! if (s) ! x = -x; ! return PyFloat_FromDouble(x); } --- 186,210 ---- /* Floating point helpers */ static PyObject * ! unpack_float(const char *p, /* start of 4-byte string */ ! int le) /* true for little-endian, false for big-endian */ { double x; ! x = _PyFloat_Unpack4((unsigned char *)p, le); ! if (x == -1.0 && PyErr_Occurred()) ! return NULL; return PyFloat_FromDouble(x); } static PyObject * ! unpack_double(const char *p, /* start of 8-byte string */ ! int le) /* true for little-endian, false for big-endian */ { double x; ! x = _PyFloat_Unpack8((unsigned char *)p, le); ! if (x == -1.0 && PyErr_Occurred()) ! return NULL; return PyFloat_FromDouble(x); } *************** *** 888,892 **** bu_float(const char *p, const formatdef *f) { ! return unpack_float(p, 1); } --- 614,618 ---- bu_float(const char *p, const formatdef *f) { ! return unpack_float(p, 0); } *************** *** 894,898 **** bu_double(const char *p, const formatdef *f) { ! return unpack_double(p, 1); } --- 620,624 ---- bu_double(const char *p, const formatdef *f) { ! return unpack_double(p, 0); } *************** *** 968,972 **** return -1; } ! return pack_float(x, p, 1); } --- 694,698 ---- return -1; } ! return _PyFloat_Pack4(x, (unsigned char *)p, 0); } *************** *** 980,984 **** return -1; } ! return pack_double(x, p, 1); } --- 706,710 ---- return -1; } ! return _PyFloat_Pack8(x, (unsigned char *)p, 0); } *************** *** 1054,1058 **** lu_float(const char *p, const formatdef *f) { ! return unpack_float(p+3, -1); } --- 780,784 ---- lu_float(const char *p, const formatdef *f) { ! return unpack_float(p, 1); } *************** *** 1060,1064 **** lu_double(const char *p, const formatdef *f) { ! return unpack_double(p+7, -1); } --- 786,790 ---- lu_double(const char *p, const formatdef *f) { ! return unpack_double(p, 1); } *************** *** 1134,1138 **** return -1; } ! return pack_float(x, p+3, -1); } --- 860,864 ---- return -1; } ! return _PyFloat_Pack4(x, (unsigned char *)p, 1); } *************** *** 1146,1150 **** return -1; } ! return pack_double(x, p+7, -1); } --- 872,876 ---- return -1; } ! return _PyFloat_Pack8(x, (unsigned char *)p, 1); } From tim_one@users.sourceforge.net Thu Mar 20 20:53:35 2003 From: tim_one@users.sourceforge.net (tim_one@users.sourceforge.net) Date: Thu, 20 Mar 2003 12:53:35 -0800 Subject: [Python-checkins] python/dist/src/Objects floatobject.c,2.120,2.121 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory sc8-pr-cvs1:/tmp/cvs-serv6732/python/Objects Modified Files: floatobject.c Log Message: New private API functions _PyFloat_{Pack,Unpack}(4,8}. This is a refactoring to get all the duplicates of this delicate code out of the cPickle and struct modules. Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.120 retrieving revision 2.121 diff -C2 -d -r2.120 -r2.121 *** floatobject.c 29 Jan 2003 17:58:45 -0000 2.120 --- floatobject.c 20 Mar 2003 20:53:32 -0000 2.121 *************** *** 905,906 **** --- 905,1219 ---- } } + + /*---------------------------------------------------------------------------- + * _PyFloat_{Pack,Unpack}{4,8}. See floatobject.h. + * + * TODO: On platforms that use the standard IEEE-754 single and double + * formats natively, these routines could simply copy the bytes. + */ + int + _PyFloat_Pack4(double x, unsigned char *p, int le) + { + unsigned char sign; + int e; + double f; + unsigned int fbits; + int incr = 1; + + if (le) { + p += 3; + incr = -1; + } + + if (x < 0) { + sign = 1; + x = -x; + } + else + sign = 0; + + f = frexp(x, &e); + + /* Normalize f to be in the range [1.0, 2.0) */ + if (0.5 <= f && f < 1.0) { + f *= 2.0; + e--; + } + else if (f == 0.0) + e = 0; + else { + PyErr_SetString(PyExc_SystemError, + "frexp() result out of range"); + return -1; + } + + if (e >= 128) + goto Overflow; + else if (e < -126) { + /* Gradual underflow */ + f = ldexp(f, 126 + e); + e = 0; + } + else if (!(e == 0 && f == 0.0)) { + e += 127; + f -= 1.0; /* Get rid of leading 1 */ + } + + f *= 8388608.0; /* 2**23 */ + fbits = (long) floor(f + 0.5); /* Round */ + assert(fbits <= 8388608); + if (fbits >> 23) { + /* The carry propagated out of a string of 23 1 bits. */ + fbits = 0; + ++e; + if (e >= 255) + goto Overflow; + } + + /* First byte */ + *p = (sign << 7) | (e >> 1); + p += incr; + + /* Second byte */ + *p = (char) (((e & 1) << 7) | (fbits >> 16)); + p += incr; + + /* Third byte */ + *p = (fbits >> 8) & 0xFF; + p += incr; + + /* Fourth byte */ + *p = fbits & 0xFF; + + /* Done */ + return 0; + + Overflow: + PyErr_SetString(PyExc_OverflowError, + "float too large to pack with f format"); + return -1; + } + + int + _PyFloat_Pack8(double x, unsigned char *p, int le) + { + unsigned char sign; + int e; + double f; + unsigned int fhi, flo; + int incr = 1; + + if (le) { + p += 7; + incr = -1; + } + + if (x < 0) { + sign = 1; + x = -x; + } + else + sign = 0; + + f = frexp(x, &e); + + /* Normalize f to be in the range [1.0, 2.0) */ + if (0.5 <= f && f < 1.0) { + f *= 2.0; + e--; + } + else if (f == 0.0) + e = 0; + else { + PyErr_SetString(PyExc_SystemError, + "frexp() result out of range"); + return -1; + } + + if (e >= 1024) + goto Overflow; + else if (e < -1022) { + /* Gradual underflow */ + f = ldexp(f, 1022 + e); + e = 0; + } + else if (!(e == 0 && f == 0.0)) { + e += 1023; + f -= 1.0; /* Get rid of leading 1 */ + } + + /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */ + f *= 268435456.0; /* 2**28 */ + fhi = (unsigned int)f; /* Truncate */ + assert(fhi < 268435456); + + f -= (double)fhi; + f *= 16777216.0; /* 2**24 */ + flo = (unsigned int)(f + 0.5); /* Round */ + assert(flo <= 16777216); + if (flo >> 24) { + /* The carry propagated out of a string of 24 1 bits. */ + flo = 0; + ++fhi; + if (fhi >> 28) { + /* And it also progagated out of the next 28 bits. */ + fhi = 0; + ++e; + if (e >= 2047) + goto Overflow; + } + } + + /* First byte */ + *p = (sign << 7) | (e >> 4); + p += incr; + + /* Second byte */ + *p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24)); + p += incr; + + /* Third byte */ + *p = (fhi >> 16) & 0xFF; + p += incr; + + /* Fourth byte */ + *p = (fhi >> 8) & 0xFF; + p += incr; + + /* Fifth byte */ + *p = fhi & 0xFF; + p += incr; + + /* Sixth byte */ + *p = (flo >> 16) & 0xFF; + p += incr; + + /* Seventh byte */ + *p = (flo >> 8) & 0xFF; + p += incr; + + /* Eighth byte */ + *p = flo & 0xFF; + p += incr; + + /* Done */ + return 0; + + Overflow: + PyErr_SetString(PyExc_OverflowError, + "float too large to pack with d format"); + return -1; + } + + double + _PyFloat_Unpack4(const unsigned char *p, int le) + { + unsigned char sign; + int e; + unsigned int f; + double x; + int incr = 1; + + if (le) { + p += 3; + incr = -1; + } + + /* First byte */ + sign = (*p >> 7) & 1; + e = (*p & 0x7F) << 1; + p += incr; + + /* Second byte */ + e |= (*p >> 7) & 1; + f = (*p & 0x7F) << 16; + p += incr; + + /* Third byte */ + f |= *p << 8; + p += incr; + + /* Fourth byte */ + f |= *p; + + x = (double)f / 8388608.0; + + /* XXX This sadly ignores Inf/NaN issues */ + if (e == 0) + e = -126; + else { + x += 1.0; + e -= 127; + } + x = ldexp(x, e); + + if (sign) + x = -x; + + return x; + } + + double + _PyFloat_Unpack8(const unsigned char *p, int le) + { + unsigned char sign; + int e; + unsigned int fhi, flo; + double x; + int incr = 1; + + if (le) { + p += 7; + incr = -1; + } + + /* First byte */ + sign = (*p >> 7) & 1; + e = (*p & 0x7F) << 4; + p += incr; + + /* Second byte */ + e |= (*p >> 4) & 0xF; + fhi = (*p & 0xF) << 24; + p += incr; + + /* Third byte */ + fhi |= *p << 16; + p += incr; + + /* Fourth byte */ + fhi |= *p << 8; + p += incr; + + /* Fifth byte */ + fhi |= *p; + p += incr; + + /* Sixth byte */ + flo = *p << 16; + p += incr; + + /* Seventh byte */ + flo |= *p << 8; + p += incr; + + /* Eighth byte */ + flo |= *p; + + x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */ + x /= 268435456.0; /* 2**28 */ + + /* XXX This sadly ignores Inf/NaN */ + if (e == 0) + e = -1022; + else { + x += 1.0; + e -= 1023; + } + x = ldexp(x, e); + + if (sign) + x = -x; + + return x; + } From jvr@users.sourceforge.net Thu Mar 20 21:37:50 2003 From: jvr@users.sourceforge.net (jvr@users.sourceforge.net) Date: Thu, 20 Mar 2003 13:37:50 -0800 Subject: [Python-checkins] python/dist/src/Lib/plat-mac bundlebuilder.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/plat-mac In directory sc8-pr-cvs1:/tmp/cvs-serv2916 Modified Files: bundlebuilder.py Log Message: set $PYTHONHOME in the bootstrap script, for no good reason really, except to avoid getpath.c giving unsollicited advice on stderr. Index: bundlebuilder.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/plat-mac/bundlebuilder.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** bundlebuilder.py 5 Mar 2003 14:44:54 -0000 1.20 --- bundlebuilder.py 20 Mar 2003 21:37:05 -0000 1.21 *************** *** 273,276 **** --- 273,277 ---- sys.argv.insert(1, mainprogram) os.environ["PYTHONPATH"] = resdir + os.environ["PYTHONHOME"] = resdir os.environ["PYTHONEXECUTABLE"] = executable os.execve(executable, sys.argv, os.environ) From fdrake@users.sourceforge.net Thu Mar 20 22:18:02 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Thu, 20 Mar 2003 14:18:02 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libstdtypes.tex,1.120,1.121 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv23654 Modified Files: libstdtypes.tex Log Message: - added example of using a comparison function with list.sort(), and explained the construction of a [(key, value), ...] list as an alternative - note that support for cmpfunc=None was added in 2.3 Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.120 retrieving revision 1.121 diff -C2 -d -r1.120 -r1.121 *** libstdtypes.tex 6 Mar 2003 23:54:27 -0000 1.120 --- libstdtypes.tex 20 Mar 2003 22:17:59 -0000 1.121 *************** *** 1000,1009 **** the first argument is considered smaller than, equal to, or larger than the second argument. Note that this slows the sorting process ! down considerably; e.g. to sort a list in reverse order it is much ! faster to call method \method{sort()} followed by \method{reverse()} ! than to use method \method{sort()} with a comparison function that reverses the ordering of the elements. Passing \constant{None} as the comparison function is semantically equivalent to calling \method{sort()} with no comparison function. \item[(9)] Whether the \method{sort()} method is stable is not defined by --- 1000,1031 ---- the first argument is considered smaller than, equal to, or larger than the second argument. Note that this slows the sorting process ! down considerably; for example to sort a list in reverse order it is much ! faster to call \method{sort()} followed by \method{reverse()} ! than to use \method{sort()} with a comparison function that reverses the ordering of the elements. Passing \constant{None} as the comparison function is semantically equivalent to calling \method{sort()} with no comparison function. + \versionchanged[Support for \code{None} as an equivalent to omitting + \var{cmpfunc} was added]{2.3} + + As an example of using the \var{cmpfunc} argument to the + \method{sort()} method, consider sorting a list of sequences by the + second element of that list: + + \begin{verbatim} + def mycmp(a, b): + return cmp(a[1], b[1]) + + mylist.sort(mycmp) + \end{verbatim} + + A more time-efficient approach for reasonably-sized data structures can + often be used: + + \begin{verbatim} + tmplist = [(x[1], x) for x in mylist] + tmplist.sort() + mylist = [x for (key, x) in tmplist] + \end{verbatim} \item[(9)] Whether the \method{sort()} method is stable is not defined by From fdrake@users.sourceforge.net Thu Mar 20 22:20:53 2003 From: fdrake@users.sourceforge.net (fdrake@users.sourceforge.net) Date: Thu, 20 Mar 2003 14:20:53 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libstdtypes.tex,1.80.6.20,1.80.6.21 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv24949a Modified Files: Tag: release22-maint libstdtypes.tex Log Message: - added example of using a comparison function with list.sort(), and explained the construction of a [(key, value), ...] list as an alternative - backport additional notes on list use from Python 2.3 documentation; mostly warnings about what not to rely on Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.80.6.20 retrieving revision 1.80.6.21 diff -C2 -d -r1.80.6.20 -r1.80.6.21 *** libstdtypes.tex 4 Mar 2003 00:50:20 -0000 1.80.6.20 --- libstdtypes.tex 20 Mar 2003 22:20:43 -0000 1.80.6.21 *************** *** 922,926 **** {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} --- 922,926 ---- {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), (8), (9)} \end{tableiii} \indexiv{operations on}{mutable}{sequence}{types} *************** *** 965,973 **** the first argument is considered smaller than, equal to, or larger than the second argument. Note that this slows the sorting process ! down considerably; e.g. to sort a list in reverse order it is much ! faster to use calls to the methods \method{sort()} and ! \method{reverse()} than to use the built-in function ! \function{sort()} with a comparison function that reverses the ! ordering of the elements. \end{description} --- 965,1002 ---- the first argument is considered smaller than, equal to, or larger than the second argument. Note that this slows the sorting process ! down considerably; for example, to sort a list in reverse order it is much ! faster to call \method{sort()} followed by \method{reverse()} ! than to use \method{sort()} with a comparison function that ! reverses the ordering of the elements. ! ! As an example of using the \var{cmpfunc} argument to the ! \method{sort()} method, consider sorting a list of sequences by the ! second element of that list: ! ! \begin{verbatim} ! def mycmp(a, b): ! return cmp(a[1], b[1]) ! ! mylist.sort(mycmp) ! \end{verbatim} ! ! A more time-efficient approach for reasonably-sized data structures can ! often be used: ! ! \begin{verbatim} ! tmplist = [(x[1], x) for x in mylist] ! tmplist.sort() ! mylist = [x for (key, x) in tmplist] ! \end{verbatim} ! ! \item[(8)] Whether the \method{sort()} method is stable is not defined by ! the language (a sort is stable if it guarantees not to change the ! relative order of elements that compare equal). In the C ! implementation of Python, sorts were stable only by accident through ! Python 2.2. Code that intends to be portable across ! implementations and versions must not rely on stability. ! ! \item[(9)] While a list is being sorted, the effect of attempting to ! mutate, or even inspect, the list is undefined. \end{description} From montanaro@users.sourceforge.net Thu Mar 20 22:51:45 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 20 Mar 2003 14:51:45 -0800 Subject: [Python-checkins] python/dist/src/Lib/csv - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Lib/csv In directory sc8-pr-cvs1:/tmp/cvs-serv7869/Lib/csv Log Message: Directory /cvsroot/python/python/dist/src/Lib/csv added to the repository From montanaro@users.sourceforge.net Thu Mar 20 23:29:14 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 20 Mar 2003 15:29:14 -0800 Subject: [Python-checkins] python/dist/src/Modules _csv.c,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory sc8-pr-cvs1:/tmp/cvs-serv24199/Modules Added Files: _csv.c Log Message: new CSV file processing module - see PEP 305 --- NEW FILE: _csv.c --- /* TODO: */ #include "Python.h" #include "structmember.h" /* begin 2.2 compatibility macros */ #ifndef PyDoc_STRVAR /* Define macros for inline documentation. */ #define PyDoc_VAR(name) static char name[] #define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str) #ifdef WITH_DOC_STRINGS #define PyDoc_STR(str) str #else #define PyDoc_STR(str) "" #endif #endif /* ifndef PyDoc_STRVAR */ #ifndef PyMODINIT_FUNC [...1426 lines suppressed...] /* Add quote styles into dictionary */ for (style = quote_styles; style->name; style++) { v = PyInt_FromLong(style->style); if (v == NULL) return; res = PyModule_AddObject(module, style->name, v); if (res < 0) return; } /* Add the Dialect type */ if (PyModule_AddObject(module, "Dialect", (PyObject *)&Dialect_Type)) return; /* Add the CSV exception object to the module. */ error_obj = PyErr_NewException("_csv.Error", NULL, NULL); if (error_obj == NULL) return; PyModule_AddObject(module, "Error", error_obj); } From montanaro@users.sourceforge.net Thu Mar 20 23:29:14 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 20 Mar 2003 15:29:14 -0800 Subject: [Python-checkins] python/dist/src/Lib/csv __init__.py,NONE,1.1 csv.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/csv In directory sc8-pr-cvs1:/tmp/cvs-serv24199/Lib/csv Added Files: __init__.py csv.py Log Message: new CSV file processing module - see PEP 305 --- NEW FILE: __init__.py --- --- NEW FILE: csv.py --- from _csv import Error, __version__, writer, reader, register_dialect, \ unregister_dialect, get_dialect, list_dialects, \ QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE, \ __doc__ __all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", "Error", "Dialect", "excel", "excel_tab", "reader", "writer", "register_dialect", "get_dialect", "list_dialects", "unregister_dialect", "__version__", "DictReader", "DictWriter" ] class Dialect: _name = "" _valid = False # placeholders delimiter = None quotechar = None escapechar = None doublequote = None skipinitialspace = None lineterminator = None quoting = None def __init__(self): if self.__class__ != Dialect: self._valid = True errors = self._validate() if errors != []: raise Error, "Dialect did not validate: %s" % ", ".join(errors) def _validate(self): errors = [] if not self._valid: errors.append("can't directly instantiate Dialect class") if self.delimiter is None: errors.append("delimiter character not set") elif (not isinstance(self.delimiter, str) or len(self.delimiter) > 1): errors.append("delimiter must be one-character string") if self.quotechar is None: if self.quoting != QUOTE_NONE: errors.append("quotechar not set") elif (not isinstance(self.quotechar, str) or len(self.quotechar) > 1): errors.append("quotechar must be one-character string") if self.lineterminator is None: errors.append("lineterminator not set") elif not isinstance(self.lineterminator, str): errors.append("lineterminator must be a string") if self.doublequote not in (True, False): errors.append("doublequote parameter must be True or False") if self.skipinitialspace not in (True, False): errors.append("skipinitialspace parameter must be True or False") if self.quoting is None: errors.append("quoting parameter not set") if self.quoting is QUOTE_NONE: if (not isinstance(self.escapechar, (unicode, str)) or len(self.escapechar) > 1): errors.append("escapechar must be a one-character string or unicode object") return errors class excel(Dialect): delimiter = ',' quotechar = '"' doublequote = True skipinitialspace = False lineterminator = '\r\n' quoting = QUOTE_MINIMAL register_dialect("excel", excel) class excel_tab(excel): delimiter = '\t' register_dialect("excel-tab", excel_tab) class DictReader: def __init__(self, f, fieldnames, restkey=None, restval=None, dialect="excel", *args): self.fieldnames = fieldnames # list of keys for the dict self.restkey = restkey # key to catch long rows self.restval = restval # default value for short rows self.reader = reader(f, dialect, *args) def __iter__(self): return self def next(self): row = self.reader.next() # unlike the basic reader, we prefer not to return blanks, # because we will typically wind up with a dict full of None # values while row == []: row = self.reader.next() d = dict(zip(self.fieldnames, row)) lf = len(self.fieldnames) lr = len(row) if lf < lr: d[self.restkey] = row[lf:] elif lf > lr: for key in self.fieldnames[lr:]: d[key] = self.restval return d class DictWriter: def __init__(self, f, fieldnames, restval="", extrasaction="raise", dialect="excel", *args): self.fieldnames = fieldnames # list of keys for the dict self.restval = restval # for writing short dicts if extrasaction.lower() not in ("raise", "ignore"): raise ValueError, \ ("extrasaction (%s) must be 'raise' or 'ignore'" % extrasaction) self.extrasaction = extrasaction self.writer = writer(f, dialect, *args) def _dict_to_list(self, rowdict): if self.extrasaction == "raise": for k in rowdict.keys(): if k not in self.fieldnames: raise ValueError, "dict contains fields not in fieldnames" return [rowdict.get(key, self.restval) for key in self.fieldnames] def writerow(self, rowdict): return self.writer.writerow(self._dict_to_list(rowdict)) def writerows(self, rowdicts): rows = [] for rowdict in rowdicts: rows.append(self._dict_to_list(rowdict)) return self.writer.writerows(rows) From montanaro@users.sourceforge.net Thu Mar 20 23:29:14 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 20 Mar 2003 15:29:14 -0800 Subject: [Python-checkins] python/dist/src/Doc/lib libcsv.tex,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory sc8-pr-cvs1:/tmp/cvs-serv24199/Doc/lib Added Files: libcsv.tex Log Message: new CSV file processing module - see PEP 305 --- NEW FILE: libcsv.tex --- \section{\module{csv} --- CSV File Reading and Writing} \declaremodule{standard}{csv} \modulesynopsis{Write and read tabular data to and from delimited files.} \versionadded{2.3} \index{csv} \indexii{data}{tabular} The so-called CSV (Comma Separated Values) format is the most common import and export format for spreadsheets and databases. There is no ``CSV standard'', so the format is operationally defined by the many applications which read and write it. The lack of a standard means that subtle differences often exist in the data produced and consumed by different applications. These differences can make it annoying to process CSV files from multiple sources. Still, while the delimiters and quoting characters vary, the overall format is similar enough that it is possible to write a single module which can efficiently manipulate such data, hiding the details of reading and writing the data from the programmer. The \module{csv} module implements classes to read and write tabular data in CSV format. It allows programmers to say, ``write this data in the format preferred by Excel,'' or ``read data from this file which was generated by Excel,'' without knowing the precise details of the CSV format used by Excel. Programmers can also describe the CSV formats understood by other applications or define their own special-purpose CSV formats. The \module{csv} module's \class{reader} and \class{writer} objects read and write sequences. Programmers can also read and write data in dictionary form using the \class{DictReader} and \class{DictWriter} classes. \note{The first version of the \module{csv} module doesn't support Unicode input. Also, there are currently some issues regarding \ASCII{} NUL characters. Accordingly, all input should generally be plain \ASCII{} to be safe. These restrictions will be removed in the future.} \begin{seealso} % \seemodule{array}{Arrays of uniformly types numeric values.} \seepep{305}{CSV File API} {The Python Enhancement Proposal which proposed this addition to Python.} \end{seealso} \subsection{Module Contents} The \module{csv} module defines the following functions: \begin{funcdesc}{reader}{csvfile\optional{, dialect=\code{'excel'}\optional{, fmtparam}}} Return a reader object which will iterate over lines in the given {}\var{csvfile}. \var{csvfile} can be any object which supports the iterator protocol and returns a string each time its \method{next} method is called. An optional \var{dialect} parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of the \class{Dialect} class or one of the strings returned by the \function{list_dialects} function. The other optional {}\var{fmtparam} keyword arguments can be given to override individual formatting parameters in the current dialect. For more information about the dialect and formatting parameters, see section~\ref{fmt-params}, ``Dialects and Formatting Parameters'' for details of these parameters. All data read are returned as strings. No automatic data type conversion is performed. \end{funcdesc} \begin{funcdesc}{writer}{csvfile\optional{, dialect=\code{'excel'}\optional{, fmtparam}}} Return a writer object responsible for converting the user's data into delimited strings on the given file-like object. An optional {}\var{dialect} parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of the \class{Dialect} class or one of the strings returned by the \function{list_dialects} function. The other optional {}\var{fmtparam} keyword arguments can be given to override individual formatting parameters in the current dialect. For more information about the dialect and formatting parameters, see section~\ref{fmt-params}, ``Dialects and Formatting Parameters'' for details of these parameters. To make it as easy as possible to interface with modules which implement the DB API, the value \constant{None} is written as the empty string. While this isn't a reversible transformation, it makes it easier to dump SQL NULL data values to CSV files without preprocessing the data returned from a \code{cursor.fetch*()} call. All other non-string data are stringified with \function{str()} before being written. \end{funcdesc} \begin{funcdesc}{register_dialect}{name, dialect} Associate \var{dialect} with \var{name}. \var{dialect} must be a subclass of \class{csv.Dialect}. \var{name} must be a string or Unicode object. \end{funcdesc} \begin{funcdesc}{unregister_dialect}{name} Delete the dialect associated with \var{name} from the dialect registry. An \exception{Error} is raised if \var{name} is not a registered dialect name. \end{funcdesc} \begin{funcdesc}{get_dialect}{name} Return the dialect associated with \var{name}. An \exception{Error} is raised if \var{name} is not a registered dialect name. \end{funcdesc} \begin{funcdesc}{list_dialects}{} Return the names of all registered dialects. \end{funcdesc} The \module{csv} module defines the following classes: \begin{classdesc}{DictReader}{csvfile, fieldnames\optional{, restkey=\code{None}\optional{, restval=\code{None}\optional{, dialect=\code{'excel'}\optional{, fmtparam}}}}} Create an object which operates like a regular reader but maps the information read into a dict whose keys are given by the \var{fieldnames} parameter. If the row read has fewer fields than the fieldnames sequence, the value of \var{restval} will be used as the default value. If the row read has more fields than the fieldnames sequence, the remaining data is added as a sequence keyed by the value of \var{restkey}. If the row read has fewer fields than the fieldnames sequence, the remaining keys take the value of the optiona \var{restval} parameter. All other parameters are interpreted as for regular readers. \end{classdesc} \begin{classdesc}{DictWriter}{csvfile, fieldnames\optional{, restval=""\optional{, extrasaction=\code{'raise'}\optional{, dialect=\code{'excel'}\optional{, fmtparam}}}}} Create an object which operates like a regular writer but maps dictionaries onto output rows. The \var{fieldnames} parameter identifies the order in which values in the dictionary passed to the \method{writerow()} method are written to the \var{csvfile}. The optional \var{restval} parameter specifies the value to be written if the dictionary is missing a key in \var{fieldnames}. If the dictionary passed to the \method{writerow()} method contains a key not found in \var{fieldnames}, the optional \var{extrasaction} parameter indicates what action to take. If it is set to \code{'raise'} a \exception{ValueError} is raised. If it is set to \code{'ignore'}, extra values in the dictionary are ignored. All other parameters are interpreted as for regular writers. \end{classdesc} \begin{classdesc*}{Dialect}{} The \class{Dialect} class is a container class relied on primarily for its attributes, which are used to define the parameters for a specific \class{reader} or \class{writer} instance. Dialect objects support the following data attributes: \begin{memberdesc}[string]{delimiter} A one-character string used to separate fields. It defaults to \code{","}. \end{memberdesc} \begin{memberdesc}[boolean]{doublequote} Controls how instances of \var{quotechar} appearing inside a field should be themselves be quoted. When \constant{True}, the character is doubledd. When \constant{False}, the \var{escapechar} must be a one-character string which is used as a prefix to the \var{quotechar}. It defaults to \constant{True}. \end{memberdesc} \begin{memberdesc}{escapechar} A one-character string used to escape the \var{delimiter} if \var{quoting} is set to \constant{QUOTE_NONE}. It defaults to \constant{None}. \end{memberdesc} \begin{memberdesc}[string]{lineterminator} The string used to terminate lines in the CSV file. It defaults to \code{"\e r\e n"}. \end{memberdesc} \begin{memberdesc}[string]{quotechar} A one-character string used to quote elements containing the \var{delimiter} or which start with the \var{quotechar}. It defaults to \code{'"'}. \end{memberdesc} \begin{memberdesc}[integer]{quoting} Controls when quotes should be generated by the writer. It can take on any of the \code{QUOTE_*} constants defined below and defaults to \constant{QUOTE_MINIMAL}. \end{memberdesc} \begin{memberdesc}[boolean]{skipinitialspace} When \constant{True}, whitespace immediately following the \var{delimiter} is ignored. The default is \constant{False}. \end{memberdesc} \end{classdesc*} The \module{csv} module defines the following constants: \begin{datadesc}{QUOTE_ALWAYS} Instructs \class{writer} objects to quote all fields. \end{datadesc} \begin{datadesc}{QUOTE_MINIMAL} Instructs \class{writer} objects to only quote those fields which contain the current \var{delimiter} or begin with the current \var{quotechar}. \end{datadesc} \begin{datadesc}{QUOTE_NONNUMERIC} Instructs \class{writer} objects to quote all non-numeric fields. \end{datadesc} \begin{datadesc}{QUOTE_NONE} Instructs \class{writer} objects to never quote fields. When the current \var{delimiter} occurs in output data it is preceded by the current \var{escapechar} character. When \constant{QUOTE_NONE} is in effect, it is an error not to have a single-character \var{escapechar} defined, even if no data to be written contains the \var{delimiter} character. \end{datadesc} The \module{csv} module defines the following exception: \begin{excdesc}{Error} Raised by any of the functions when an error is detected. \end{excdesc} \subsection{Dialects and Formatting Parameters\label{fmt-params}} To make it easier to specify the format of input and output records, specific formatting parameters are grouped together into dialects. A dialect is a subclass of the \class{Dialect} class having a set of specific methods and a single \method{validate()} method. When creating \class{reader} or \class{writer} objects, the programmer can specify a string or a subclass of the \class{Dialect} class as the dialect parameter. In addition to, or instead of, the \var{dialect} parameter, the programmer can also specify individual formatting parameters, which have the same names as the attributes defined above for the \class{Dialect} class. \subsection{Reader Objects} \class{DictReader} and \var{reader} objects have the following public methods: \begin{methoddesc}{next}{} Return the next row of the reader's iterable object as a list, parsed according to the current dialect. \end{methoddesc} \subsection{Writer Objects} \class{DictWriter} and \var{writer} objects have the following public methods: \begin{methoddesc}{writerow}{row} Write the \var{row} parameter to the writer's file object, formatted according to the current dialect. \end{methoddesc} \begin{methoddesc}{writerows}{rows} Write all the \var{rows} parameters to the writer's file object, formatted according to the current dialect. \end{methoddesc} \subsection{Examples} The ``Hello, world'' of csv reading is \begin{verbatim} reader = csv.reader(file("some.csv")) for row in reader: print row \end{verbatim} The corresponding simplest possible writing example is \begin{verbatim} writer = csv.writer(file("some.csv", "w")) for row in someiterable: writer.writerow(row) \end{verbatim} From montanaro@users.sourceforge.net Thu Mar 20 23:29:14 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 20 Mar 2003 15:29:14 -0800 Subject: [Python-checkins] python/dist/src/Lib/test test_csv.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory sc8-pr-cvs1:/tmp/cvs-serv24199/Lib/test Added Files: test_csv.py Log Message: new CSV file processing module - see PEP 305 --- NEW FILE: test_csv.py --- # Copyright (C) 2001,2002 Python Software Foundation # csv package unit tests import sys import unittest from StringIO import StringIO from csv import csv import gc class Test_Csv(unittest.TestCase): """ Test the underlying C csv parser in ways that are not appropriate from the high level interface. Further tests of this nature are done in TestDialectRegistry. """ def test_reader_arg_valid(self): self.assertRaises(TypeError, csv.reader) self.assertRaises(TypeError, csv.reader, None) self.assertRaises(AttributeError, csv.reader, [], bad_attr = 0) self.assertRaises(csv.Error, csv.reader, [], 'foo') class BadClass: def __init__(self): raise IOError self.assertRaises(IOError, csv.reader, [], BadClass) self.assertRaises(TypeError, csv.reader, [], None) class BadDialect: bad_attr = 0 self.assertRaises(AttributeError, csv.reader, [], BadDialect) def test_writer_arg_valid(self): self.assertRaises(TypeError, csv.writer) self.assertRaises(TypeError, csv.writer, None) self.assertRaises(AttributeError, csv.writer, StringIO(), bad_attr = 0) def _test_attrs(self, obj): self.assertEqual(obj.dialect.delimiter, ',') obj.dialect.delimiter = '\t' self.assertEqual(obj.dialect.delimiter, '\t') self.assertRaises(TypeError, delattr, obj.dialect, 'delimiter') self.assertRaises(TypeError, setattr, obj.dialect, 'lineterminator', None) obj.dialect.escapechar = None self.assertEqual(obj.dialect.escapechar, None) self.assertRaises(TypeError, delattr, obj.dialect, 'quoting') self.assertRaises(TypeError, setattr, obj.dialect, 'quoting', None) obj.dialect.quoting = csv.QUOTE_MINIMAL self.assertEqual(obj.dialect.quoting, csv.QUOTE_MINIMAL) def test_reader_attrs(self): self._test_attrs(csv.reader([])) def test_writer_attrs(self): self._test_attrs(csv.writer(StringIO())) def _write_test(self, fields, expect, **kwargs): fileobj = StringIO() writer = csv.writer(fileobj, **kwargs) writer.writerow(fields) self.assertEqual(fileobj.getvalue(), expect + writer.dialect.lineterminator) def test_write_arg_valid(self): self.assertRaises(csv.Error, self._write_test, None, '') self._write_test((), '') self._write_test([None], '""') self.assertRaises(csv.Error, self._write_test, [None], None, quoting = csv.QUOTE_NONE) # Check that exceptions are passed up the chain class BadList: def __len__(self): return 10; def __getitem__(self, i): if i > 2: raise IOError self.assertRaises(IOError, self._write_test, BadList(), '') class BadItem: def __str__(self): raise IOError self.assertRaises(IOError, self._write_test, [BadItem()], '') def test_write_bigfield(self): # This exercises the buffer realloc functionality bigstring = 'X' * 50000 self._write_test([bigstring,bigstring], '%s,%s' % \ (bigstring, bigstring)) def test_write_quoting(self): self._write_test(['a','1','p,q'], 'a,1,"p,q"') self.assertRaises(csv.Error, self._write_test, ['a','1','p,q'], 'a,1,"p,q"', quoting = csv.QUOTE_NONE) self._write_test(['a','1','p,q'], 'a,1,"p,q"', quoting = csv.QUOTE_MINIMAL) self._write_test(['a','1','p,q'], '"a",1,"p,q"', quoting = csv.QUOTE_NONNUMERIC) self._write_test(['a','1','p,q'], '"a","1","p,q"', quoting = csv.QUOTE_ALL) def test_write_escape(self): self._write_test(['a','1','p,q'], 'a,1,"p,q"', escapechar='\\') # FAILED - needs to be fixed [am]: # self._write_test(['a','1','p,"q"'], 'a,1,"p,\\"q\\"', # escapechar='\\', doublequote = 0) self._write_test(['a','1','p,q'], 'a,1,p\\,q', escapechar='\\', quoting = csv.QUOTE_NONE) def test_writerows(self): class BrokenFile: def write(self, buf): raise IOError writer = csv.writer(BrokenFile()) self.assertRaises(IOError, writer.writerows, [['a']]) fileobj = StringIO() writer = csv.writer(fileobj) self.assertRaises(TypeError, writer.writerows, None) writer.writerows([['a','b'],['c','d']]) self.assertEqual(fileobj.getvalue(), "a,b\r\nc,d\r\n") def _read_test(self, input, expect, **kwargs): reader = csv.reader(input, **kwargs) result = list(reader) self.assertEqual(result, expect) def test_read_oddinputs(self): self._read_test([], []) self._read_test([''], [[]]) self.assertRaises(csv.Error, self._read_test, ['"ab"c'], None, strict = 1) # cannot handle null bytes for the moment self.assertRaises(csv.Error, self._read_test, ['ab\0c'], None, strict = 1) self._read_test(['"ab"c'], [['abc']], doublequote = 0) def test_read_eol(self): self._read_test(['a,b'], [['a','b']]) self._read_test(['a,b\n'], [['a','b']]) self._read_test(['a,b\r\n'], [['a','b']]) self._read_test(['a,b\r'], [['a','b']]) self.assertRaises(csv.Error, self._read_test, ['a,b\rc,d'], []) self.assertRaises(csv.Error, self._read_test, ['a,b\nc,d'], []) self.assertRaises(csv.Error, self._read_test, ['a,b\r\nc,d'], []) def test_read_escape(self): self._read_test(['a,\\b,c'], [['a', '\\b', 'c']], escapechar='\\') self._read_test(['a,b\\,c'], [['a', 'b,c']], escapechar='\\') self._read_test(['a,"b\\,c"'], [['a', 'b,c']], escapechar='\\') self._read_test(['a,"b,\\c"'], [['a', 'b,\\c']], escapechar='\\') self._read_test(['a,"b,c\\""'], [['a', 'b,c"']], escapechar='\\') self._read_test(['a,"b,c"\\'], [['a', 'b,c\\']], escapechar='\\') def test_read_bigfield(self): # This exercises the buffer realloc functionality bigstring = 'X' * 50000 bigline = '%s,%s' % (bigstring, bigstring) self._read_test([bigline], [[bigstring, bigstring]]) class TestDialectRegistry(unittest.TestCase): def test_registry_badargs(self): self.assertRaises(TypeError, csv.list_dialects, None) self.assertRaises(TypeError, csv.get_dialect) self.assertRaises(csv.Error, csv.get_dialect, None) self.assertRaises(csv.Error, csv.get_dialect, "nonesuch") self.assertRaises(TypeError, csv.unregister_dialect) self.assertRaises(csv.Error, csv.unregister_dialect, None) self.assertRaises(csv.Error, csv.unregister_dialect, "nonesuch") self.assertRaises(TypeError, csv.register_dialect, None) self.assertRaises(TypeError, csv.register_dialect, None, None) self.assertRaises(TypeError, csv.register_dialect, "nonesuch", None) class bogus: def __init__(self): raise KeyError self.assertRaises(KeyError, csv.register_dialect, "nonesuch", bogus) def test_registry(self): class myexceltsv(csv.excel): delimiter = "\t" name = "myexceltsv" expected_dialects = csv.list_dialects() + [name] expected_dialects.sort() csv.register_dialect(name, myexceltsv) try: self.failUnless(isinstance(csv.get_dialect(name), myexceltsv)) got_dialects = csv.list_dialects() got_dialects.sort() self.assertEqual(expected_dialects, got_dialects) finally: csv.unregister_dialect(name) def test_incomplete_dialect(self): class myexceltsv(csv.Dialect): delimiter = "\t" self.assertRaises(csv.Error, myexceltsv) def test_space_dialect(self): class space(csv.excel): delimiter = " " quoting = csv.QUOTE_NONE escapechar = "\\" s = StringIO("abc def\nc1ccccc1 benzene\n") rdr = csv.reader(s, dialect=space()) self.assertEqual(rdr.next(), ["abc", "def"]) self.assertEqual(rdr.next(), ["c1ccccc1", "benzene"]) def test_dialect_apply(self): class testA(csv.excel): delimiter = "\t" class testB(csv.excel): delimiter = ":" class testC(csv.excel): delimiter = "|" csv.register_dialect('testC', testC) try: fileobj = StringIO() writer = csv.writer(fileobj) writer.writerow([1,2,3]) self.assertEqual(fileobj.getvalue(), "1,2,3\r\n") fileobj = StringIO() writer = csv.writer(fileobj, testA) writer.writerow([1,2,3]) self.assertEqual(fileobj.getvalue(), "1\t2\t3\r\n") fileobj = StringIO() writer = csv.writer(fileobj, dialect=testB()) writer.writerow([1,2,3]) self.assertEqual(fileobj.getvalue(), "1:2:3\r\n") fileobj = StringIO() writer = csv.writer(fileobj, dialect='testC') writer.writerow([1,2,3]) self.assertEqual(fileobj.getvalue(), "1|2|3\r\n") fileobj = StringIO() writer = csv.writer(fileobj, dialect=testA, delimiter=';') writer.writerow([1,2,3]) self.assertEqual(fileobj.getvalue(), "1;2;3\r\n") finally: csv.unregister_dialect('testC') def test_bad_dialect(self): # Unknown parameter self.assertRaises(AttributeError, csv.reader, [], bad_attr = 0) # Bad values self.assertRaises(TypeError, csv.reader, [], delimiter = None) self.assertRaises(TypeError, csv.reader, [], quoting = -1) self.assertRaises(TypeError, csv.reader, [], quoting = 100) class TestCsvBase(unittest.TestCase): def readerAssertEqual(self, input, expected_result): reader = csv.reader(StringIO(input), dialect = self.dialect) fields = list(reader) self.assertEqual(fields, expected_result) def writerAssertEqual(self, input, expected_result): fileobj = StringIO() writer = csv.writer(fileobj, dialect = self.dialect) writer.writerows(input) self.assertEqual(fileobj.getvalue(), expected_result) class TestDialectExcel(TestCsvBase): dialect = 'excel' def test_single(self): self.readerAssertEqual('abc', [['abc']]) def test_simple(self): self.readerAssertEqual('1,2,3,4,5', [['1','2','3','4','5']]) def test_blankline(self): self.readerAssertEqual('', []) def test_empty_fields(self): self.readerAssertEqual(',', [['', '']]) def test_singlequoted(self): self.readerAssertEqual('""', [['']]) def test_singlequoted_left_empty(self): self.readerAssertEqual('"",', [['','']]) def test_singlequoted_right_empty(self): self.readerAssertEqual(',""', [['','']]) def test_single_quoted_quote(self): self.readerAssertEqual('""""', [['"']]) def test_quoted_quotes(self): self.readerAssertEqual('""""""', [['""']]) def test_inline_quote(self): self.readerAssertEqual('a""b', [['a""b']]) def test_inline_quotes(self): self.readerAssertEqual('a"b"c', [['a"b"c']]) def test_quotes_and_more(self): self.readerAssertEqual('"a"b', [['ab']]) def test_lone_quote(self): self.readerAssertEqual('a"b', [['a"b']]) def test_quote_and_quote(self): self.readerAssertEqual('"a" "b"', [['a "b"']]) def test_space_and_quote(self): self.readerAssertEqual(' "a"', [[' "a"']]) def test_quoted(self): self.readerAssertEqual('1,2,3,"I think, therefore I am",5,6', [['1', '2', '3', 'I think, therefore I am', '5', '6']]) def test_quoted_quote(self): self.readerAssertEqual('1,2,3,"""I see,"" said the blind man","as he picked up his hammer and saw"', [['1', '2', '3', '"I see," said the blind man', 'as he picked up his hammer and saw']]) def test_quoted_nl(self): input = '''\ 1,2,3,"""I see,"" said the blind man","as he picked up his hammer and saw" 9,8,7,6''' self.readerAssertEqual(input, [['1', '2', '3', '"I see,"\nsaid the blind man', 'as he picked up his\nhammer and saw'], ['9','8','7','6']]) def test_dubious_quote(self): self.readerAssertEqual('12,12,1",', [['12', '12', '1"', '']]) def test_null(self): self.writerAssertEqual([], '') def test_single(self): self.writerAssertEqual([['abc']], 'abc\r\n') def test_simple(self): self.writerAssertEqual([[1, 2, 'abc', 3, 4]], '1,2,abc,3,4\r\n') def test_quotes(self): self.writerAssertEqual([[1, 2, 'a"bc"', 3, 4]], '1,2,"a""bc""",3,4\r\n') def test_quote_fieldsep(self): self.writerAssertEqual([['abc,def']], '"abc,def"\r\n') def test_newlines(self): self.writerAssertEqual([[1, 2, 'a\nbc', 3, 4]], '1,2,"a\nbc",3,4\r\n') class EscapedExcel(csv.excel): quoting = csv.QUOTE_NONE escapechar = '\\' class TestEscapedExcel(TestCsvBase): dialect = EscapedExcel() def test_escape_fieldsep(self): self.writerAssertEqual([['abc,def']], 'abc\\,def\r\n') def test_read_escape_fieldsep(self): self.readerAssertEqual('abc\\,def\r\n', [['abc,def']]) class QuotedEscapedExcel(csv.excel): quoting = csv.QUOTE_NONNUMERIC escapechar = '\\' class TestQuotedEscapedExcel(TestCsvBase): dialect = QuotedEscapedExcel() def test_write_escape_fieldsep(self): self.writerAssertEqual([['abc,def']], '"abc,def"\r\n') def test_read_escape_fieldsep(self): self.readerAssertEqual('"abc\\,def"\r\n', [['abc,def']]) # Disabled, pending support in csv.utils module class TestDictFields(unittest.TestCase): ### "long" means the row is longer than the number of fieldnames ### "short" means there are fewer elements in the row than fieldnames def test_write_simple_dict(self): fileobj = StringIO() writer = csv.DictWriter(fileobj, fieldnames = ["f1", "f2", "f3"]) writer.writerow({"f1": 10, "f3": "abc"}) self.assertEqual(fileobj.getvalue(), "10,,abc\r\n") def test_write_no_fields(self): fileobj = StringIO() self.assertRaises(TypeError, csv.DictWriter, fileobj) def test_read_dict_fields(self): reader = csv.DictReader(StringIO("1,2,abc\r\n"), fieldnames=["f1", "f2", "f3"]) self.assertEqual(reader.next(), {"f1": '1', "f2": '2', "f3": 'abc'}) def test_read_long(self): reader = csv.DictReader(StringIO("1,2,abc,4,5,6\r\n"), fieldnames=["f1", "f2"]) self.assertEqual(reader.next(), {"f1": '1', "f2": '2', None: ["abc", "4", "5", "6"]}) def test_read_long_with_rest(self): reader = csv.DictReader(StringIO("1,2,abc,4,5,6\r\n"), fieldnames=["f1", "f2"], restkey="_rest") self.assertEqual(reader.next(), {"f1": '1', "f2": '2', "_rest": ["abc", "4", "5", "6"]}) def test_read_short(self): reader = csv.DictReader(["1,2,abc,4,5,6\r\n","1,2,abc\r\n"], fieldnames="1 2 3 4 5 6".split(), restval="DEFAULT") self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc', "4": '4', "5": '5', "6": '6'}) self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc', "4": 'DEFAULT', "5": 'DEFAULT', "6": 'DEFAULT'}) def test_read_with_blanks(self): reader = csv.DictReader(["1,2,abc,4,5,6\r\n","\r\n", "1,2,abc,4,5,6\r\n"], fieldnames="1 2 3 4 5 6".split()) self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc', "4": '4', "5": '5', "6": '6'}) self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc', "4": '4', "5": '5', "6": '6'}) class TestArrayWrites(unittest.TestCase): def test_int_write(self): import array contents = [(20-i) for i in range(20)] a = array.array('i', contents) fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") writer.writerow(a) expected = ",".join([str(i) for i in a])+"\r\n" self.assertEqual(fileobj.getvalue(), expected) def test_double_write(self): import array contents = [(20-i)*0.1 for i in range(20)] a = array.array('d', contents) fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") writer.writerow(a) expected = ",".join([str(i) for i in a])+"\r\n" self.assertEqual(fileobj.getvalue(), expected) def test_float_write(self): import array contents = [(20-i)*0.1 for i in range(20)] a = array.array('f', contents) fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") writer.writerow(a) expected = ",".join([str(i) for i in a])+"\r\n" self.assertEqual(fileobj.getvalue(), expected) def test_char_write(self): import array, string a = array.array('c', string.letters) fileobj = StringIO() writer = csv.writer(fileobj, dialect="excel") writer.writerow(a) expected = ",".join(a)+"\r\n" self.assertEqual(fileobj.getvalue(), expected) class TestDialectValidity(unittest.TestCase): def test_quoting(self): class mydialect(csv.Dialect): delimiter = ";" escapechar = '\\' doublequote = False skipinitialspace = True lineterminator = '\r\n' quoting = csv.QUOTE_NONE d = mydialect() mydialect.quoting = None self.assertRaises(csv.Error, mydialect) mydialect.quoting = csv.QUOTE_NONE mydialect.escapechar = None self.assertRaises(csv.Error, mydialect) mydialect.doublequote = True mydialect.quoting = csv.QUOTE_ALL mydialect.quotechar = '"' d = mydialect() mydialect.quotechar = "''" self.assertRaises(csv.Error, mydialect) mydialect.quotechar = 4 self.assertRaises(csv.Error, mydialect) def test_delimiter(self): class mydialect(csv.Dialect): delimiter = ";" escapechar = '\\' doublequote = False skipinitialspace = True lineterminator = '\r\n' quoting = csv.QUOTE_NONE d = mydialect() mydialect.delimiter = ":::" self.assertRaises(csv.Error, mydialect) mydialect.delimiter = 4 self.assertRaises(csv.Error, mydialect) def test_lineterminator(self): class mydialect(csv.Dialect): delimiter = ";" escapechar = '\\' doublequote = False skipinitialspace = True lineterminator = '\r\n' quoting = csv.QUOTE_NONE d = mydialect() mydialect.lineterminator = ":::" d = mydialect() mydialect.lineterminator = 4 self.assertRaises(csv.Error, mydialect) if not hasattr(sys, "gettotalrefcount"): print "*** skipping leakage tests ***" else: class NUL: def write(s, *args): pass writelines = write class TestLeaks(unittest.TestCase): def test_create_read(self): delta = 0 lastrc = sys.gettotalrefcount() for i in xrange(20): gc.collect() self.assertEqual(gc.garbage, []) rc = sys.gettotalrefcount() csv.reader(["a,b,c\r\n"]) csv.reader(["a,b,c\r\n"]) csv.reader(["a,b,c\r\n"]) delta = rc-lastrc lastrc = rc # if csv.reader() leaks, last delta should be 3 or more self.assertEqual(delta < 3, True) def test_create_write(self): delta = 0 lastrc = sys.gettotalrefcount() s = NUL() for i in xrange(20): gc.collect() self.assertEqual(gc.garbage, []) rc = sys.gettotalrefcount() csv.writer(s) csv.writer(s) csv.writer(s) delta = rc-lastrc lastrc = rc # if csv.writer() leaks, last delta should be 3 or more self.assertEqual(delta < 3, True) def test_read(self): delta = 0 rows = ["a,b,c\r\n"]*5 lastrc = sys.gettotalrefcount() for i in xrange(20): gc.collect() self.assertEqual(gc.garbage, []) rc = sys.gettotalrefcount() rdr = csv.reader(rows) for row in rdr: pass delta = rc-lastrc lastrc = rc # if reader leaks during read, delta should be 5 or more self.assertEqual(delta < 5, True) def test_write(self): delta = 0 rows = [[1,2,3]]*5 s = NUL() lastrc = sys.gettotalrefcount() for i in xrange(20): gc.collect() self.assertEqual(gc.garbage, []) rc = sys.gettotalrefcount() writer = csv.writer(s) for row in rows: writer.writerow(row) delta = rc-lastrc lastrc = rc # if writer leaks during write, last delta should be 5 or more self.assertEqual(delta < 5, True) def _testclasses(): mod = sys.modules[__name__] return [getattr(mod, name) for name in dir(mod) if name.startswith('Test')] def suite(): suite = unittest.TestSuite() for testclass in _testclasses(): suite.addTest(unittest.makeSuite(testclass)) return suite if __name__ == '__main__': unittest.main(defaultTest='suite') From montanaro@users.sourceforge.net Thu Mar 20 23:31:04 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 20 Mar 2003 15:31:04 -0800 Subject: [Python-checkins] python/dist/src/Lib/csv/util - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Lib/csv/util In directory sc8-pr-cvs1:/tmp/cvs-serv25338/Lib/csv/util Log Message: Directory /cvsroot/python/python/dist/src/Lib/csv/util added to the repository From montanaro@users.sourceforge.net Thu Mar 20 23:31:26 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 20 Mar 2003 15:31:26 -0800 Subject: [Python-checkins] python/dist/src/Lib/csv/util sniffer.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/csv/util In directory sc8-pr-cvs1:/tmp/cvs-serv25444/Lib/csv/util Added Files: sniffer.py Log Message: forgot Cliff's sniffer --- NEW FILE: sniffer.py --- """ dialect = Sniffer().sniff(file('csv/easy.csv')) print "delimiter", dialect.delimiter print "quotechar", dialect.quotechar print "skipinitialspace", dialect.skipinitialspace """ from csv import csv import re # ------------------------------------------------------------------------------ class Sniffer: """ "Sniffs" the format of a CSV file (i.e. delimiter, quotechar) Returns a csv.Dialect object. """ def __init__(self, sample = 16 * 1024): # in case there is more than one possible delimiter self.preferred = [',', '\t', ';', ' ', ':'] # amount of data (in bytes) to sample self.sample = sample def sniff(self, fileobj): """ Takes a file-like object and returns a dialect (or None) """ self.fileobj = fileobj data = fileobj.read(self.sample) quotechar, delimiter, skipinitialspace = self._guessQuoteAndDelimiter(data) if delimiter is None: delimiter, skipinitialspace = self._guessDelimiter(data) class Dialect(csv.Dialect): _name = "sniffed" lineterminator = '\r\n' quoting = csv.QUOTE_MINIMAL # escapechar = '' doublequote = False Dialect.delimiter = delimiter Dialect.quotechar = quotechar Dialect.skipinitialspace = skipinitialspace self.dialect = Dialect return self.dialect def hasHeaders(self): return self._hasHeaders(self.fileobj, self.dialect) def register_dialect(self, name = 'sniffed'): csv.register_dialect(name, self.dialect) def _guessQuoteAndDelimiter(self, data): """ Looks for text enclosed between two identical quotes (the probable quotechar) which are preceded and followed by the same character (the probable delimiter). For example: ,'some text', The quote with the most wins, same with the delimiter. If there is no quotechar the delimiter can't be determined this way. """ matches = [] for restr in ('(?P[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?P=delim)', # ,".*?", '(?:^|\n)(?P["\']).*?(?P=quote)(?P[^\w\n"\'])(?P ?)', # ".*?", '(?P>[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?:$|\n)', # ,".*?" '(?:^|\n)(?P["\']).*?(?P=quote)(?:$|\n)'): # ".*?" (no delim, no space) regexp = re.compile(restr, re.S | re.M) matches = regexp.findall(data) if matches: break if not matches: return ('', None, 0) # (quotechar, delimiter, skipinitialspace) quotes = {} delims = {} spaces = 0 for m in matches: n = regexp.groupindex['quote'] - 1 key = m[n] if key: quotes[key] = quotes.get(key, 0) + 1 try: n = regexp.groupindex['delim'] - 1 key = m[n] except KeyError: continue if key: delims[key] = delims.get(key, 0) + 1 try: n = regexp.groupindex['space'] - 1 except KeyError: continue if m[n]: spaces += 1 quotechar = reduce(lambda a, b, quotes = quotes: (quotes[a] > quotes[b]) and a or b, quotes.keys()) if delims: delim = reduce(lambda a, b, delims = delims: (delims[a] > delims[b]) and a or b, delims.keys()) skipinitialspace = delims[delim] == spaces if delim == '\n': # most likely a file with a single column delim = '' else: # there is *no* delimiter, it's a single column of quoted data delim = '' skipinitialspace = 0 return (quotechar, delim, skipinitialspace) def _guessDelimiter(self, data): """ The delimiter /should/ occur the same number of times on each row. However, due to malformed data, it may not. We don't want an all or nothing approach, so we allow for small variations in this number. 1) build a table of the frequency of each character on every line. 2) build a table of freqencies of this frequency (meta-frequency?), e.g. "x occurred 5 times in 10 rows, 6 times in 1000 rows, 7 times in 2 rows" 3) use the mode of the meta-frequency to determine the /expected/ frequency for that character 4) find out how often the character actually meets that goal 5) the character that best meets its goal is the delimiter For performance reasons, the data is evaluated in chunks, so it can try and evaluate the smallest portion of the data possible, evaluating additional chunks as necessary. """ data = filter(None, data.split('\n')) ascii = [chr(c) for c in range(127)] # 7-bit ASCII # build frequency tables chunkLength = min(10, len(data)) iteration = 0 charFrequency = {} modes = {} delims = {} start, end = 0, min(chunkLength, len(data)) while start < len(data): iteration += 1 for line in data[start:end]: for char in ascii: metafrequency = charFrequency.get(char, {}) freq = line.strip().count(char) # must count even if frequency is 0 metafrequency[freq] = metafrequency.get(freq, 0) + 1 # value is the mode charFrequency[char] = metafrequency for char in charFrequency.keys(): items = charFrequency[char].items() if len(items) == 1 and items[0][0] == 0: continue # get the mode of the frequencies if len(items) > 1: modes[char] = reduce(lambda a, b: a[1] > b[1] and a or b, items) # adjust the mode - subtract the sum of all other frequencies items.remove(modes[char]) modes[char] = (modes[char][0], modes[char][1] - reduce(lambda a, b: (0, a[1] + b[1]), items)[1]) else: modes[char] = items[0] # build a list of possible delimiters modeList = modes.items() total = float(chunkLength * iteration) consistency = 1.0 # (rows of consistent data) / (number of rows) = 100% threshold = 0.9 # minimum consistency threshold while len(delims) == 0 and consistency >= threshold: for k, v in modeList: if v[0] > 0 and v[1] > 0: if (v[1]/total) >= consistency: delims[k] = v consistency -= 0.01 if len(delims) == 1: delim = delims.keys()[0] skipinitialspace = data[0].count(delim) == data[0].count("%c " % delim) return (delim, skipinitialspace) # analyze another chunkLength lines start = end end += chunkLength if not delims: return ('', 0) # if there's more than one, fall back to a 'preferred' list if len(delims) > 1: for d in self.preferred: if d in delims.keys(): skipinitialspace = data[0].count(d) == data[0].count("%c " % d) return (d, skipinitialspace) # finally, just return the first damn character in the list delim = delims.keys()[0] skipinitialspace = data[0].count(delim) == data[0].count("%c " % delim) return (delim, skipinitialspace) def _hasHeaders(self, fileobj, dialect): # Creates a dictionary of types of data in each column. If any column # is of a single type (say, integers), *except* for the first row, then the first # row is presumed to be labels. If the type can't be determined, it is assumed to # be a string in which case the length of the string is the determining factor: if # all of the rows except for the first are the same length, it's a header. # Finally, a 'vote' is taken at the end for each column, adding or subtracting from # the likelihood of the first row being a header. def seval(item): """ Strips parens from item prior to calling eval in an attempt to make it safer """ return eval(item.replace('(', '').replace(')', '')) fileobj.seek(0) # rewind the fileobj - this might not work for some file-like objects... reader = csv.reader(fileobj, delimiter = dialect.delimiter, quotechar = dialect.quotechar, skipinitialspace = dialect.skipinitialspace) header = reader.next() # assume first row is header columns = len(header) columnTypes = {} for i in range(columns): columnTypes[i] = None checked = 0 for row in reader: if checked > 20: # arbitrary number of rows to check, to keep it sane break checked += 1 if len(row) != columns: continue # skip rows that have irregular number of columns for col in columnTypes.keys(): try: try: # is it a built-in type (besides string)? thisType = type(seval(row[col])) except OverflowError: # a long int? thisType = type(seval(row[col] + 'L')) thisType = type(0) # treat long ints as int except: # fallback to length of string thisType = len(row[col]) if thisType != columnTypes[col]: if columnTypes[col] is None: # add new column type columnTypes[col] = thisType else: # type is inconsistent, remove column from consideration del columnTypes[col] # finally, compare results against first row and "vote" on whether it's a header hasHeader = 0 for col, colType in columnTypes.items(): if type(colType) == type(0): # it's a length if len(header[col]) != colType: hasHeader += 1 else: hasHeader -= 1 else: # attempt typecast try: eval("%s(%s)" % (colType.__name__, header[col])) except: hasHeader += 1 else: hasHeader -= 1 return hasHeader > 0 From montanaro@users.sourceforge.net Thu Mar 20 23:34:25 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 20 Mar 2003 15:34:25 -0800 Subject: [Python-checkins] python/dist/src setup.py,1.155,1.156 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv26751 Modified Files: setup.py Log Message: build _csv extension module Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.155 retrieving revision 1.156 diff -C2 -d -r1.155 -r1.156 *** setup.py 6 Mar 2003 23:03:43 -0000 1.155 --- setup.py 20 Mar 2003 23:34:22 -0000 1.156 *************** *** 430,433 **** --- 430,436 ---- exts.append( Extension('crypt', ['cryptmodule.c'], libraries=libs) ) + # CSV files + exts.append( Extension('_csv', ['_csv.c']) ) + # socket(2) exts.append( Extension('_socket', ['socketmodule.c'], From montanaro@users.sourceforge.net Thu Mar 20 23:35:43 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 20 Mar 2003 15:35:43 -0800 Subject: [Python-checkins] python/dist/src Makefile.pre.in,1.117,1.118 Message-ID: Update of /cvsroot/python/python/dist/src In directory sc8-pr-cvs1:/tmp/cvs-serv27282 Modified Files: Makefile.pre.in Log Message: include the csv package during installation Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.117 retrieving revision 1.118 diff -C2 -d -r1.117 -r1.118 *** Makefile.pre.in 17 Mar 2003 15:43:32 -0000 1.117 --- Makefile.pre.in 20 Mar 2003 23:35:38 -0000 1.118 *************** *** 627,631 **** LIBSUBDIRS= lib-old lib-tk site-packages test test/output test/data \ encodings email email/test email/test/data compiler hotshot \ ! logging bsddb bsddb/test \ distutils distutils/command $(XMLLIBSUBDIRS) curses $(MACHDEPS) libinstall: $(BUILDPYTHON) $(srcdir)/Lib/$(PLATDIR) --- 627,631 ---- LIBSUBDIRS= lib-old lib-tk site-packages test test/output test/data \ encodings email email/test email/test/data compiler hotshot \ ! logging bsddb bsddb/test csv \ distutils distutils/command $(XMLLIBSUBDIRS) curses $(MACHDEPS) libinstall: $(BUILDPYTHON) $(srcdir)/Lib/$(PLATDIR) From montanaro@users.sourceforge.net Thu Mar 20 23:36:58 2003 From: montanaro@users.sourceforge.net (montanaro@users.sourceforge.net) Date: Thu, 20 Mar 2003 15:36:58 -0800 Subject: [Python-checkins] python/dist/src/Misc NEWS,1.700,1.701 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory sc8-pr-cvs1:/tmp/cvs-serv27744 Modified Files: NEWS Log Message: announce csv package Index: NEWS ==============================================