From python-checkins at python.org Thu Feb 1 00:31:46 2007 From: python-checkins at python.org (brett.cannon) Date: Thu, 1 Feb 2007 00:31:46 +0100 (CET) Subject: [Python-checkins] r53608 - in python/branches/bcannon-objcap: BRANCHNEWS Include/moduleobject.h Objects/moduleobject.c Python/import.c Python/pythonrun.c Message-ID: <20070131233146.8ED181E4006@bag.python.org> Author: brett.cannon Date: Thu Feb 1 00:31:44 2007 New Revision: 53608 Modified: python/branches/bcannon-objcap/BRANCHNEWS python/branches/bcannon-objcap/Include/moduleobject.h python/branches/bcannon-objcap/Objects/moduleobject.c python/branches/bcannon-objcap/Python/import.c python/branches/bcannon-objcap/Python/pythonrun.c Log: Change the import machinery on how it handles importing 'sys'. Before the import code used the cached dictionary that was created after _PySys_Init() was called but before any subsequent items were added (e.g., sys.path). Now, PyImport_FindExtension() (which is what uses the extension module cache for importing new modules) checks if it is dealing with 'sys'. If it is it then sets the module's dict to the interpreter's sysdict instead of the cached version. Modified: python/branches/bcannon-objcap/BRANCHNEWS ============================================================================== --- python/branches/bcannon-objcap/BRANCHNEWS (original) +++ python/branches/bcannon-objcap/BRANCHNEWS Thu Feb 1 00:31:44 2007 @@ -8,6 +8,11 @@ Core and builtins ----------------- +* Make importing the sys module after it has been completely deleted use the + interpreter's sysdict instead of the cached dict used by the import + machinery. This lets the sys module be deleted for security reasons during + startup. + * rev. ????: Added a delegate for import that calls sys.import_. * rev. 51679: Remove the constructor for the 'code' type. This means instances Modified: python/branches/bcannon-objcap/Include/moduleobject.h ============================================================================== --- python/branches/bcannon-objcap/Include/moduleobject.h (original) +++ python/branches/bcannon-objcap/Include/moduleobject.h Thu Feb 1 00:31:44 2007 @@ -14,6 +14,7 @@ PyAPI_FUNC(PyObject *) PyModule_New(const char *); PyAPI_FUNC(PyObject *) PyModule_GetDict(PyObject *); +PyAPI_FUNC(void) PyModule_SetDict(PyObject *, PyObject *); PyAPI_FUNC(char *) PyModule_GetName(PyObject *); PyAPI_FUNC(char *) PyModule_GetFilename(PyObject *); PyAPI_FUNC(void) _PyModule_Clear(PyObject *); Modified: python/branches/bcannon-objcap/Objects/moduleobject.c ============================================================================== --- python/branches/bcannon-objcap/Objects/moduleobject.c (original) +++ python/branches/bcannon-objcap/Objects/moduleobject.c Thu Feb 1 00:31:44 2007 @@ -54,6 +54,16 @@ return d; } +void +PyModule_SetDict(PyObject *m, PyObject *new_dict) +{ + PyModuleObject *module = (PyModuleObject *)m; + PyObject *old_dict = module->md_dict; + + Py_XDECREF(old_dict); + module->md_dict = new_dict; +} + char * PyModule_GetName(PyObject *m) { Modified: python/branches/bcannon-objcap/Python/import.c ============================================================================== --- python/branches/bcannon-objcap/Python/import.c (original) +++ python/branches/bcannon-objcap/Python/import.c Thu Feb 1 00:31:44 2007 @@ -563,8 +563,17 @@ mdict = PyModule_GetDict(mod); if (mdict == NULL) return NULL; - if (PyDict_Update(mdict, dict)) - return NULL; + if ((!strcmp("sys", name)) && (!strcmp("sys", filename))) { + PyThreadState *tstate = PyThreadState_GET(); + PyObject *sysdict = tstate->interp->sysdict; + + Py_INCREF(sysdict); + PyModule_SetDict(mod, sysdict); + } + else { + if (PyDict_Update(mdict, dict)) + return NULL; + } if (Py_VerboseFlag) PySys_WriteStderr("import %s # previously loaded (%s)\n", name, filename); Modified: python/branches/bcannon-objcap/Python/pythonrun.c ============================================================================== --- python/branches/bcannon-objcap/Python/pythonrun.c (original) +++ python/branches/bcannon-objcap/Python/pythonrun.c Thu Feb 1 00:31:44 2007 @@ -357,9 +357,6 @@ Current scope of execution. * exceptions Safe to keep around. - * sys - Certain values set during Python initialization that are lost - when the module is deleted and then re-imported. * encodings Does dynamic import of encodings which requires globals() to work; globals() fails when the module has been deleted. @@ -379,7 +376,6 @@ if ((strcmp(module_name, "__builtin__") != 0) && (strcmp(module_name, "exceptions") != 0) && (strcmp(module_name, "__main__") != 0) && - (strcmp(module_name, "sys") != 0) && (strcmp(module_name, "encodings") != 0) && (strcmp(module_name, "encodings.utf_8") != 0) && (strcmp(module_name, "codecs") != 0) && From python-checkins at python.org Thu Feb 1 01:20:26 2007 From: python-checkins at python.org (brett.cannon) Date: Thu, 1 Feb 2007 01:20:26 +0100 (CET) Subject: [Python-checkins] r53609 - in python/branches/bcannon-objcap: BRANCHNEWS Python/pythonrun.c Message-ID: <20070201002026.B64561E400D@bag.python.org> Author: brett.cannon Date: Thu Feb 1 01:20:25 2007 New Revision: 53609 Modified: python/branches/bcannon-objcap/BRANCHNEWS python/branches/bcannon-objcap/Python/pythonrun.c Log: Get the 'warnings' module cached away in the C code so that the module is still usable by C code. Modified: python/branches/bcannon-objcap/BRANCHNEWS ============================================================================== --- python/branches/bcannon-objcap/BRANCHNEWS (original) +++ python/branches/bcannon-objcap/BRANCHNEWS Thu Feb 1 01:20:25 2007 @@ -8,6 +8,8 @@ Core and builtins ----------------- +* Force 'warnings' to be cached by the C code. + * Make importing the sys module after it has been completely deleted use the interpreter's sysdict instead of the cached dict used by the import machinery. This lets the sys module be deleted for security reasons during Modified: python/branches/bcannon-objcap/Python/pythonrun.c ============================================================================== --- python/branches/bcannon-objcap/Python/pythonrun.c (original) +++ python/branches/bcannon-objcap/Python/pythonrun.c Thu Feb 1 01:20:25 2007 @@ -334,6 +334,7 @@ PyInterpreterState *interp; Py_ssize_t module_count, x; PyObject* module_names_list; + PyObject* hidden_modules; Py_InitializeEx(1); @@ -359,32 +360,53 @@ Safe to keep around. * encodings Does dynamic import of encodings which requires globals() to - work; globals() fails when the module has been deleted. - * encodings.utf_8 - Many encodings use this. + work; globals() fails when the module has been deleted. Also + fails if you hide module because importing of submodules for + encodings no longer has the parent package. * codecs Incremental codecs fail. - * warnings + * _codecs + Exposed by codecs. + * warnings (hide: needs sys._getframe()) Warnings reset otherwise. */ + /* Get the 'warnings' module cached away at the C level. */ + PyModule_GetWarningsModule(); module_names_list = PyDict_Keys(interp->modules); module_count = PyList_GET_SIZE(module_names_list); + hidden_modules = PyDict_New(); for (x=0; x < module_count; x+=1) { char *module_name = PyString_AS_STRING( PyList_GET_ITEM(module_names_list, x)); - if ((strcmp(module_name, "__builtin__") != 0) && - (strcmp(module_name, "exceptions") != 0) && - (strcmp(module_name, "__main__") != 0) && - (strcmp(module_name, "encodings") != 0) && - (strcmp(module_name, "encodings.utf_8") != 0) && - (strcmp(module_name, "codecs") != 0) && - (strcmp(module_name, "warnings") != 0)) { + /* Modules that *must* stay visible. */ + if ((strcmp(module_name, "__builtin__") == 0) || + (strcmp(module_name, "__main__") == 0) || + (strcmp(module_name, "exceptions") == 0) || + (strcmp(module_name, "encodings") == 0) || + (strcmp(module_name, "codecs") == 0) || + (strcmp(module_name, "_codecs") == 0)) { + continue; + } + /* Modules that *must* stay but can be invisible. */ + /*else if ((strcmp(module_name, "warnings") == 0)) { + PyObject *module = + PyDict_GetItemString(interp->modules, + module_name); + PyDict_SetItemString(hidden_modules, module_name, + module); + PyDict_DelItemString(interp->modules, module_name); + }*/ + /* Everything else can go. */ + else { PyDict_DelItemString(interp->modules, module_name); } } - PyDict_SetItemString(interp->sysdict, "modules", interp->modules); + /* Store away modules that must stick around but should not be exposed. + */ + PyDict_SetItemString(interp->modules, ".hidden", hidden_modules); + PyDict_SetItemString(interp->sysdict, "modules", interp->modules); } From buildbot at python.org Thu Feb 1 03:39:53 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 01 Feb 2007 02:39:53 +0000 Subject: [Python-checkins] buildbot failure in x86 OpenBSD 2.5 Message-ID: <20070201023953.DD27A1E4006@bag.python.org> The Buildbot has detected a new failure of x86 OpenBSD 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520OpenBSD%25202.5/builds/183 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Reynaldo': Robbie Build Source Stamp: [branch Addison] Dylan Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Thu Feb 1 03:40:23 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 01 Feb 2007 02:40:23 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.5 Message-ID: <20070201024023.0D9591E400D@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520gentoo%25202.5/builds/201 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Nicholas': Rodney Build Source Stamp: [branch Roberto] Chris Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Thu Feb 1 03:42:51 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 01 Feb 2007 02:42:51 +0000 Subject: [Python-checkins] buildbot failure in x86 XP 2.5 Message-ID: <20070201024251.95A611E4006@bag.python.org> The Buildbot has detected a new failure of x86 XP 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520XP%25202.5/builds/104 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Daquan': Jayden Build Source Stamp: [branch Elian] River Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Thu Feb 1 03:53:51 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 01 Feb 2007 02:53:51 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 2.5 Message-ID: <20070201025352.0B1171E4006@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%2520gentoo%25202.5/builds/204 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Mauro': Wyatt Build Source Stamp: [branch Igor] Ali Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Thu Feb 1 04:00:08 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 01 Feb 2007 03:00:08 +0000 Subject: [Python-checkins] buildbot failure in g4 osx.4 2.5 Message-ID: <20070201030008.5ED2D1E4006@bag.python.org> The Buildbot has detected a new failure of g4 osx.4 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/g4%2520osx.4%25202.5/builds/193 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Carey': Chance Build Source Stamp: [branch Fernando] Marcos Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Thu Feb 1 04:00:24 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 01 Feb 2007 03:00:24 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 2.5 Message-ID: <20070201030024.7FEE91E4006@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%2520solaris10%2520gcc%25202.5/builds/194 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Emmett': Markus Build Source Stamp: [branch Jace] Kenny Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From python-checkins at python.org Thu Feb 1 19:02:39 2007 From: python-checkins at python.org (thomas.wouters) Date: Thu, 1 Feb 2007 19:02:39 +0100 (CET) Subject: [Python-checkins] r53610 - in python/branches/p3yk: Doc/api/concrete.tex Doc/commontex/license.tex Doc/dist/dist.tex Doc/lib/libmailbox.tex Doc/lib/librandom.tex Doc/lib/libstruct.tex Doc/lib/libtime.tex Doc/ref/ref3.tex Include/Python-ast.h Include/object.h Lib/logging/handlers.py Lib/mailbox.py Lib/ntpath.py Lib/pdb.py Lib/random.py Lib/rfc822.py Lib/smtplib.py Lib/socket.py Lib/tarfile.py Lib/test/crashers/weakref_in_del.py Lib/test/output/test_new Lib/test/output/test_popen Lib/test/output/test_resource Lib/test/test_array.py Lib/test/test_deque.py Lib/test/test_dumbdbm.py Lib/test/test_itertools.py Lib/test/test_mailbox.py Lib/test/test_new.py Lib/test/test_ntpath.py Lib/test/test_old_mailbox.py Lib/test/test_popen.py Lib/test/test_posixpath.py Lib/test/test_random.py Lib/test/test_resource.py Lib/test/test_socket.py Lib/test/test_struct.py Lib/test/test_urllib2net.py Lib/test/test_uu.py Lib/test/test_weakref.py Lib/urllib.py Lib/urllib2.py Modules/_ctypes/_ctypes_test.c Modules/_randommodule.c Modules/_struct.c Modules/arraymodule.c Modules/collectionsmodule.c Modules/itertoolsmodule.c Objects/fileobject.c Objects/object.c Objects/typeobject.c Objects/weakrefobject.c PCbuild/_bsddb.vcproj PCbuild/_elementtree.vcproj PCbuild/_msi.vcproj PCbuild/_socket.vcproj PCbuild/_sqlite3.vcproj PCbuild/_ssl.mak PCbuild/_testcapi.vcproj PCbuild/_tkinter.vcproj PCbuild/build_ssl.py PCbuild/bz2.vcproj PCbuild/pyexpat.vcproj PCbuild/python.vcproj PCbuild/pythoncore.vcproj PCbuild/pythonw.vcproj PCbuild/select.vcproj PCbuild/unicodedata.vcproj PCbuild/winsound.vcproj Parser/asdl_c.py Python/pythonrun.c Python/sysmodule.c Python/traceback.c Tools/msi/uuids.py configure configure.in pyconfig.h.in Message-ID: <20070201180239.E2C411E4009@bag.python.org> Author: thomas.wouters Date: Thu Feb 1 19:02:27 2007 New Revision: 53610 Removed: python/branches/p3yk/Lib/test/output/test_new python/branches/p3yk/Lib/test/output/test_popen python/branches/p3yk/Lib/test/output/test_resource Modified: python/branches/p3yk/ (props changed) python/branches/p3yk/Doc/api/concrete.tex python/branches/p3yk/Doc/commontex/license.tex python/branches/p3yk/Doc/dist/dist.tex python/branches/p3yk/Doc/lib/libmailbox.tex python/branches/p3yk/Doc/lib/librandom.tex python/branches/p3yk/Doc/lib/libstruct.tex python/branches/p3yk/Doc/lib/libtime.tex python/branches/p3yk/Doc/ref/ref3.tex python/branches/p3yk/Include/Python-ast.h python/branches/p3yk/Include/object.h python/branches/p3yk/Lib/logging/handlers.py python/branches/p3yk/Lib/mailbox.py python/branches/p3yk/Lib/ntpath.py python/branches/p3yk/Lib/pdb.py python/branches/p3yk/Lib/random.py python/branches/p3yk/Lib/rfc822.py python/branches/p3yk/Lib/smtplib.py python/branches/p3yk/Lib/socket.py python/branches/p3yk/Lib/tarfile.py python/branches/p3yk/Lib/test/crashers/weakref_in_del.py python/branches/p3yk/Lib/test/test_array.py python/branches/p3yk/Lib/test/test_deque.py python/branches/p3yk/Lib/test/test_dumbdbm.py python/branches/p3yk/Lib/test/test_itertools.py python/branches/p3yk/Lib/test/test_mailbox.py python/branches/p3yk/Lib/test/test_new.py python/branches/p3yk/Lib/test/test_ntpath.py python/branches/p3yk/Lib/test/test_old_mailbox.py python/branches/p3yk/Lib/test/test_popen.py python/branches/p3yk/Lib/test/test_posixpath.py python/branches/p3yk/Lib/test/test_random.py python/branches/p3yk/Lib/test/test_resource.py python/branches/p3yk/Lib/test/test_socket.py python/branches/p3yk/Lib/test/test_struct.py python/branches/p3yk/Lib/test/test_urllib2net.py python/branches/p3yk/Lib/test/test_uu.py python/branches/p3yk/Lib/test/test_weakref.py python/branches/p3yk/Lib/urllib.py python/branches/p3yk/Lib/urllib2.py python/branches/p3yk/Modules/_ctypes/_ctypes_test.c python/branches/p3yk/Modules/_randommodule.c python/branches/p3yk/Modules/_struct.c python/branches/p3yk/Modules/arraymodule.c python/branches/p3yk/Modules/collectionsmodule.c python/branches/p3yk/Modules/itertoolsmodule.c python/branches/p3yk/Objects/fileobject.c python/branches/p3yk/Objects/object.c python/branches/p3yk/Objects/typeobject.c python/branches/p3yk/Objects/weakrefobject.c python/branches/p3yk/PCbuild/_bsddb.vcproj python/branches/p3yk/PCbuild/_elementtree.vcproj python/branches/p3yk/PCbuild/_msi.vcproj python/branches/p3yk/PCbuild/_socket.vcproj python/branches/p3yk/PCbuild/_sqlite3.vcproj python/branches/p3yk/PCbuild/_ssl.mak python/branches/p3yk/PCbuild/_testcapi.vcproj python/branches/p3yk/PCbuild/_tkinter.vcproj python/branches/p3yk/PCbuild/build_ssl.py python/branches/p3yk/PCbuild/bz2.vcproj python/branches/p3yk/PCbuild/pyexpat.vcproj python/branches/p3yk/PCbuild/python.vcproj python/branches/p3yk/PCbuild/pythoncore.vcproj python/branches/p3yk/PCbuild/pythonw.vcproj python/branches/p3yk/PCbuild/select.vcproj python/branches/p3yk/PCbuild/unicodedata.vcproj python/branches/p3yk/PCbuild/winsound.vcproj python/branches/p3yk/Parser/asdl_c.py python/branches/p3yk/Python/pythonrun.c python/branches/p3yk/Python/sysmodule.c python/branches/p3yk/Python/traceback.c python/branches/p3yk/Tools/msi/uuids.py python/branches/p3yk/configure python/branches/p3yk/configure.in python/branches/p3yk/pyconfig.h.in Log: Merged revisions 53451-53537 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r53454 | brett.cannon | 2007-01-15 20:12:08 +0100 (Mon, 15 Jan 2007) | 3 lines Add a note for strptime that just because strftime supports some extra directive that is not documented that strptime will as well. ........ r53458 | vinay.sajip | 2007-01-16 10:50:07 +0100 (Tue, 16 Jan 2007) | 1 line Updated rotating file handlers to use _open(). ........ r53459 | marc-andre.lemburg | 2007-01-16 14:03:06 +0100 (Tue, 16 Jan 2007) | 2 lines Add news items for the recent pybench and platform changes. ........ r53460 | sjoerd.mullender | 2007-01-16 17:42:38 +0100 (Tue, 16 Jan 2007) | 4 lines Fixed ntpath.expandvars to not replace references to non-existing variables with nothing. Also added tests. This fixes bug #494589. ........ r53464 | neal.norwitz | 2007-01-17 07:23:51 +0100 (Wed, 17 Jan 2007) | 1 line Give Calvin Spealman access for python-dev summaries. ........ r53465 | neal.norwitz | 2007-01-17 09:37:26 +0100 (Wed, 17 Jan 2007) | 1 line Remove Calvin since he only has access to the website currently. ........ r53466 | thomas.heller | 2007-01-17 10:40:34 +0100 (Wed, 17 Jan 2007) | 2 lines Replace C++ comments with C comments. ........ r53472 | andrew.kuchling | 2007-01-17 20:55:06 +0100 (Wed, 17 Jan 2007) | 1 line [Part of bug #1599254] Add suggestion to Mailbox docs to use Maildir, and warn user to lock/unlock mailboxes when modifying them ........ r53475 | georg.brandl | 2007-01-17 22:09:04 +0100 (Wed, 17 Jan 2007) | 2 lines Bug #1637967: missing //= operator in list. ........ r53477 | georg.brandl | 2007-01-17 22:19:58 +0100 (Wed, 17 Jan 2007) | 2 lines Bug #1629125: fix wrong data type (int -> Py_ssize_t) in PyDict_Next docs. ........ r53481 | neal.norwitz | 2007-01-18 06:40:58 +0100 (Thu, 18 Jan 2007) | 1 line Try reverting part of r53145 that seems to cause the Windows buildbots to fail in test_uu.UUFileTest.test_encode ........ r53482 | fred.drake | 2007-01-18 06:42:30 +0100 (Thu, 18 Jan 2007) | 1 line add missing version entry ........ r53483 | neal.norwitz | 2007-01-18 07:20:55 +0100 (Thu, 18 Jan 2007) | 7 lines This test doesn't pass on Windows. The cause seems to be that chmod doesn't support the same funcationality as on Unix. I'm not sure if this fix is the best (or if it will even work)--it's a test to see if the buildbots start passing again. It might be better to not even run this test if it's windows (or non-posix). ........ r53488 | neal.norwitz | 2007-01-19 06:53:33 +0100 (Fri, 19 Jan 2007) | 1 line SF #1635217, Fix unbalanced paren ........ r53489 | martin.v.loewis | 2007-01-19 07:42:22 +0100 (Fri, 19 Jan 2007) | 3 lines Prefix AST symbols with _Py_. Fixes #1637022. Will backport. ........ r53497 | martin.v.loewis | 2007-01-19 19:01:38 +0100 (Fri, 19 Jan 2007) | 2 lines Add UUIDs for 2.5.1 and 2.5.2 ........ r53499 | raymond.hettinger | 2007-01-19 19:07:18 +0100 (Fri, 19 Jan 2007) | 1 line SF# 1635892: Fix docs for betavariate's input parameters . ........ r53503 | martin.v.loewis | 2007-01-20 15:05:39 +0100 (Sat, 20 Jan 2007) | 2 lines Merge 53501 and 53502 from 25 branch: Add /GS- for AMD64 and Itanium builds where missing. ........ r53504 | walter.doerwald | 2007-01-20 18:28:31 +0100 (Sat, 20 Jan 2007) | 2 lines Port test_resource.py to unittest. ........ r53505 | walter.doerwald | 2007-01-20 19:19:33 +0100 (Sat, 20 Jan 2007) | 2 lines Add argument tests an calls of resource.getrusage(). ........ r53506 | walter.doerwald | 2007-01-20 20:03:17 +0100 (Sat, 20 Jan 2007) | 2 lines resource.RUSAGE_BOTH might not exist. ........ r53507 | walter.doerwald | 2007-01-21 00:07:28 +0100 (Sun, 21 Jan 2007) | 2 lines Port test_new.py to unittest. ........ r53508 | martin.v.loewis | 2007-01-21 10:33:07 +0100 (Sun, 21 Jan 2007) | 2 lines Patch #1610575: Add support for _Bool to struct. ........ r53509 | georg.brandl | 2007-01-21 11:28:43 +0100 (Sun, 21 Jan 2007) | 3 lines Bug #1486663: don't reject keyword arguments for subclasses of builtin types. ........ r53511 | georg.brandl | 2007-01-21 11:35:10 +0100 (Sun, 21 Jan 2007) | 2 lines Patch #1627441: close sockets properly in urllib2. ........ r53517 | georg.brandl | 2007-01-22 20:40:21 +0100 (Mon, 22 Jan 2007) | 3 lines Use new email module names (#1637162, #1637159, #1637157). ........ r53518 | andrew.kuchling | 2007-01-22 21:26:40 +0100 (Mon, 22 Jan 2007) | 1 line Improve pattern used for mbox 'From' lines; add a simple test ........ r53519 | andrew.kuchling | 2007-01-22 21:27:50 +0100 (Mon, 22 Jan 2007) | 1 line Make comment match the code ........ r53522 | georg.brandl | 2007-01-22 22:10:33 +0100 (Mon, 22 Jan 2007) | 2 lines Bug #1249573: fix rfc822.parsedate not accepting a certain date format ........ r53524 | georg.brandl | 2007-01-22 22:23:41 +0100 (Mon, 22 Jan 2007) | 2 lines Bug #1627316: handle error in condition/ignore pdb commands more gracefully. ........ r53526 | lars.gustaebel | 2007-01-23 12:17:33 +0100 (Tue, 23 Jan 2007) | 4 lines Patch #1507247: tarfile.py: use current umask for intermediate directories. ........ r53527 | thomas.wouters | 2007-01-23 14:42:00 +0100 (Tue, 23 Jan 2007) | 13 lines SF patch #1630975: Fix crash when replacing sys.stdout in sitecustomize When running the interpreter in an environment that would cause it to set stdout/stderr/stdin's encoding, having a sitecustomize that would replace them with something other than PyFile objects would crash the interpreter. Fix it by simply ignoring the encoding-setting for non-files. This could do with a test, but I can think of no maintainable and portable way to test this bug, short of adding a sitecustomize.py to the buildsystem and have it always run with it (hmmm....) ........ r53528 | thomas.wouters | 2007-01-23 14:50:49 +0100 (Tue, 23 Jan 2007) | 4 lines Add news entry about last checkin (oops.) ........ r53531 | martin.v.loewis | 2007-01-23 22:11:47 +0100 (Tue, 23 Jan 2007) | 4 lines Make PyTraceBack_Here use the current thread, not the frame's thread state. Fixes #1579370. Will backport. ........ r53535 | brett.cannon | 2007-01-24 00:21:22 +0100 (Wed, 24 Jan 2007) | 5 lines Fix crasher for when an object's __del__ creates a new weakref to itself. Patch only fixes new-style classes; classic classes still buggy. Closes bug #1377858. Already backported. ........ r53536 | walter.doerwald | 2007-01-24 01:42:19 +0100 (Wed, 24 Jan 2007) | 2 lines Port test_popen.py to unittest. ........ Modified: python/branches/p3yk/Doc/api/concrete.tex ============================================================================== --- python/branches/p3yk/Doc/api/concrete.tex (original) +++ python/branches/p3yk/Doc/api/concrete.tex Thu Feb 1 19:02:27 2007 @@ -2082,7 +2082,7 @@ \begin{verbatim} PyObject *key, *value; -int pos = 0; +Py_ssize_t pos = 0; while (PyDict_Next(self->dict, &pos, &key, &value)) { /* do something interesting with the values... */ @@ -2097,7 +2097,7 @@ \begin{verbatim} PyObject *key, *value; -int pos = 0; +Py_ssize_t pos = 0; while (PyDict_Next(self->dict, &pos, &key, &value)) { int i = PyInt_AS_LONG(value) + 1; Modified: python/branches/p3yk/Doc/commontex/license.tex ============================================================================== --- python/branches/p3yk/Doc/commontex/license.tex (original) +++ python/branches/p3yk/Doc/commontex/license.tex Thu Feb 1 19:02:27 2007 @@ -50,6 +50,7 @@ \linev{2.4.1}{2.4}{2005}{PSF}{yes} \linev{2.4.2}{2.4.1}{2005}{PSF}{yes} \linev{2.4.3}{2.4.2}{2006}{PSF}{yes} + \linev{2.4.4}{2.4.3}{2006}{PSF}{yes} \linev{2.5}{2.4}{2006}{PSF}{yes} \end{tablev} Modified: python/branches/p3yk/Doc/dist/dist.tex ============================================================================== --- python/branches/p3yk/Doc/dist/dist.tex (original) +++ python/branches/p3yk/Doc/dist/dist.tex Thu Feb 1 19:02:27 2007 @@ -692,7 +692,7 @@ \begin{tableii}{l|l}{code}{Provides Expression}{Explanation} \lineii{mypkg} {Provide \code{mypkg}, using the distribution version} - \lineii{mypkg (1.1} {Provide \code{mypkg} version 1.1, regardless of the + \lineii{mypkg (1.1)} {Provide \code{mypkg} version 1.1, regardless of the distribution version} \end{tableii} Modified: python/branches/p3yk/Doc/lib/libmailbox.tex ============================================================================== --- python/branches/p3yk/Doc/lib/libmailbox.tex (original) +++ python/branches/p3yk/Doc/lib/libmailbox.tex Thu Feb 1 19:02:27 2007 @@ -25,22 +25,29 @@ A mailbox, which may be inspected and modified. \end{classdesc*} +The \class{Mailbox} class defines an interface and +is not intended to be instantiated. Instead, format-specific +subclasses should inherit from \class{Mailbox} and your code +should instantiate a particular subclass. + The \class{Mailbox} interface is dictionary-like, with small keys -corresponding to messages. Keys are issued by the \class{Mailbox} instance -with which they will be used and are only meaningful to that \class{Mailbox} -instance. A key continues to identify a message even if the corresponding -message is modified, such as by replacing it with another message. Messages may -be added to a \class{Mailbox} instance using the set-like method -\method{add()} and removed using a \code{del} statement or the set-like methods -\method{remove()} and \method{discard()}. +corresponding to messages. Keys are issued by the \class{Mailbox} +instance with which they will be used and are only meaningful to that +\class{Mailbox} instance. A key continues to identify a message even +if the corresponding message is modified, such as by replacing it with +another message. + +Messages may be added to a \class{Mailbox} instance using the set-like +method \method{add()} and removed using a \code{del} statement or the +set-like methods \method{remove()} and \method{discard()}. \class{Mailbox} interface semantics differ from dictionary semantics in some -noteworthy ways. Each time a message is requested, a new representation -(typically a \class{Message} instance) is generated, based upon the current -state of the mailbox. Similarly, when a message is added to a \class{Mailbox} -instance, the provided message representation's contents are copied. In neither -case is a reference to the message representation kept by the \class{Mailbox} -instance. +noteworthy ways. Each time a message is requested, a new +representation (typically a \class{Message} instance) is generated +based upon the current state of the mailbox. Similarly, when a message +is added to a \class{Mailbox} instance, the provided message +representation's contents are copied. In neither case is a reference +to the message representation kept by the \class{Mailbox} instance. The default \class{Mailbox} iterator iterates over message representations, not keys as the default dictionary iterator does. Moreover, modification of a @@ -51,9 +58,14 @@ \exception{KeyError} exception if the corresponding message is subsequently removed. -\class{Mailbox} itself is intended to define an interface and to be inherited -from by format-specific subclasses but is not intended to be instantiated. -Instead, you should instantiate a subclass. +Be very cautious when modifying mailboxes that might also be changed +by some other process. The safest mailbox format to use for such +tasks is Maildir; try to avoid using single-file formats such as mbox +for concurrent writing. If you're modifying a mailbox, no matter what +the format, you must lock it by calling the \method{lock()} and +\method{unlock()} methods before making any changes. Failing to lock +the mailbox runs the risk of losing data if some other process makes +changes to the mailbox while your Python code is running. \class{Mailbox} instances have the following methods: @@ -202,15 +214,16 @@ \begin{methoddesc}{flush}{} Write any pending changes to the filesystem. For some \class{Mailbox} -subclasses, changes are always written immediately and this method does -nothing. +subclasses, changes are always written immediately and \method{flush()} does +nothing, but you should still make a habit of calling this method. \end{methoddesc} \begin{methoddesc}{lock}{} Acquire an exclusive advisory lock on the mailbox so that other processes know not to modify it. An \exception{ExternalClashError} is raised if the lock is not available. The particular locking mechanisms used depend upon the mailbox -format. +format. You should \emph{always} lock the mailbox before making any +modifications to its contents. \end{methoddesc} \begin{methoddesc}{unlock}{} @@ -1373,36 +1386,55 @@ \begin{verbatim} import mailbox destination = mailbox.MH('~/Mail') +destination.lock() for message in mailbox.Babyl('~/RMAIL'): destination.add(MHMessage(message)) +destination.flush() +destination.unlock() \end{verbatim} -An example of sorting mail from numerous mailing lists, being careful to avoid -mail corruption due to concurrent modification by other programs, mail loss due -to interruption of the program, or premature termination due to malformed -messages in the mailbox: +This example sorts mail from several mailing lists into different +mailboxes, being careful to avoid mail corruption due to concurrent +modification by other programs, mail loss due to interruption of the +program, or premature termination due to malformed messages in the +mailbox: \begin{verbatim} import mailbox import email.Errors + list_names = ('python-list', 'python-dev', 'python-bugs') + boxes = dict((name, mailbox.mbox('~/email/%s' % name)) for name in list_names) -inbox = mailbox.Maildir('~/Maildir', None) +inbox = mailbox.Maildir('~/Maildir', factory=None) + for key in inbox.iterkeys(): try: message = inbox[key] except email.Errors.MessageParseError: continue # The message is malformed. Just leave it. + for name in list_names: list_id = message['list-id'] if list_id and name in list_id: + # Get mailbox to use box = boxes[name] + + # Write copy to disk before removing original. + # If there's a crash, you might duplicate a message, but + # that's better than losing a message completely. box.lock() box.add(message) - box.flush() # Write copy to disk before removing original. + box.flush() box.unlock() + + # Remove original message + inbox.lock() inbox.discard(key) + inbox.flush() + inbox.unlock() break # Found destination, so stop looking. + for box in boxes.itervalues(): box.close() \end{verbatim} Modified: python/branches/p3yk/Doc/lib/librandom.tex ============================================================================== --- python/branches/p3yk/Doc/lib/librandom.tex (original) +++ python/branches/p3yk/Doc/lib/librandom.tex Thu Feb 1 19:02:27 2007 @@ -185,7 +185,7 @@ \begin{funcdesc}{betavariate}{alpha, beta} Beta distribution. Conditions on the parameters are - \code{\var{alpha} > -1} and \code{\var{beta} > -1}. + \code{\var{alpha} > 0} and \code{\var{beta} > 0}. Returned values range between 0 and 1. \end{funcdesc} Modified: python/branches/p3yk/Doc/lib/libstruct.tex ============================================================================== --- python/branches/p3yk/Doc/lib/libstruct.tex (original) +++ python/branches/p3yk/Doc/lib/libstruct.tex Thu Feb 1 19:02:27 2007 @@ -50,14 +50,15 @@ \lineiv{c}{\ctype{char}}{string of length 1}{} \lineiv{b}{\ctype{signed char}}{integer}{} \lineiv{B}{\ctype{unsigned char}}{integer}{} + \lineiv{t}{\ctype{_Bool}}{bool}{(1)} \lineiv{h}{\ctype{short}}{integer}{} \lineiv{H}{\ctype{unsigned short}}{integer}{} \lineiv{i}{\ctype{int}}{integer}{} \lineiv{I}{\ctype{unsigned int}}{long}{} \lineiv{l}{\ctype{long}}{integer}{} \lineiv{L}{\ctype{unsigned long}}{long}{} - \lineiv{q}{\ctype{long long}}{long}{(1)} - \lineiv{Q}{\ctype{unsigned long long}}{long}{(1)} + \lineiv{q}{\ctype{long long}}{long}{(2)} + \lineiv{Q}{\ctype{unsigned long long}}{long}{(2)} \lineiv{f}{\ctype{float}}{float}{} \lineiv{d}{\ctype{double}}{float}{} \lineiv{s}{\ctype{char[]}}{string}{} @@ -70,6 +71,11 @@ \begin{description} \item[(1)] + The \character{t} conversion code corresponds to the \ctype{_Bool} type + defined by C99. If this type is not available, it is simulated using a + \ctype{char}. In standard mode, it is always represented by one byte. + \versionadded{2.6} +\item[(2)] The \character{q} and \character{Q} conversion codes are available in native mode only if the platform C compiler supports C \ctype{long long}, or, on Windows, \ctype{__int64}. They are always available in standard @@ -118,6 +124,12 @@ meaning a Python long integer will be used to hold the pointer; other platforms use 32-bit pointers and will use a Python integer. +For the \character{t} format character, the return value is either +\constant{True} or \constant{False}. When packing, the truth value +of the argument object is used. Either 0 or 1 in the native or standard +bool representation will be packed, and any non-zero value will be True +when unpacking. + By default, C numbers are represented in the machine's native format and byte order, and properly aligned by skipping pad bytes if necessary (according to the rules used by the C compiler). @@ -151,6 +163,7 @@ \ctype{long long} (\ctype{__int64} on Windows) is 8 bytes; \ctype{float} and \ctype{double} are 32-bit and 64-bit IEEE floating point numbers, respectively. +\ctype{_Bool} is 1 byte. Note the difference between \character{@} and \character{=}: both use native byte order, but the size and alignment of the latter is Modified: python/branches/p3yk/Doc/lib/libtime.tex ============================================================================== --- python/branches/p3yk/Doc/lib/libtime.tex (original) +++ python/branches/p3yk/Doc/lib/libtime.tex Thu Feb 1 19:02:27 2007 @@ -324,6 +324,12 @@ it is platform-specific except for recognizing UTC and GMT which are always known (and are considered to be non-daylight savings timezones). + +Only the directives specified in the documentation are supported. Because +\code{strftime()} is implemented per platform it can sometimes offer more +directives than those listed. But \code{strptime()} is independent of any +platform and thus does not necessarily support all directives available that +are not documented as supported. \end{funcdesc} \begin{datadesc}{struct_time} Modified: python/branches/p3yk/Doc/ref/ref3.tex ============================================================================== --- python/branches/p3yk/Doc/ref/ref3.tex (original) +++ python/branches/p3yk/Doc/ref/ref3.tex Thu Feb 1 19:02:27 2007 @@ -1997,8 +1997,8 @@ \methodline[numeric object]{__ixor__}{self, other} \methodline[numeric object]{__ior__}{self, other} These methods are called to implement the augmented arithmetic -operations (\code{+=}, \code{-=}, \code{*=}, \code{/=}, \code{\%=}, -\code{**=}, \code{<<=}, \code{>>=}, \code{\&=}, +operations (\code{+=}, \code{-=}, \code{*=}, \code{/=}, \code{//=}, +\code{\%=}, \code{**=}, \code{<<=}, \code{>>=}, \code{\&=}, \code{\textasciicircum=}, \code{|=}). These methods should attempt to do the operation in-place (modifying \var{self}) and return the result (which could be, but does not have to be, \var{self}). If a specific method Modified: python/branches/p3yk/Include/Python-ast.h ============================================================================== --- python/branches/p3yk/Include/Python-ast.h (original) +++ python/branches/p3yk/Include/Python-ast.h Thu Feb 1 19:02:27 2007 @@ -366,97 +366,157 @@ }; -mod_ty Module(asdl_seq * body, PyArena *arena); -mod_ty Interactive(asdl_seq * body, PyArena *arena); -mod_ty Expression(expr_ty body, PyArena *arena); -mod_ty Suite(asdl_seq * body, PyArena *arena); -stmt_ty FunctionDef(identifier name, arguments_ty args, asdl_seq * body, - asdl_seq * decorators, expr_ty returns, int lineno, int - col_offset, PyArena *arena); -stmt_ty ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int - lineno, int col_offset, PyArena *arena); -stmt_ty Return(expr_ty value, int lineno, int col_offset, PyArena *arena); -stmt_ty Delete(asdl_seq * targets, int lineno, int col_offset, PyArena *arena); -stmt_ty Assign(asdl_seq * targets, expr_ty value, int lineno, int col_offset, - PyArena *arena); -stmt_ty AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, - int col_offset, PyArena *arena); -stmt_ty Print(expr_ty dest, asdl_seq * values, bool nl, int lineno, int - col_offset, PyArena *arena); -stmt_ty For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, - int lineno, int col_offset, PyArena *arena); -stmt_ty While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int - col_offset, PyArena *arena); -stmt_ty If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int - col_offset, PyArena *arena); -stmt_ty With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body, int - lineno, int col_offset, PyArena *arena); -stmt_ty Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, int - col_offset, PyArena *arena); -stmt_ty TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int - lineno, int col_offset, PyArena *arena); -stmt_ty TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int +#define Module(a0, a1) _Py_Module(a0, a1) +mod_ty _Py_Module(asdl_seq * body, PyArena *arena); +#define Interactive(a0, a1) _Py_Interactive(a0, a1) +mod_ty _Py_Interactive(asdl_seq * body, PyArena *arena); +#define Expression(a0, a1) _Py_Expression(a0, a1) +mod_ty _Py_Expression(expr_ty body, PyArena *arena); +#define Suite(a0, a1) _Py_Suite(a0, a1) +mod_ty _Py_Suite(asdl_seq * body, PyArena *arena); +#define FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body, + asdl_seq * decorators, expr_ty returns, int lineno, int + col_offset, PyArena *arena); +#define ClassDef(a0, a1, a2, a3, a4, a5) _Py_ClassDef(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int + lineno, int col_offset, PyArena *arena); +#define Return(a0, a1, a2, a3) _Py_Return(a0, a1, a2, a3) +stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define Delete(a0, a1, a2, a3) _Py_Delete(a0, a1, a2, a3) +stmt_ty _Py_Delete(asdl_seq * targets, int lineno, int col_offset, PyArena + *arena); +#define Assign(a0, a1, a2, a3, a4) _Py_Assign(a0, a1, a2, a3, a4) +stmt_ty _Py_Assign(asdl_seq * targets, expr_ty value, int lineno, int col_offset, PyArena *arena); -stmt_ty Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, PyArena - *arena); -stmt_ty Import(asdl_seq * names, int lineno, int col_offset, PyArena *arena); -stmt_ty ImportFrom(identifier module, asdl_seq * names, int level, int lineno, - int col_offset, PyArena *arena); -stmt_ty Global(asdl_seq * names, int lineno, int col_offset, PyArena *arena); -stmt_ty Expr(expr_ty value, int lineno, int col_offset, PyArena *arena); -stmt_ty Pass(int lineno, int col_offset, PyArena *arena); -stmt_ty Break(int lineno, int col_offset, PyArena *arena); -stmt_ty Continue(int lineno, int col_offset, PyArena *arena); -expr_ty BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, - PyArena *arena); -expr_ty BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int - col_offset, PyArena *arena); -expr_ty UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, - PyArena *arena); -expr_ty Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, - PyArena *arena); -expr_ty IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int - col_offset, PyArena *arena); -expr_ty Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset, - PyArena *arena); -expr_ty Set(asdl_seq * elts, int lineno, int col_offset, PyArena *arena); -expr_ty ListComp(expr_ty elt, asdl_seq * generators, int lineno, int +#define AugAssign(a0, a1, a2, a3, a4, a5) _Py_AugAssign(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int + lineno, int col_offset, PyArena *arena); +#define Print(a0, a1, a2, a3, a4, a5) _Py_Print(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Print(expr_ty dest, asdl_seq * values, bool nl, int lineno, int + col_offset, PyArena *arena); +#define For(a0, a1, a2, a3, a4, a5, a6) _Py_For(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * + orelse, int lineno, int col_offset, PyArena *arena); +#define While(a0, a1, a2, a3, a4, a5) _Py_While(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, + int col_offset, PyArena *arena); +#define If(a0, a1, a2, a3, a4, a5) _Py_If(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, + int col_offset, PyArena *arena); +#define With(a0, a1, a2, a3, a4, a5) _Py_With(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body, + int lineno, int col_offset, PyArena *arena); +#define Raise(a0, a1, a2, a3, a4, a5) _Py_Raise(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, int + col_offset, PyArena *arena); +#define TryExcept(a0, a1, a2, a3, a4, a5) _Py_TryExcept(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, + int lineno, int col_offset, PyArena *arena); +#define TryFinally(a0, a1, a2, a3, a4) _Py_TryFinally(a0, a1, a2, a3, a4) +stmt_ty _Py_TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int + col_offset, PyArena *arena); +#define Assert(a0, a1, a2, a3, a4) _Py_Assert(a0, a1, a2, a3, a4) +stmt_ty _Py_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, + PyArena *arena); +#define Import(a0, a1, a2, a3) _Py_Import(a0, a1, a2, a3) +stmt_ty _Py_Import(asdl_seq * names, int lineno, int col_offset, PyArena + *arena); +#define ImportFrom(a0, a1, a2, a3, a4, a5) _Py_ImportFrom(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_ImportFrom(identifier module, asdl_seq * names, int level, int + lineno, int col_offset, PyArena *arena); +#define Global(a0, a1, a2, a3) _Py_Global(a0, a1, a2, a3) +stmt_ty _Py_Global(asdl_seq * names, int lineno, int col_offset, PyArena + *arena); +#define Expr(a0, a1, a2, a3) _Py_Expr(a0, a1, a2, a3) +stmt_ty _Py_Expr(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define Pass(a0, a1, a2) _Py_Pass(a0, a1, a2) +stmt_ty _Py_Pass(int lineno, int col_offset, PyArena *arena); +#define Break(a0, a1, a2) _Py_Break(a0, a1, a2) +stmt_ty _Py_Break(int lineno, int col_offset, PyArena *arena); +#define Continue(a0, a1, a2) _Py_Continue(a0, a1, a2) +stmt_ty _Py_Continue(int lineno, int col_offset, PyArena *arena); +#define BoolOp(a0, a1, a2, a3, a4) _Py_BoolOp(a0, a1, a2, a3, a4) +expr_ty _Py_BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, + PyArena *arena); +#define BinOp(a0, a1, a2, a3, a4, a5) _Py_BinOp(a0, a1, a2, a3, a4, a5) +expr_ty _Py_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int + col_offset, PyArena *arena); +#define UnaryOp(a0, a1, a2, a3, a4) _Py_UnaryOp(a0, a1, a2, a3, a4) +expr_ty _Py_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, + PyArena *arena); +#define Lambda(a0, a1, a2, a3, a4) _Py_Lambda(a0, a1, a2, a3, a4) +expr_ty _Py_Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, + PyArena *arena); +#define IfExp(a0, a1, a2, a3, a4, a5) _Py_IfExp(a0, a1, a2, a3, a4, a5) +expr_ty _Py_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int + col_offset, PyArena *arena); +#define Dict(a0, a1, a2, a3, a4) _Py_Dict(a0, a1, a2, a3, a4) +expr_ty _Py_Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset, PyArena *arena); -expr_ty GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int +#define Set(a0, a1, a2, a3) _Py_Set(a0, a1, a2, a3) +expr_ty _Py_Set(asdl_seq * elts, int lineno, int col_offset, PyArena *arena); +#define ListComp(a0, a1, a2, a3, a4) _Py_ListComp(a0, a1, a2, a3, a4) +expr_ty _Py_ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, PyArena *arena); -expr_ty Yield(expr_ty value, int lineno, int col_offset, PyArena *arena); -expr_ty Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int - lineno, int col_offset, PyArena *arena); -expr_ty Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty - starargs, expr_ty kwargs, int lineno, int col_offset, PyArena - *arena); -expr_ty Num(object n, int lineno, int col_offset, PyArena *arena); -expr_ty Str(string s, int lineno, int col_offset, PyArena *arena); -expr_ty Ellipsis(int lineno, int col_offset, PyArena *arena); -expr_ty Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int - lineno, int col_offset, PyArena *arena); -expr_ty Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int - lineno, int col_offset, PyArena *arena); -expr_ty Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, - PyArena *arena); -expr_ty List(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, - PyArena *arena); -expr_ty Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, - PyArena *arena); -slice_ty Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena); -slice_ty ExtSlice(asdl_seq * dims, PyArena *arena); -slice_ty Index(expr_ty value, PyArena *arena); -comprehension_ty comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, - PyArena *arena); -excepthandler_ty excepthandler(expr_ty type, identifier name, asdl_seq * body, - int lineno, int col_offset, PyArena *arena); -arguments_ty arguments(asdl_seq * args, identifier vararg, expr_ty - varargannotation, asdl_seq * kwonlyargs, identifier - kwarg, expr_ty kwargannotation, asdl_seq * defaults, - asdl_seq * kw_defaults, PyArena *arena); -arg_ty SimpleArg(identifier arg, expr_ty annotation, PyArena *arena); -arg_ty NestedArgs(asdl_seq * args, PyArena *arena); -keyword_ty keyword(identifier arg, expr_ty value, PyArena *arena); -alias_ty alias(identifier name, identifier asname, PyArena *arena); +#define GeneratorExp(a0, a1, a2, a3, a4) _Py_GeneratorExp(a0, a1, a2, a3, a4) +expr_ty _Py_GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int + col_offset, PyArena *arena); +#define Yield(a0, a1, a2, a3) _Py_Yield(a0, a1, a2, a3) +expr_ty _Py_Yield(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define Compare(a0, a1, a2, a3, a4, a5) _Py_Compare(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, + int lineno, int col_offset, PyArena *arena); +#define Call(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Call(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty + starargs, expr_ty kwargs, int lineno, int col_offset, PyArena + *arena); +#define Num(a0, a1, a2, a3) _Py_Num(a0, a1, a2, a3) +expr_ty _Py_Num(object n, int lineno, int col_offset, PyArena *arena); +#define Str(a0, a1, a2, a3) _Py_Str(a0, a1, a2, a3) +expr_ty _Py_Str(string s, int lineno, int col_offset, PyArena *arena); +#define Ellipsis(a0, a1, a2) _Py_Ellipsis(a0, a1, a2) +expr_ty _Py_Ellipsis(int lineno, int col_offset, PyArena *arena); +#define Attribute(a0, a1, a2, a3, a4, a5) _Py_Attribute(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int + lineno, int col_offset, PyArena *arena); +#define Subscript(a0, a1, a2, a3, a4, a5) _Py_Subscript(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int + lineno, int col_offset, PyArena *arena); +#define Name(a0, a1, a2, a3, a4) _Py_Name(a0, a1, a2, a3, a4) +expr_ty _Py_Name(identifier id, expr_context_ty ctx, int lineno, int + col_offset, PyArena *arena); +#define List(a0, a1, a2, a3, a4) _Py_List(a0, a1, a2, a3, a4) +expr_ty _Py_List(asdl_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, PyArena *arena); +#define Tuple(a0, a1, a2, a3, a4) _Py_Tuple(a0, a1, a2, a3, a4) +expr_ty _Py_Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, PyArena *arena); +#define Slice(a0, a1, a2, a3) _Py_Slice(a0, a1, a2, a3) +slice_ty _Py_Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena); +#define ExtSlice(a0, a1) _Py_ExtSlice(a0, a1) +slice_ty _Py_ExtSlice(asdl_seq * dims, PyArena *arena); +#define Index(a0, a1) _Py_Index(a0, a1) +slice_ty _Py_Index(expr_ty value, PyArena *arena); +#define comprehension(a0, a1, a2, a3) _Py_comprehension(a0, a1, a2, a3) +comprehension_ty _Py_comprehension(expr_ty target, expr_ty iter, asdl_seq * + ifs, PyArena *arena); +#define excepthandler(a0, a1, a2, a3, a4, a5) _Py_excepthandler(a0, a1, a2, a3, a4, a5) +excepthandler_ty _Py_excepthandler(expr_ty type, identifier name, asdl_seq * + body, int lineno, int col_offset, PyArena + *arena); +#define arguments(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_arguments(a0, a1, a2, a3, a4, a5, a6, a7, a8) +arguments_ty _Py_arguments(asdl_seq * args, identifier vararg, expr_ty + varargannotation, asdl_seq * kwonlyargs, identifier + kwarg, expr_ty kwargannotation, asdl_seq * defaults, + asdl_seq * kw_defaults, PyArena *arena); +#define SimpleArg(a0, a1, a2) _Py_SimpleArg(a0, a1, a2) +arg_ty _Py_SimpleArg(identifier arg, expr_ty annotation, PyArena *arena); +#define NestedArgs(a0, a1) _Py_NestedArgs(a0, a1) +arg_ty _Py_NestedArgs(asdl_seq * args, PyArena *arena); +#define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2) +keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena); +#define alias(a0, a1, a2) _Py_alias(a0, a1, a2) +alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena); PyObject* PyAST_mod2obj(mod_ty t); Modified: python/branches/p3yk/Include/object.h ============================================================================== --- python/branches/p3yk/Include/object.h (original) +++ python/branches/p3yk/Include/object.h Thu Feb 1 19:02:27 2007 @@ -368,7 +368,7 @@ /* Generic operations on objects */ PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); -PyAPI_FUNC(void) _Py_Break(void); +PyAPI_FUNC(void) _Py_BreakPoint(void); PyAPI_FUNC(void) _PyObject_Dump(PyObject *); PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *); PyAPI_FUNC(PyObject *) _PyObject_Str(PyObject *); Modified: python/branches/p3yk/Lib/logging/handlers.py ============================================================================== --- python/branches/p3yk/Lib/logging/handlers.py (original) +++ python/branches/p3yk/Lib/logging/handlers.py Thu Feb 1 19:02:27 2007 @@ -1,4 +1,4 @@ -# Copyright 2001-2005 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2007 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -22,7 +22,7 @@ Should work under Python versions >= 1.5.2, except that source line information is not available unless 'sys._getframe()' is. -Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2007 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ @@ -135,10 +135,8 @@ os.remove(dfn) os.rename(self.baseFilename, dfn) #print "%s -> %s" % (self.baseFilename, dfn) - if self.encoding: - self.stream = codecs.open(self.baseFilename, 'w', self.encoding) - else: - self.stream = open(self.baseFilename, 'w') + self.mode = 'w' + self.stream = self._open() def shouldRollover(self, record): """ @@ -281,10 +279,8 @@ s.sort() os.remove(s[0]) #print "%s -> %s" % (self.baseFilename, dfn) - if self.encoding: - self.stream = codecs.open(self.baseFilename, 'w', self.encoding) - else: - self.stream = open(self.baseFilename, 'w') + self.mode = 'w' + self.stream = self._open() self.rolloverAt = self.rolloverAt + self.interval class WatchedFileHandler(logging.FileHandler): @@ -786,7 +782,7 @@ try: import smtplib try: - from email.Utils import formatdate + from email.utils import formatdate except ImportError: formatdate = self.date_time port = self.mailport Modified: python/branches/p3yk/Lib/mailbox.py ============================================================================== --- python/branches/p3yk/Lib/mailbox.py (original) +++ python/branches/p3yk/Lib/mailbox.py Thu Feb 1 19:02:27 2007 @@ -16,8 +16,8 @@ import errno import copy import email -import email.Message -import email.Generator +import email.message +import email.generator import rfc822 import StringIO try: @@ -193,9 +193,9 @@ # To get native line endings on disk, the user-friendly \n line endings # used in strings and by email.Message are translated here. """Dump message contents to target file.""" - if isinstance(message, email.Message.Message): + if isinstance(message, email.message.Message): buffer = StringIO.StringIO() - gen = email.Generator.Generator(buffer, mangle_from_, 0) + gen = email.generator.Generator(buffer, mangle_from_, 0) gen.flatten(message) buffer.seek(0) target.write(buffer.read().replace('\n', os.linesep)) @@ -704,7 +704,7 @@ message = '' elif isinstance(message, _mboxMMDFMessage): from_line = 'From ' + message.get_from() - elif isinstance(message, email.Message.Message): + elif isinstance(message, email.message.Message): from_line = message.get_unixfrom() # May be None. if from_line is None: from_line = 'From MAILER-DAEMON %s' % time.asctime(time.gmtime()) @@ -1254,9 +1254,9 @@ self._file.write(os.linesep) else: self._file.write('1,,' + os.linesep) - if isinstance(message, email.Message.Message): + if isinstance(message, email.message.Message): orig_buffer = StringIO.StringIO() - orig_generator = email.Generator.Generator(orig_buffer, False, 0) + orig_generator = email.generator.Generator(orig_buffer, False, 0) orig_generator.flatten(message) orig_buffer.seek(0) while True: @@ -1267,7 +1267,7 @@ self._file.write('*** EOOH ***' + os.linesep) if isinstance(message, BabylMessage): vis_buffer = StringIO.StringIO() - vis_generator = email.Generator.Generator(vis_buffer, False, 0) + vis_generator = email.generator.Generator(vis_buffer, False, 0) vis_generator.flatten(message.get_visible()) while True: line = vis_buffer.readline() @@ -1323,12 +1323,12 @@ return (start, stop) -class Message(email.Message.Message): +class Message(email.message.Message): """Message with mailbox-format-specific properties.""" def __init__(self, message=None): """Initialize a Message instance.""" - if isinstance(message, email.Message.Message): + if isinstance(message, email.message.Message): self._become_message(copy.deepcopy(message)) if isinstance(message, Message): message._explain_to(self) @@ -1337,7 +1337,7 @@ elif hasattr(message, "read"): self._become_message(email.message_from_file(message)) elif message is None: - email.Message.Message.__init__(self) + email.message.Message.__init__(self) else: raise TypeError('Invalid message type: %s' % type(message)) @@ -1468,7 +1468,7 @@ def __init__(self, message=None): """Initialize an mboxMMDFMessage instance.""" self.set_from('MAILER-DAEMON', True) - if isinstance(message, email.Message.Message): + if isinstance(message, email.message.Message): unixfrom = message.get_unixfrom() if unixfrom is not None and unixfrom.startswith('From '): self.set_from(unixfrom[5:]) @@ -1990,10 +1990,12 @@ # that the two characters preceding "From " are \n\n or the beginning of # the file. Fixing this would require a more extensive rewrite than is # necessary. For convenience, we've added a PortableUnixMailbox class - # which uses the more lenient _fromlinepattern regular expression. + # which does no checking of the format of the 'From' line. - _fromlinepattern = r"From \s*[^\s]+\s+\w\w\w\s+\w\w\w\s+\d?\d\s+" \ - r"\d?\d:\d\d(:\d\d)?(\s+[^\s]+)?\s+\d\d\d\d\s*$" + _fromlinepattern = (r"From \s*[^\s]+\s+\w\w\w\s+\w\w\w\s+\d?\d\s+" + r"\d?\d:\d\d(:\d\d)?(\s+[^\s]+)?\s+\d\d\d\d\s*" + r"[^\s]*\s*" + "$") _regexp = None def _strict_isrealfromline(self, line): Modified: python/branches/p3yk/Lib/ntpath.py ============================================================================== --- python/branches/p3yk/Lib/ntpath.py (original) +++ python/branches/p3yk/Lib/ntpath.py Thu Feb 1 19:02:27 2007 @@ -344,8 +344,10 @@ var = path[:index] if var in os.environ: res = res + os.environ[var] + else: + res = res + '${' + var + '}' except ValueError: - res = res + path + res = res + '${' + path index = pathlen - 1 else: var = '' @@ -357,8 +359,10 @@ c = path[index:index + 1] if var in os.environ: res = res + os.environ[var] + else: + res = res + '$' + var if c != '': - res = res + c + index = index - 1 else: res = res + c index = index + 1 Modified: python/branches/p3yk/Lib/pdb.py ============================================================================== --- python/branches/p3yk/Lib/pdb.py (original) +++ python/branches/p3yk/Lib/pdb.py Thu Feb 1 19:02:27 2007 @@ -479,7 +479,12 @@ def do_condition(self, arg): # arg is breakpoint number and condition args = arg.split(' ', 1) - bpnum = int(args[0].strip()) + try: + bpnum = int(args[0].strip()) + except ValueError: + # something went wrong + print >>self.stdout, \ + 'Breakpoint index %r is not a number' % args[0] try: cond = args[1] except: @@ -494,7 +499,12 @@ def do_ignore(self,arg): """arg is bp number followed by ignore count.""" args = arg.split() - bpnum = int(args[0].strip()) + try: + bpnum = int(args[0].strip()) + except ValueError: + # something went wrong + print >>self.stdout, \ + 'Breakpoint index %r is not a number' % args[0] try: count = int(args[1].strip()) except: Modified: python/branches/p3yk/Lib/random.py ============================================================================== --- python/branches/p3yk/Lib/random.py (original) +++ python/branches/p3yk/Lib/random.py Thu Feb 1 19:02:27 2007 @@ -569,7 +569,7 @@ def betavariate(self, alpha, beta): """Beta distribution. - Conditions on the parameters are alpha > -1 and beta} > -1. + Conditions on the parameters are alpha > 0 and beta > 0. Returned values range between 0 and 1. """ Modified: python/branches/p3yk/Lib/rfc822.py ============================================================================== --- python/branches/p3yk/Lib/rfc822.py (original) +++ python/branches/p3yk/Lib/rfc822.py Thu Feb 1 19:02:27 2007 @@ -850,6 +850,11 @@ if data[0][-1] in (',', '.') or data[0].lower() in _daynames: # There's a dayname here. Skip it del data[0] + else: + # no space after the "weekday,"? + i = data[0].rfind(',') + if i >= 0: + data[0] = data[0][i+1:] if len(data) == 3: # RFC 850 date, deprecated stuff = data[0].split('-') if len(stuff) == 3: Modified: python/branches/p3yk/Lib/smtplib.py ============================================================================== --- python/branches/p3yk/Lib/smtplib.py (original) +++ python/branches/p3yk/Lib/smtplib.py Thu Feb 1 19:02:27 2007 @@ -43,10 +43,10 @@ import socket import re -import email.Utils +import email.utils import base64 import hmac -from email.base64MIME import encode as encode_base64 +from email.base64mime import encode as encode_base64 from sys import stderr __all__ = ["SMTPException","SMTPServerDisconnected","SMTPResponseException", @@ -172,7 +172,7 @@ """ m = (None, None) try: - m = email.Utils.parseaddr(addr)[1] + m = email.utils.parseaddr(addr)[1] except AttributeError: pass if m == (None, None): # Indicates parse failure or AttributeError Modified: python/branches/p3yk/Lib/socket.py ============================================================================== --- python/branches/p3yk/Lib/socket.py (original) +++ python/branches/p3yk/Lib/socket.py Thu Feb 1 19:02:27 2007 @@ -204,9 +204,10 @@ __slots__ = ["mode", "bufsize", "softspace", # "closed" is a property, see below - "_sock", "_rbufsize", "_wbufsize", "_rbuf", "_wbuf"] + "_sock", "_rbufsize", "_wbufsize", "_rbuf", "_wbuf", + "_close"] - def __init__(self, sock, mode='rb', bufsize=-1): + def __init__(self, sock, mode='rb', bufsize=-1, close=False): self._sock = sock self.mode = mode # Not actually used in this version if bufsize < 0: @@ -222,6 +223,7 @@ self._wbufsize = bufsize self._rbuf = "" # A string self._wbuf = [] # A list of strings + self._close = close def _getclosed(self): return self._sock is None @@ -232,6 +234,8 @@ if self._sock: self.flush() finally: + if self._close: + self._sock.close() self._sock = None def __del__(self): Modified: python/branches/p3yk/Lib/tarfile.py ============================================================================== --- python/branches/p3yk/Lib/tarfile.py (original) +++ python/branches/p3yk/Lib/tarfile.py Thu Feb 1 19:02:27 2007 @@ -1632,19 +1632,7 @@ # Create all upper directories. upperdirs = os.path.dirname(targetpath) if upperdirs and not os.path.exists(upperdirs): - ti = TarInfo() - ti.name = upperdirs - ti.type = DIRTYPE - ti.mode = 0777 - ti.mtime = tarinfo.mtime - ti.uid = tarinfo.uid - ti.gid = tarinfo.gid - ti.uname = tarinfo.uname - ti.gname = tarinfo.gname - try: - self._extract_member(ti, ti.name) - except: - pass + os.makedirs(upperdirs) if tarinfo.islnk() or tarinfo.issym(): self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname)) Modified: python/branches/p3yk/Lib/test/crashers/weakref_in_del.py ============================================================================== --- python/branches/p3yk/Lib/test/crashers/weakref_in_del.py (original) +++ python/branches/p3yk/Lib/test/crashers/weakref_in_del.py Thu Feb 1 19:02:27 2007 @@ -1,11 +1,12 @@ import weakref # http://python.org/sf/1377858 +# Fixed for new-style classes in 2.5c1. ref = None def test_weakref_in_del(): - class Target(object): + class Target(): def __del__(self): global ref ref = weakref.ref(self) Deleted: /python/branches/p3yk/Lib/test/output/test_new ============================================================================== --- /python/branches/p3yk/Lib/test/output/test_new Thu Feb 1 19:02:27 2007 +++ (empty file) @@ -1,6 +0,0 @@ -test_new -new.module() -new.classobj() -new.instancemethod() -new.function() -new.code() Deleted: /python/branches/p3yk/Lib/test/output/test_popen ============================================================================== --- /python/branches/p3yk/Lib/test/output/test_popen Thu Feb 1 19:02:27 2007 +++ (empty file) @@ -1,3 +0,0 @@ -test_popen -Test popen: -popen seemed to process the command-line correctly Deleted: /python/branches/p3yk/Lib/test/output/test_resource ============================================================================== --- /python/branches/p3yk/Lib/test/output/test_resource Thu Feb 1 19:02:27 2007 +++ (empty file) @@ -1,2 +0,0 @@ -test_resource -True Modified: python/branches/p3yk/Lib/test/test_array.py ============================================================================== --- python/branches/p3yk/Lib/test/test_array.py (original) +++ python/branches/p3yk/Lib/test/test_array.py Thu Feb 1 19:02:27 2007 @@ -12,6 +12,10 @@ class ArraySubclass(array.array): pass +class ArraySubclassWithKwargs(array.array): + def __init__(self, typecode, newarg=None): + array.array.__init__(typecode) + tests = [] # list to accumulate all tests typecodes = "cubBhHiIlLfd" @@ -683,6 +687,9 @@ b = array.array('B', range(64)) self.assertEqual(rc, sys.getrefcount(10)) + def test_subclass_with_kwargs(self): + # SF bug #1486663 -- this used to erroneously raise a TypeError + ArraySubclassWithKwargs('b', newarg=1) class StringTest(BaseTest): Modified: python/branches/p3yk/Lib/test/test_deque.py ============================================================================== --- python/branches/p3yk/Lib/test/test_deque.py (original) +++ python/branches/p3yk/Lib/test/test_deque.py Thu Feb 1 19:02:27 2007 @@ -486,6 +486,16 @@ d1 == d2 # not clear if this is supposed to be True or False, # but it used to give a SystemError + +class SubclassWithKwargs(deque): + def __init__(self, newarg=1): + deque.__init__(self) + +class TestSubclassWithKwargs(unittest.TestCase): + def test_subclass_with_kwargs(self): + # SF bug #1486663 -- this used to erroneously raise a TypeError + SubclassWithKwargs(newarg=1) + #============================================================================== libreftest = """ @@ -599,6 +609,7 @@ TestBasic, TestVariousIteratorArgs, TestSubclass, + TestSubclassWithKwargs, ) test_support.run_unittest(*test_classes) Modified: python/branches/p3yk/Lib/test/test_dumbdbm.py ============================================================================== --- python/branches/p3yk/Lib/test/test_dumbdbm.py (original) +++ python/branches/p3yk/Lib/test/test_dumbdbm.py Thu Feb 1 19:02:27 2007 @@ -50,11 +50,17 @@ finally: os.umask(old_umask) + expected_mode = 0635 + if os.name != 'posix': + # Windows only supports setting the read-only attribute. + # This shouldn't fail, but doesn't work like Unix either. + expected_mode = 0666 + import stat st = os.stat(_fname + '.dat') - self.assertEqual(stat.S_IMODE(st.st_mode), 0635) + self.assertEqual(stat.S_IMODE(st.st_mode), expected_mode) st = os.stat(_fname + '.dir') - self.assertEqual(stat.S_IMODE(st.st_mode), 0635) + self.assertEqual(stat.S_IMODE(st.st_mode), expected_mode) def test_close_twice(self): f = dumbdbm.open(_fname) Modified: python/branches/p3yk/Lib/test/test_itertools.py ============================================================================== --- python/branches/p3yk/Lib/test/test_itertools.py (original) +++ python/branches/p3yk/Lib/test/test_itertools.py Thu Feb 1 19:02:27 2007 @@ -744,6 +744,21 @@ self.assertRaises(AssertionError, list, cycle(gen1())) self.assertEqual(hist, [0,1]) +class SubclassWithKwargsTest(unittest.TestCase): + def test_keywords_in_subclass(self): + # count is not subclassable... + for cls in (repeat, izip, ifilter, ifilterfalse, chain, imap, + starmap, islice, takewhile, dropwhile, cycle): + class Subclass(cls): + def __init__(self, newarg=None, *args): + cls.__init__(self, *args) + try: + Subclass(newarg=1) + except TypeError as err: + # we expect type errors because of wrong argument count + self.failIf("does not take keyword arguments" in err.args[0]) + + libreftest = """ Doctest for examples in the library reference: libitertools.tex @@ -938,7 +953,8 @@ def test_main(verbose=None): test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC, - RegressionTests, LengthTransparency) + RegressionTests, LengthTransparency, + SubclassWithKwargsTest) test_support.run_unittest(*test_classes) # verify reference counting Modified: python/branches/p3yk/Lib/test/test_mailbox.py ============================================================================== --- python/branches/p3yk/Lib/test/test_mailbox.py (original) +++ python/branches/p3yk/Lib/test/test_mailbox.py Thu Feb 1 19:02:27 2007 @@ -4,7 +4,7 @@ import stat import socket import email -import email.Message +import email.message import rfc822 import re import StringIO @@ -22,7 +22,7 @@ def _check_sample(self, msg): # Inspect a mailbox.Message representation of the sample message - self.assert_(isinstance(msg, email.Message.Message)) + self.assert_(isinstance(msg, email.message.Message)) self.assert_(isinstance(msg, mailbox.Message)) for key, value in _sample_headers.iteritems(): self.assert_(value in msg.get_all(key)) @@ -30,7 +30,7 @@ self.assert_(len(msg.get_payload()) == len(_sample_payloads)) for i, payload in enumerate(_sample_payloads): part = msg.get_payload(i) - self.assert_(isinstance(part, email.Message.Message)) + self.assert_(isinstance(part, email.message.Message)) self.assert_(not isinstance(part, mailbox.Message)) self.assert_(part.get_payload() == payload) @@ -939,7 +939,7 @@ self._delete_recursively(self._path) def test_initialize_with_eMM(self): - # Initialize based on email.Message.Message instance + # Initialize based on email.message.Message instance eMM = email.message_from_string(_sample_message) msg = self._factory(eMM) self._post_initialize_hook(msg) @@ -965,7 +965,7 @@ # Initialize without arguments msg = self._factory() self._post_initialize_hook(msg) - self.assert_(isinstance(msg, email.Message.Message)) + self.assert_(isinstance(msg, email.message.Message)) self.assert_(isinstance(msg, mailbox.Message)) self.assert_(isinstance(msg, self._factory)) self.assert_(msg.keys() == []) @@ -992,7 +992,7 @@ mailbox.BabylMessage, mailbox.MMDFMessage): other_msg = class_() msg._explain_to(other_msg) - other_msg = email.Message.Message() + other_msg = email.message.Message() self.assertRaises(TypeError, lambda: msg._explain_to(other_msg)) def _post_initialize_hook(self, msg): @@ -1732,11 +1732,11 @@ def test_unix_mbox(self): ### should be better! - import email.Parser + import email.parser fname = self.createMessage("cur", True) n = 0 for msg in mailbox.PortableUnixMailbox(open(fname), - email.Parser.Parser().parse): + email.parser.Parser().parse): n += 1 self.assertEqual(msg["subject"], "Simple Test") self.assertEqual(len(str(msg)), len(FROM_)+len(DUMMY_MESSAGE)) Modified: python/branches/p3yk/Lib/test/test_new.py ============================================================================== --- python/branches/p3yk/Lib/test/test_new.py (original) +++ python/branches/p3yk/Lib/test/test_new.py Thu Feb 1 19:02:27 2007 @@ -1,180 +1,158 @@ -from test.test_support import verbose, verify, TestFailed -import sys -import new - -class Eggs: - def get_yolks(self): - return self.yolks - -print 'new.module()' -m = new.module('Spam') -if verbose: - print m -m.Eggs = Eggs -sys.modules['Spam'] = m -import Spam - -def get_more_yolks(self): - return self.yolks + 3 - -print 'new.classobj()' -C = new.classobj('Spam', (Spam.Eggs,), {'get_more_yolks': get_more_yolks}) -if verbose: - print C - -def break_yolks(self): - self.yolks = self.yolks - 2 -print 'new.instancemethod()' -c = C() -c.yolks = 3 -im = new.instancemethod(break_yolks, c, C) -if verbose: - print im - -verify(c.get_yolks() == 3 and c.get_more_yolks() == 6, - 'Broken call of hand-crafted class instance') -im() -verify(c.get_yolks() == 1 and c.get_more_yolks() == 4, - 'Broken call of hand-crafted instance method') - -im = new.instancemethod(break_yolks, c) -im() -verify(c.get_yolks() == -1) -try: - new.instancemethod(break_yolks, None) -except TypeError: - pass -else: - raise TestFailed, "dangerous instance method creation allowed" - -# Verify that instancemethod() doesn't allow keyword args -try: - new.instancemethod(break_yolks, c, kw=1) -except TypeError: - pass -else: - raise TestFailed, "instancemethod shouldn't accept keyword args" - -# It's unclear what the semantics should be for a code object compiled at -# module scope, but bound and run in a function. In CPython, `c' is global -# (by accident?) while in Jython, `c' is local. The intent of the test -# clearly is to make `c' global, so let's be explicit about it. -codestr = ''' -global c -a = 1 -b = 2 -c = a + b -''' - -ccode = compile(codestr, '', 'exec') -# Jython doesn't have a __builtins__, so use a portable alternative -import __builtin__ -g = {'c': 0, '__builtins__': __builtin__} -# this test could be more robust -print 'new.function()' -func = new.function(ccode, g) -if verbose: - print func -func() -verify(g['c'] == 3, - 'Could not create a proper function object') - -# test the various extended flavors of function.new -def f(x): - def g(y): - return x + y - return g -g = f(4) -new.function(f.func_code, {}, "blah") -g2 = new.function(g.func_code, {}, "blah", (2,), g.func_closure) -verify(g2() == 6) -g3 = new.function(g.func_code, {}, "blah", None, g.func_closure) -verify(g3(5) == 9) -def test_closure(func, closure, exc): - try: - new.function(func.func_code, {}, "", None, closure) - except exc: - pass - else: - print "corrupt closure accepted" - -test_closure(g, None, TypeError) # invalid closure -test_closure(g, (1,), TypeError) # non-cell in closure -test_closure(g, (1, 1), ValueError) # closure is wrong size -test_closure(f, g.func_closure, ValueError) # no closure needed - -print 'new.code()' -# bogus test of new.code() -# Note: Jython will never have new.code() -if hasattr(new, 'code'): - def f(a): pass - - c = f.func_code - argcount = c.co_argcount - kwonlyargcount = c.co_kwonlyargcount - nlocals = c.co_nlocals - stacksize = c.co_stacksize - flags = c.co_flags - codestring = c.co_code - constants = c.co_consts - names = c.co_names - varnames = c.co_varnames - filename = c.co_filename - name = c.co_name - firstlineno = c.co_firstlineno - lnotab = c.co_lnotab - freevars = c.co_freevars - cellvars = c.co_cellvars - - d = new.code(argcount, kwonlyargcount, - nlocals, stacksize, flags, codestring, - constants, names, varnames, filename, name, - firstlineno, lnotab, freevars, cellvars) - - # test backwards-compatibility version with no freevars or cellvars - d = new.code(argcount, kwonlyargcount, - nlocals, stacksize, flags, codestring, - constants, names, varnames, filename, name, - firstlineno, lnotab) - - try: # this used to trigger a SystemError - d = new.code(-argcount, kwonlyargcount, - nlocals, stacksize, flags, codestring, - constants, names, varnames, filename, name, - firstlineno, lnotab) - except ValueError: - pass - else: - raise TestFailed, "negative co_argcount didn't trigger an exception" - - try: # this used to trigger a SystemError - d = new.code(argcount, kwonlyargcount, - -nlocals, stacksize, flags, codestring, - constants, names, varnames, filename, name, - firstlineno, lnotab) - except ValueError: - pass - else: - raise TestFailed, "negative co_nlocals didn't trigger an exception" - - try: # this used to trigger a Py_FatalError! - d = new.code(argcount, kwonlyargcount, - nlocals, stacksize, flags, codestring, - constants, (5,), varnames, filename, name, - firstlineno, lnotab) - except TypeError: - pass - else: - raise TestFailed, "non-string co_name didn't trigger an exception" - - # new.code used to be a way to mutate a tuple... - class S(str): pass - t = (S("ab"),) - d = new.code(argcount, kwonlyargcount, - nlocals, stacksize, flags, codestring, - constants, t, varnames, filename, name, - firstlineno, lnotab) - verify(type(t[0]) is S, "eek, tuple changed under us!") +import unittest +from test import test_support +import sys, new + +class NewTest(unittest.TestCase): + def test_spam(self): + class Eggs: + def get_yolks(self): + return self.yolks + + m = new.module('Spam') + m.Eggs = Eggs + sys.modules['Spam'] = m + import Spam + + def get_more_yolks(self): + return self.yolks + 3 + + # new.classobj() + C = new.classobj('Spam', (Spam.Eggs,), {'get_more_yolks': get_more_yolks}) + + def break_yolks(self): + self.yolks = self.yolks - 2 + + # new.instancemethod() + c = C() + c.yolks = 3 + im = new.instancemethod(break_yolks, c, C) + + self.assertEqual(c.get_yolks(), 3, + 'Broken call of hand-crafted class instance') + self.assertEqual(c.get_more_yolks(), 6, + 'Broken call of hand-crafted class instance') + + im() + self.assertEqual(c.get_yolks(), 1, + 'Broken call of hand-crafted instance method') + self.assertEqual(c.get_more_yolks(), 4, + 'Broken call of hand-crafted instance method') + + im = new.instancemethod(break_yolks, c) + im() + self.assertEqual(c.get_yolks(), -1) + + # Verify that dangerous instance method creation is forbidden + self.assertRaises(TypeError, new.instancemethod, break_yolks, None) + + # Verify that instancemethod() doesn't allow keyword args + self.assertRaises(TypeError, new.instancemethod, break_yolks, c, kw=1) + + def test_scope(self): + # It's unclear what the semantics should be for a code object compiled + # at module scope, but bound and run in a function. In CPython, `c' is + # global (by accident?) while in Jython, `c' is local. The intent of + # the test clearly is to make `c' global, so let's be explicit about it. + codestr = ''' + global c + a = 1 + b = 2 + c = a + b + ''' + + codestr = "\n".join(l.strip() for l in codestr.splitlines()) + + ccode = compile(codestr, '', 'exec') + # Jython doesn't have a __builtins__, so use a portable alternative + import __builtin__ + g = {'c': 0, '__builtins__': __builtin__} + + # this test could be more robust + func = new.function(ccode, g) + func() + self.assertEqual(g['c'], 3, 'Could not create a proper function object') + + def test_function(self): + # test the various extended flavors of function.new + def f(x): + def g(y): + return x + y + return g + g = f(4) + new.function(f.func_code, {}, "blah") + g2 = new.function(g.func_code, {}, "blah", (2,), g.func_closure) + self.assertEqual(g2(), 6) + g3 = new.function(g.func_code, {}, "blah", None, g.func_closure) + self.assertEqual(g3(5), 9) + def test_closure(func, closure, exc): + self.assertRaises(exc, new.function, func.func_code, {}, "", None, closure) + + test_closure(g, None, TypeError) # invalid closure + test_closure(g, (1,), TypeError) # non-cell in closure + test_closure(g, (1, 1), ValueError) # closure is wrong size + test_closure(f, g.func_closure, ValueError) # no closure needed + + # Note: Jython will never have new.code() + if hasattr(new, 'code'): + def test_code(self): + # bogus test of new.code() + def f(a): pass + + c = f.func_code + argcount = c.co_argcount + kwonlyargcount = c.co_kwonlyargcount + nlocals = c.co_nlocals + stacksize = c.co_stacksize + flags = c.co_flags + codestring = c.co_code + constants = c.co_consts + names = c.co_names + varnames = c.co_varnames + filename = c.co_filename + name = c.co_name + firstlineno = c.co_firstlineno + lnotab = c.co_lnotab + freevars = c.co_freevars + cellvars = c.co_cellvars + + d = new.code(argcount, kwonlyargcount, nlocals, stacksize, flags, + codestring, constants, names, varnames, filename, + name, firstlineno, lnotab, freevars, cellvars) + + # test backwards-compatibility version with no freevars or cellvars + d = new.code(argcount, kwonlyargcount, nlocals, stacksize, + flags, codestring, constants, names, varnames, + filename, name, firstlineno, lnotab) + + # negative co_argcount used to trigger a SystemError + self.assertRaises(ValueError, new.code, + -argcount, kwonlyargcount, nlocals, stacksize, flags, + codestring, constants, names, varnames, filename, name, + firstlineno, lnotab) + + # negative co_nlocals used to trigger a SystemError + self.assertRaises(ValueError, new.code, + argcount, kwonlyargcount, -nlocals, stacksize, flags, + codestring, constants, names, varnames, filename, name, + firstlineno, lnotab) + + # non-string co_name used to trigger a Py_FatalError + self.assertRaises(TypeError, new.code, + argcount, kwonlyargcount, nlocals, stacksize, flags, + codestring, constants, (5,), varnames, filename, name, + firstlineno, lnotab) + + # new.code used to be a way to mutate a tuple... + class S(str): + pass + t = (S("ab"),) + d = new.code(argcount, kwonlyargcount, nlocals, stacksize, + flags, codestring, constants, t, varnames, + filename, name, firstlineno, lnotab) + self.assert_(type(t[0]) is S, "eek, tuple changed under us!") - if verbose: - print d +def test_main(): + test_support.run_unittest(NewTest) + +if __name__ == "__main__": + test_main() Modified: python/branches/p3yk/Lib/test/test_ntpath.py ============================================================================== --- python/branches/p3yk/Lib/test/test_ntpath.py (original) +++ python/branches/p3yk/Lib/test/test_ntpath.py Thu Feb 1 19:02:27 2007 @@ -115,6 +115,28 @@ tester("ntpath.normpath('C:////a/b')", r'C:\a\b') tester("ntpath.normpath('//machine/share//a/b')", r'\\machine\share\a\b') +oldenv = os.environ.copy() +try: + os.environ.clear() + os.environ["foo"] = "bar" + os.environ["{foo"] = "baz1" + os.environ["{foo}"] = "baz2" + tester('ntpath.expandvars("foo")', "foo") + tester('ntpath.expandvars("$foo bar")', "bar bar") + tester('ntpath.expandvars("${foo}bar")', "barbar") + tester('ntpath.expandvars("$[foo]bar")', "$[foo]bar") + tester('ntpath.expandvars("$bar bar")', "$bar bar") + tester('ntpath.expandvars("$?bar")', "$?bar") + tester('ntpath.expandvars("${foo}bar")', "barbar") + tester('ntpath.expandvars("$foo}bar")', "bar}bar") + tester('ntpath.expandvars("${foo")', "${foo") + tester('ntpath.expandvars("${{foo}}")', "baz1}") + tester('ntpath.expandvars("$foo$foo")', "barbar") + tester('ntpath.expandvars("$bar$bar")', "$bar$bar") +finally: + os.environ.clear() + os.environ.update(oldenv) + # ntpath.abspath() can only be used on a system with the "nt" module # (reasonably), so we protect this test with "import nt". This allows # the rest of the tests for the ntpath module to be run to completion Modified: python/branches/p3yk/Lib/test/test_old_mailbox.py ============================================================================== --- python/branches/p3yk/Lib/test/test_old_mailbox.py (original) +++ python/branches/p3yk/Lib/test/test_old_mailbox.py Thu Feb 1 19:02:27 2007 @@ -109,11 +109,44 @@ self.assertEqual(len(str(msg)), len(FROM_)+len(DUMMY_MESSAGE)) self.assertEqual(n, 1) +class MboxTestCase(unittest.TestCase): + def setUp(self): + # create a new maildir mailbox to work with: + self._path = test_support.TESTFN + + def tearDown(self): + os.unlink(self._path) + + def test_from_regex (self): + # Testing new regex from bug #1633678 + f = open(self._path, 'w') + f.write("""From fred at example.com Mon May 31 13:24:50 2004 +0200 +Subject: message 1 + +body1 +From fred at example.com Mon May 31 13:24:50 2004 -0200 +Subject: message 2 + +body2 +From fred at example.com Mon May 31 13:24:50 2004 +Subject: message 3 + +body3 +From fred at example.com Mon May 31 13:24:50 2004 +Subject: message 4 + +body4 +""") + f.close() + box = mailbox.UnixMailbox(open(self._path, 'r')) + self.assert_(len(list(iter(box))) == 4) + + # XXX We still need more tests! def test_main(): - test_support.run_unittest(MaildirTestCase) + test_support.run_unittest(MaildirTestCase, MboxTestCase) if __name__ == "__main__": Modified: python/branches/p3yk/Lib/test/test_popen.py ============================================================================== --- python/branches/p3yk/Lib/test/test_popen.py (original) +++ python/branches/p3yk/Lib/test/test_popen.py Thu Feb 1 19:02:27 2007 @@ -4,10 +4,9 @@ Particularly useful for platforms that fake popen. """ -import os -import sys -from test.test_support import TestSkipped, reap_children -from os import popen +import unittest +from test import test_support +import os, sys # Test that command-lines get down as we expect. # To do this we execute: @@ -17,24 +16,32 @@ 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] - if got != expected: - print "Error in popen commandline handling." - print " executed '%s', expected '%r', but got '%r'" \ - % (cmdline, expected, got) - -def _test_commandline(): - _do_test_commandline("foo bar", ["foo", "bar"]) - _do_test_commandline('foo "spam and eggs" "silly walk"', ["foo", "spam and eggs", "silly walk"]) - _do_test_commandline('foo "a \\"quoted\\" arg" bar', ["foo", 'a "quoted" arg', "bar"]) - print "popen seemed to process the command-line correctly" - -def main(): - print "Test popen:" - _test_commandline() - reap_children() -main() +class PopenTest(unittest.TestCase): + def _do_test_commandline(self, cmdline, expected): + cmd = '%s -c "import sys;print sys.argv" %s' % (python, cmdline) + data = os.popen(cmd).read() + got = eval(data)[1:] # strip off argv[0] + self.assertEqual(got, expected) + + def test_popen(self): + self.assertRaises(TypeError, os.popen) + self._do_test_commandline( + "foo bar", + ["foo", "bar"] + ) + self._do_test_commandline( + 'foo "spam and eggs" "silly walk"', + ["foo", "spam and eggs", "silly walk"] + ) + self._do_test_commandline( + 'foo "a \\"quoted\\" arg" bar', + ["foo", 'a "quoted" arg', "bar"] + ) + test_support.reap_children() + +def test_main(): + test_support.run_unittest(PopenTest) + +if __name__ == "__main__": + test_main() Modified: python/branches/p3yk/Lib/test/test_posixpath.py ============================================================================== --- python/branches/p3yk/Lib/test/test_posixpath.py (original) +++ python/branches/p3yk/Lib/test/test_posixpath.py Thu Feb 1 19:02:27 2007 @@ -374,6 +374,8 @@ self.assertEqual(posixpath.expandvars("$foo}bar"), "bar}bar") self.assertEqual(posixpath.expandvars("${foo"), "${foo") self.assertEqual(posixpath.expandvars("${{foo}}"), "baz1}") + self.assertEqual(posixpath.expandvars("$foo$foo"), "barbar") + self.assertEqual(posixpath.expandvars("$bar$bar"), "$bar$bar") finally: os.environ.clear() os.environ.update(oldenv) Modified: python/branches/p3yk/Lib/test/test_random.py ============================================================================== --- python/branches/p3yk/Lib/test/test_random.py (original) +++ python/branches/p3yk/Lib/test/test_random.py Thu Feb 1 19:02:27 2007 @@ -517,6 +517,14 @@ # tests validity but not completeness of the __all__ list self.failUnless(set(random.__all__) <= set(dir(random))) + def test_random_subclass_with_kwargs(self): + # SF bug #1486663 -- this used to erroneously raise a TypeError + class Subclass(random.Random): + def __init__(self, newarg=None): + random.Random.__init__(self) + Subclass(newarg=1) + + def test_main(verbose=None): testclasses = [WichmannHill_TestBasicOps, MersenneTwister_TestBasicOps, Modified: python/branches/p3yk/Lib/test/test_resource.py ============================================================================== --- python/branches/p3yk/Lib/test/test_resource.py (original) +++ python/branches/p3yk/Lib/test/test_resource.py Thu Feb 1 19:02:27 2007 @@ -1,56 +1,96 @@ -import os -import resource +import unittest +from test import test_support -from test.test_support import TESTFN -# This test is checking a few specific problem spots. RLIMIT_FSIZE -# should be RLIM_INFINITY, which will be a really big number on a -# platform with large file support. On these platforms, we need to -# test that the get/setrlimit functions properly convert the number to -# a C long long and that the conversion doesn't raise an error. - -try: - cur, max = resource.getrlimit(resource.RLIMIT_FSIZE) -except AttributeError: - pass -else: - print resource.RLIM_INFINITY == max - resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max)) - -# Now check to see what happens when the RLIMIT_FSIZE is small. Some -# versions of Python were terminated by an uncaught SIGXFSZ, but -# pythonrun.c has been fixed to ignore that exception. If so, the -# write() should return EFBIG when the limit is exceeded. - -# At least one platform has an unlimited RLIMIT_FSIZE and attempts to -# change it raise ValueError instead. - -try: - try: - resource.setrlimit(resource.RLIMIT_FSIZE, (1024, max)) - limit_set = 1 - except ValueError: - limit_set = 0 - f = open(TESTFN, "wb") - f.write("X" * 1024) - try: - f.write("Y") - f.flush() - except IOError: - if not limit_set: - raise - f.close() - os.unlink(TESTFN) -finally: - resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max)) - -# And be sure that setrlimit is checking for really large values -too_big = 10**50 -try: - resource.setrlimit(resource.RLIMIT_FSIZE, (too_big, max)) -except (OverflowError, ValueError): - pass -try: - resource.setrlimit(resource.RLIMIT_FSIZE, (max, too_big)) -except (OverflowError, ValueError): - pass +import os, resource + +# This test is checking a few specific problem spots with the resource module. + +class ResourceTest(unittest.TestCase): + + def test_args(self): + self.assertRaises(TypeError, resource.getrlimit) + self.assertRaises(TypeError, resource.getrlimit, 42, 42) + self.assertRaises(TypeError, resource.setrlimit) + self.assertRaises(TypeError, resource.setrlimit, 42, 42, 42) + + def test_fsize_ismax(self): + + try: + (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE) + except AttributeError: + pass + else: + # RLIMIT_FSIZE should be RLIM_INFINITY, which will be a really big + # number on a platform with large file support. On these platforms, + # we need to test that the get/setrlimit functions properly convert + # the number to a C long long and that the conversion doesn't raise + # an error. + self.assertEqual(resource.RLIM_INFINITY, max) + resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max)) + + def test_fsize_enforced(self): + try: + (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE) + except AttributeError: + pass + else: + # Check to see what happens when the RLIMIT_FSIZE is small. Some + # versions of Python were terminated by an uncaught SIGXFSZ, but + # pythonrun.c has been fixed to ignore that exception. If so, the + # write() should return EFBIG when the limit is exceeded. + + # At least one platform has an unlimited RLIMIT_FSIZE and attempts + # to change it raise ValueError instead. + try: + try: + resource.setrlimit(resource.RLIMIT_FSIZE, (1024, max)) + limit_set = True + except ValueError: + limit_set = False + f = open(test_support.TESTFN, "wb") + f.write("X" * 1024) + try: + f.write("Y") + f.flush() + except IOError: + if not limit_set: + raise + f.close() + os.unlink(test_support.TESTFN) + finally: + resource.setrlimit(resource.RLIMIT_FSIZE, (cur, max)) + + def test_fsize_toobig(self): + # Be sure that setrlimit is checking for really large values + too_big = 10**50 + try: + (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE) + except AttributeError: + pass + else: + try: + resource.setrlimit(resource.RLIMIT_FSIZE, (too_big, max)) + except (OverflowError, ValueError): + pass + try: + resource.setrlimit(resource.RLIMIT_FSIZE, (max, too_big)) + except (OverflowError, ValueError): + pass + + def test_getrusage(self): + self.assertRaises(TypeError, resource.getrusage) + self.assertRaises(TypeError, resource.getrusage, 42, 42) + usageself = resource.getrusage(resource.RUSAGE_SELF) + usagechildren = resource.getrusage(resource.RUSAGE_CHILDREN) + # May not be available on all systems. + try: + usageboth = resource.getrusage(resource.RUSAGE_BOTH) + except (ValueError, AttributeError): + pass + +def test_main(verbose=None): + test_support.run_unittest(ResourceTest) + +if __name__ == "__main__": + test_main() Modified: python/branches/p3yk/Lib/test/test_socket.py ============================================================================== --- python/branches/p3yk/Lib/test/test_socket.py (original) +++ python/branches/p3yk/Lib/test/test_socket.py Thu Feb 1 19:02:27 2007 @@ -809,6 +809,31 @@ bufsize = 2 # Exercise the buffering code + +class Urllib2FileobjectTest(unittest.TestCase): + + # urllib2.HTTPHandler has "borrowed" socket._fileobject, and requires that + # it close the socket if the close c'tor argument is true + + def testClose(self): + class MockSocket: + closed = False + def flush(self): pass + def close(self): self.closed = True + + # must not close unless we request it: the original use of _fileobject + # by module socket requires that the underlying socket not be closed until + # the _socketobject that created the _fileobject is closed + s = MockSocket() + f = socket._fileobject(s) + f.close() + self.assert_(not s.closed) + + s = MockSocket() + f = socket._fileobject(s, close=True) + f.close() + self.assert_(s.closed) + class TCPTimeoutTest(SocketTCPTest): def testTCPTimeout(self): @@ -961,7 +986,8 @@ FileObjectClassTestCase, UnbufferedFileObjectClassTestCase, LineBufferedFileObjectClassTestCase, - SmallBufferedFileObjectClassTestCase + SmallBufferedFileObjectClassTestCase, + Urllib2FileobjectTest, ]) if hasattr(socket, "socketpair"): tests.append(BasicSocketPairTest) Modified: python/branches/p3yk/Lib/test/test_struct.py ============================================================================== --- python/branches/p3yk/Lib/test/test_struct.py (original) +++ python/branches/p3yk/Lib/test/test_struct.py Thu Feb 1 19:02:27 2007 @@ -84,8 +84,8 @@ if sz * 3 != struct.calcsize('iii'): raise TestFailed, 'inconsistent sizes' -fmt = 'cbxxxxxxhhhhiillffd' -fmt3 = '3c3b18x12h6i6l6f3d' +fmt = 'cbxxxxxxhhhhiillffdt' +fmt3 = '3c3b18x12h6i6l6f3d3t' sz = struct.calcsize(fmt) sz3 = struct.calcsize(fmt3) if sz * 3 != sz3: @@ -108,19 +108,21 @@ l = 65536 f = 3.1415 d = 3.1415 +t = True for prefix in ('', '@', '<', '>', '=', '!'): - for format in ('xcbhilfd', 'xcBHILfd'): + for format in ('xcbhilfdt', 'xcBHILfdt'): format = prefix + format if verbose: print "trying:", format - s = struct.pack(format, c, b, h, i, l, f, d) - cp, bp, hp, ip, lp, fp, dp = struct.unpack(format, s) + s = struct.pack(format, c, b, h, i, l, f, d, t) + cp, bp, hp, ip, lp, fp, dp, tp = struct.unpack(format, s) if (cp != c or bp != b or hp != h or ip != i or lp != l or - int(100 * fp) != int(100 * f) or int(100 * dp) != int(100 * d)): + int(100 * fp) != int(100 * f) or int(100 * dp) != int(100 * d) or + tp != t): # ^^^ calculate only to two decimal places raise TestFailed, "unpack/pack not transitive (%s, %s)" % ( - str(format), str((cp, bp, hp, ip, lp, fp, dp))) + str(format), str((cp, bp, hp, ip, lp, fp, dp, tp))) # Test some of the new features in detail @@ -158,6 +160,11 @@ ('f', -2.0, '\300\000\000\000', '\000\000\000\300', 0), ('d', -2.0, '\300\000\000\000\000\000\000\000', '\000\000\000\000\000\000\000\300', 0), + ('t', 0, '\0', '\0', 0), + ('t', 3, '\1', '\1', 1), + ('t', True, '\1', '\1', 0), + ('t', [], '\0', '\0', 1), + ('t', (1,), '\1', '\1', 1), ] for fmt, arg, big, lil, asy in tests: @@ -612,3 +619,50 @@ test_unpack_from() test_pack_into() test_pack_into_fn() + +def test_bool(): + for prefix in tuple("<>!=")+('',): + false = (), [], [], '', 0 + true = [1], 'test', 5, -1, 0xffffffff+1, 0xffffffff/2 + + falseFormat = prefix + 't' * len(false) + if verbose: + print 'trying bool pack/unpack on', false, 'using format', falseFormat + packedFalse = struct.pack(falseFormat, *false) + unpackedFalse = struct.unpack(falseFormat, packedFalse) + + trueFormat = prefix + 't' * len(true) + if verbose: + print 'trying bool pack/unpack on', true, 'using format', trueFormat + packedTrue = struct.pack(trueFormat, *true) + unpackedTrue = struct.unpack(trueFormat, packedTrue) + + if len(true) != len(unpackedTrue): + raise TestFailed('unpacked true array is not of same size as input') + if len(false) != len(unpackedFalse): + raise TestFailed('unpacked false array is not of same size as input') + + for t in unpackedFalse: + if t is not False: + raise TestFailed('%r did not unpack as False' % t) + for t in unpackedTrue: + if t is not True: + raise TestFailed('%r did not unpack as false' % t) + + if prefix and verbose: + print 'trying size of bool with format %r' % (prefix+'t') + packed = struct.pack(prefix+'t', 1) + + if len(packed) != struct.calcsize(prefix+'t'): + raise TestFailed('packed length is not equal to calculated size') + + if len(packed) != 1 and prefix: + raise TestFailed('encoded bool is not one byte: %r' % packed) + elif not prefix and verbose: + print 'size of bool in native format is %i' % (len(packed)) + + for c in '\x01\x7f\xff\x0f\xf0': + if struct.unpack('>t', c)[0] is not True: + raise TestFailed('%c did not unpack as True' % c) + +test_bool() Modified: python/branches/p3yk/Lib/test/test_urllib2net.py ============================================================================== --- python/branches/p3yk/Lib/test/test_urllib2net.py (original) +++ python/branches/p3yk/Lib/test/test_urllib2net.py Thu Feb 1 19:02:27 2007 @@ -64,6 +64,27 @@ # urllib2.urlopen, "http://evil:thing at example.com") +class CloseSocketTest(unittest.TestCase): + + def test_close(self): + import socket, httplib, gc + + # calling .close() on urllib2's response objects should close the + # underlying socket + + # delve deep into response to fetch socket._socketobject + response = urllib2.urlopen("http://www.python.org/") + abused_fileobject = response.fp + self.assert_(abused_fileobject.__class__ is socket._fileobject) + httpresponse = abused_fileobject._sock + self.assert_(httpresponse.__class__ is httplib.HTTPResponse) + fileobject = httpresponse.fp + self.assert_(fileobject.__class__ is socket._fileobject) + + self.assert_(not fileobject.closed) + response.close() + self.assert_(fileobject.closed) + class urlopenNetworkTests(unittest.TestCase): """Tests urllib2.urlopen using the network. @@ -263,8 +284,12 @@ def test_main(): test_support.requires("network") - test_support.run_unittest(URLTimeoutTest, urlopenNetworkTests, - AuthTests, OtherNetworkTests) + test_support.run_unittest(URLTimeoutTest, + urlopenNetworkTests, + AuthTests, + OtherNetworkTests, + CloseSocketTest, + ) if __name__ == "__main__": test_main() Modified: python/branches/p3yk/Lib/test/test_uu.py ============================================================================== --- python/branches/p3yk/Lib/test/test_uu.py (original) +++ python/branches/p3yk/Lib/test/test_uu.py Thu Feb 1 19:02:27 2007 @@ -114,11 +114,11 @@ def test_encode(self): try: - fin = open(self.tmpin, 'w') + fin = open(self.tmpin, 'wb') fin.write(plaintext) fin.close() - fin = open(self.tmpin, 'r') + fin = open(self.tmpin, 'rb') fout = open(self.tmpout, 'w') uu.encode(fin, fout, self.tmpin, mode=0644) fin.close() Modified: python/branches/p3yk/Lib/test/test_weakref.py ============================================================================== --- python/branches/p3yk/Lib/test/test_weakref.py (original) +++ python/branches/p3yk/Lib/test/test_weakref.py Thu Feb 1 19:02:27 2007 @@ -6,6 +6,8 @@ from test import test_support +# Used in ReferencesTestCase.test_ref_created_during_del() . +ref_from_del = None class C: def method(self): @@ -630,6 +632,18 @@ finally: gc.set_threshold(*thresholds) + def test_ref_created_during_del(self): + # Bug #1377858 + # A weakref created in an object's __del__() would crash the + # interpreter when the weakref was cleaned up since it would refer to + # non-existent memory. This test should not segfault the interpreter. + class Target(object): + def __del__(self): + global ref_from_del + ref_from_del = weakref.ref(self) + + w = Target() + class SubclassableWeakrefTestCase(unittest.TestCase): Modified: python/branches/p3yk/Lib/urllib.py ============================================================================== --- python/branches/p3yk/Lib/urllib.py (original) +++ python/branches/p3yk/Lib/urllib.py Thu Feb 1 19:02:27 2007 @@ -452,7 +452,7 @@ def open_local_file(self, url): """Use local file.""" - import mimetypes, mimetools, email.Utils + import mimetypes, mimetools, email.utils try: from cStringIO import StringIO except ImportError: @@ -464,7 +464,7 @@ except OSError as e: raise IOError(e.errno, e.strerror, e.filename) size = stats.st_size - modified = email.Utils.formatdate(stats.st_mtime, usegmt=True) + modified = email.utils.formatdate(stats.st_mtime, usegmt=True) mtype = mimetypes.guess_type(url)[0] headers = mimetools.Message(StringIO( 'Content-Type: %s\nContent-Length: %d\nLast-modified: %s\n' % Modified: python/branches/p3yk/Lib/urllib2.py ============================================================================== --- python/branches/p3yk/Lib/urllib2.py (original) +++ python/branches/p3yk/Lib/urllib2.py Thu Feb 1 19:02:27 2007 @@ -1087,7 +1087,7 @@ # out of socket._fileobject() and into a base class. r.recv = r.read - fp = socket._fileobject(r) + fp = socket._fileobject(r, close=True) resp = addinfourl(fp, r.msg, req.get_full_url()) resp.code = r.status @@ -1209,14 +1209,14 @@ # not entirely sure what the rules are here def open_local_file(self, req): - import email.Utils + import email.utils import mimetypes host = req.get_host() file = req.get_selector() localfile = url2pathname(file) stats = os.stat(localfile) size = stats.st_size - modified = email.Utils.formatdate(stats.st_mtime, usegmt=True) + modified = email.utils.formatdate(stats.st_mtime, usegmt=True) mtype = mimetypes.guess_type(file)[0] headers = mimetools.Message(StringIO( 'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' % Modified: python/branches/p3yk/Modules/_ctypes/_ctypes_test.c ============================================================================== --- python/branches/p3yk/Modules/_ctypes/_ctypes_test.c (original) +++ python/branches/p3yk/Modules/_ctypes/_ctypes_test.c Thu Feb 1 19:02:27 2007 @@ -68,22 +68,25 @@ EXPORT(int) _testfunc_i_bhilfd(signed char b, short h, int i, long l, float f, double d) { -// printf("_testfunc_i_bhilfd got %d %d %d %ld %f %f\n", -// b, h, i, l, f, d); +/* printf("_testfunc_i_bhilfd got %d %d %d %ld %f %f\n", + b, h, i, l, f, d); +*/ return (int)(b + h + i + l + f + d); } EXPORT(float) _testfunc_f_bhilfd(signed char b, short h, int i, long l, float f, double d) { -// printf("_testfunc_f_bhilfd got %d %d %d %ld %f %f\n", -// b, h, i, l, f, d); +/* printf("_testfunc_f_bhilfd got %d %d %d %ld %f %f\n", + b, h, i, l, f, d); +*/ return (float)(b + h + i + l + f + d); } EXPORT(double) _testfunc_d_bhilfd(signed char b, short h, int i, long l, float f, double d) { -// printf("_testfunc_d_bhilfd got %d %d %d %ld %f %f\n", -// b, h, i, l, f, d); +/* printf("_testfunc_d_bhilfd got %d %d %d %ld %f %f\n", + b, h, i, l, f, d); +*/ return (double)(b + h + i + l + f + d); } @@ -378,8 +381,9 @@ } PyMethodDef module_methods[] = { -// {"get_last_tf_arg_s", get_last_tf_arg_s, METH_NOARGS}, -// {"get_last_tf_arg_u", get_last_tf_arg_u, METH_NOARGS}, +/* {"get_last_tf_arg_s", get_last_tf_arg_s, METH_NOARGS}, + {"get_last_tf_arg_u", get_last_tf_arg_u, METH_NOARGS}, +*/ {"func_si", py_func_si, METH_VARARGS}, {"func", py_func, METH_NOARGS}, { NULL, NULL, 0, NULL}, Modified: python/branches/p3yk/Modules/_randommodule.c ============================================================================== --- python/branches/p3yk/Modules/_randommodule.c (original) +++ python/branches/p3yk/Modules/_randommodule.c Thu Feb 1 19:02:27 2007 @@ -481,7 +481,7 @@ RandomObject *self; PyObject *tmp; - if (!_PyArg_NoKeywords("Random()", kwds)) + if (type == &Random_Type && !_PyArg_NoKeywords("Random()", kwds)) return NULL; self = (RandomObject *)type->tp_alloc(type, 0); Modified: python/branches/p3yk/Modules/_struct.c ============================================================================== --- python/branches/p3yk/Modules/_struct.c (original) +++ python/branches/p3yk/Modules/_struct.c Thu Feb 1 19:02:27 2007 @@ -104,6 +104,15 @@ #define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG)) #endif +#ifdef HAVE_C99_BOOL +#define BOOL_TYPE _Bool +typedef struct { char c; _Bool x; } s_bool; +#define BOOL_ALIGN (sizeof(s_bool) - sizeof(BOOL_TYPE)) +#else +#define BOOL_TYPE char +#define BOOL_ALIGN 0 +#endif + #define STRINGIFY(x) #x #ifdef __powerc @@ -534,6 +543,15 @@ #endif static PyObject * +nu_bool(const char *p, const formatdef *f) +{ + BOOL_TYPE x; + memcpy((char *)&x, p, sizeof x); + return PyBool_FromLong(x != 0); +} + + +static PyObject * nu_float(const char *p, const formatdef *f) { float x; @@ -709,6 +727,16 @@ } #endif + +static int +np_bool(char *p, PyObject *v, const formatdef *f) +{ + BOOL_TYPE y; + y = PyObject_IsTrue(v); + memcpy(p, (char *)&y, sizeof y); + return 0; +} + static int np_float(char *p, PyObject *v, const formatdef *f) { @@ -769,6 +797,7 @@ {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong}, {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong}, #endif + {'t', sizeof(BOOL_TYPE), BOOL_ALIGN, nu_bool, np_bool}, {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float}, {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double}, {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p}, @@ -863,6 +892,14 @@ return unpack_double(p, 0); } +static PyObject * +bu_bool(const char *p, const formatdef *f) +{ + char x; + memcpy((char *)&x, p, sizeof x); + return PyBool_FromLong(x != 0); +} + static int bp_int(char *p, PyObject *v, const formatdef *f) { @@ -967,6 +1004,15 @@ return _PyFloat_Pack8(x, (unsigned char *)p, 0); } +static int +bp_bool(char *p, PyObject *v, const formatdef *f) +{ + char y; + y = PyObject_IsTrue(v); + memcpy(p, (char *)&y, sizeof y); + return 0; +} + static formatdef bigendian_table[] = { {'x', 1, 0, NULL}, #ifdef PY_STRUCT_OVERFLOW_MASKING @@ -988,6 +1034,7 @@ {'L', 4, 0, bu_uint, bp_uint}, {'q', 8, 0, bu_longlong, bp_longlong}, {'Q', 8, 0, bu_ulonglong, bp_ulonglong}, + {'t', 1, 0, bu_bool, bp_bool}, {'f', 4, 0, bu_float, bp_float}, {'d', 8, 0, bu_double, bp_double}, {0} @@ -1206,6 +1253,8 @@ {'L', 4, 0, lu_uint, lp_uint}, {'q', 8, 0, lu_longlong, lp_longlong}, {'Q', 8, 0, lu_ulonglong, lp_ulonglong}, + {'t', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep, + but potentially different from native rep -- reuse bx_bool funcs. */ {'f', 4, 0, lu_float, lp_float}, {'d', 8, 0, lu_double, lp_double}, {0} Modified: python/branches/p3yk/Modules/arraymodule.c ============================================================================== --- python/branches/p3yk/Modules/arraymodule.c (original) +++ python/branches/p3yk/Modules/arraymodule.c Thu Feb 1 19:02:27 2007 @@ -1797,7 +1797,7 @@ PyObject *initial = NULL, *it = NULL; struct arraydescr *descr; - if (!_PyArg_NoKeywords("array.array()", kwds)) + if (type == &Arraytype && !_PyArg_NoKeywords("array.array()", kwds)) return NULL; if (!PyArg_ParseTuple(args, "c|O:array", &c, &initial)) Modified: python/branches/p3yk/Modules/collectionsmodule.c ============================================================================== --- python/branches/p3yk/Modules/collectionsmodule.c (original) +++ python/branches/p3yk/Modules/collectionsmodule.c Thu Feb 1 19:02:27 2007 @@ -95,7 +95,7 @@ dequeobject *deque; block *b; - if (!_PyArg_NoKeywords("deque()", kwds)) + if (type == &deque_type && !_PyArg_NoKeywords("deque()", kwds)) return NULL; /* create dequeobject structure */ Modified: python/branches/p3yk/Modules/itertoolsmodule.c ============================================================================== --- python/branches/p3yk/Modules/itertoolsmodule.c (original) +++ python/branches/p3yk/Modules/itertoolsmodule.c Thu Feb 1 19:02:27 2007 @@ -681,7 +681,7 @@ PyObject *saved; cycleobject *lz; - if (!_PyArg_NoKeywords("cycle()", kwds)) + if (type == &cycle_type && !_PyArg_NoKeywords("cycle()", kwds)) return NULL; if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable)) @@ -831,7 +831,7 @@ PyObject *it; dropwhileobject *lz; - if (!_PyArg_NoKeywords("dropwhile()", kwds)) + if (type == &dropwhile_type && !_PyArg_NoKeywords("dropwhile()", kwds)) return NULL; if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq)) @@ -975,7 +975,7 @@ PyObject *it; takewhileobject *lz; - if (!_PyArg_NoKeywords("takewhile()", kwds)) + if (type == &takewhile_type && !_PyArg_NoKeywords("takewhile()", kwds)) return NULL; if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq)) @@ -1120,7 +1120,7 @@ Py_ssize_t numargs; isliceobject *lz; - if (!_PyArg_NoKeywords("islice()", kwds)) + if (type == &islice_type && !_PyArg_NoKeywords("islice()", kwds)) return NULL; if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3)) @@ -1311,7 +1311,7 @@ PyObject *it; starmapobject *lz; - if (!_PyArg_NoKeywords("starmap()", kwds)) + if (type == &starmap_type && !_PyArg_NoKeywords("starmap()", kwds)) return NULL; if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq)) @@ -1443,7 +1443,7 @@ imapobject *lz; Py_ssize_t numargs, i; - if (!_PyArg_NoKeywords("imap()", kwds)) + if (type == &imap_type && !_PyArg_NoKeywords("imap()", kwds)) return NULL; numargs = PyTuple_Size(args); @@ -1625,7 +1625,7 @@ Py_ssize_t i; PyObject *ittuple; - if (!_PyArg_NoKeywords("chain()", kwds)) + if (type == &chain_type && !_PyArg_NoKeywords("chain()", kwds)) return NULL; /* obtain iterators */ @@ -1768,7 +1768,7 @@ PyObject *it; ifilterobject *lz; - if (!_PyArg_NoKeywords("ifilter()", kwds)) + if (type == &ifilter_type && !_PyArg_NoKeywords("ifilter()", kwds)) return NULL; if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq)) @@ -1912,7 +1912,8 @@ PyObject *it; ifilterfalseobject *lz; - if (!_PyArg_NoKeywords("ifilterfalse()", kwds)) + if (type == &ifilterfalse_type && + !_PyArg_NoKeywords("ifilterfalse()", kwds)) return NULL; if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq)) @@ -2054,7 +2055,7 @@ countobject *lz; Py_ssize_t cnt = 0; - if (!_PyArg_NoKeywords("count()", kwds)) + if (type == &count_type && !_PyArg_NoKeywords("count()", kwds)) return NULL; if (!PyArg_ParseTuple(args, "|n:count", &cnt)) @@ -2153,7 +2154,7 @@ PyObject *result; Py_ssize_t tuplesize = PySequence_Length(args); - if (!_PyArg_NoKeywords("izip()", kwds)) + if (type == &izip_type && !_PyArg_NoKeywords("izip()", kwds)) return NULL; /* args must be a tuple */ @@ -2336,7 +2337,7 @@ PyObject *element; Py_ssize_t cnt = -1; - if (!_PyArg_NoKeywords("repeat()", kwds)) + if (type == &repeat_type && !_PyArg_NoKeywords("repeat()", kwds)) return NULL; if (!PyArg_ParseTuple(args, "O|n:repeat", &element, &cnt)) Modified: python/branches/p3yk/Objects/fileobject.c ============================================================================== --- python/branches/p3yk/Objects/fileobject.c (original) +++ python/branches/p3yk/Objects/fileobject.c Thu Feb 1 19:02:27 2007 @@ -354,6 +354,8 @@ { PyFileObject *file = (PyFileObject*)f; PyObject *str = PyString_FromString(enc); + + assert(PyFile_Check(f)); if (!str) return 0; Py_DECREF(file->f_encoding); Modified: python/branches/p3yk/Objects/object.c ============================================================================== --- python/branches/p3yk/Objects/object.c (original) +++ python/branches/p3yk/Objects/object.c Thu Feb 1 19:02:27 2007 @@ -314,7 +314,7 @@ /* For debugging convenience. Set a breakpoint here and call it from your DLL */ void -_Py_Break(void) +_Py_BreakPoint(void) { } Modified: python/branches/p3yk/Objects/typeobject.c ============================================================================== --- python/branches/p3yk/Objects/typeobject.c (original) +++ python/branches/p3yk/Objects/typeobject.c Thu Feb 1 19:02:27 2007 @@ -655,6 +655,17 @@ goto endlabel; /* resurrected */ else _PyObject_GC_UNTRACK(self); + /* New weakrefs could be created during the finalizer call. + If this occurs, clear them out without calling their + finalizers since they might rely on part of the object + being finalized that has already been destroyed. */ + if (type->tp_weaklistoffset && !base->tp_weaklistoffset) { + /* Modeled after GET_WEAKREFS_LISTPTR() */ + PyWeakReference **list = (PyWeakReference **) \ + PyObject_GET_WEAKREFS_LISTPTR(self); + while (*list) + _PyWeakref_ClearRef(*list); + } } /* Clear slots up to the nearest base with a different tp_dealloc */ Modified: python/branches/p3yk/Objects/weakrefobject.c ============================================================================== --- python/branches/p3yk/Objects/weakrefobject.c (original) +++ python/branches/p3yk/Objects/weakrefobject.c Thu Feb 1 19:02:27 2007 @@ -57,6 +57,9 @@ PyWeakref_GET_OBJECT(self)); if (*list == self) + /* If 'self' is the end of the list (and thus self->wr_next == NULL) + then the weakref list itself (and thus the value of *list) will + end up being set to NULL. */ *list = self->wr_next; self->wr_object = Py_None; if (self->wr_prev != NULL) Modified: python/branches/p3yk/PCbuild/_bsddb.vcproj ============================================================================== --- python/branches/p3yk/PCbuild/_bsddb.vcproj (original) +++ python/branches/p3yk/PCbuild/_bsddb.vcproj Thu Feb 1 19:02:27 2007 @@ -130,7 +130,7 @@ ATLMinimizesCRunTimeLibraryUsage="FALSE"> f_tstate; + PyThreadState *tstate = PyThreadState_GET(); PyTracebackObject *oldtb = (PyTracebackObject *) tstate->curexc_traceback; PyTracebackObject *tb = newtracebackobject(oldtb, frame); if (tb == NULL) Modified: python/branches/p3yk/Tools/msi/uuids.py ============================================================================== --- python/branches/p3yk/Tools/msi/uuids.py (original) +++ python/branches/p3yk/Tools/msi/uuids.py Thu Feb 1 19:02:27 2007 @@ -33,4 +33,8 @@ '2.5.121': '{8e9321bc-6b24-48a3-8fd4-c95f8e531e5f}', # 2.5c1 '2.5.122': '{a6cd508d-9599-45da-a441-cbffa9f7e070}', # 2.5c2 '2.5.150': '{0a2c5854-557e-48c8-835a-3b9f074bdcaa}', # 2.5.0 + '2.5.1121':'{0378b43e-6184-4c2f-be1a-4a367781cd54}', # 2.5.1c1 + '2.5.1150':'{31800004-6386-4999-a519-518f2d78d8f0}', # 2.5.1 + '2.5.2150':'{6304a7da-1132-4e91-a343-a296269eab8a}', # 2.5.2c1 + '2.5.2150':'{6b976adf-8ae8-434e-b282-a06c7f624d2f}', # 2.5.2 } Modified: python/branches/p3yk/configure ============================================================================== --- python/branches/p3yk/configure (original) +++ python/branches/p3yk/configure Thu Feb 1 19:02:27 2007 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 51211 . +# From configure.in Revision: 53017 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.0. # @@ -10608,6 +10608,467 @@ fi +{ echo "$as_me:$LINENO: checking for _Bool support" >&5 +echo $ECHO_N "checking for _Bool support... $ECHO_C" >&6; } +have_c99_bool=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +_Bool x; x = (_Bool)0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_C99_BOOL 1 +_ACEOF + + have_c99_bool=yes + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $have_c99_bool" >&5 +echo "${ECHO_T}$have_c99_bool" >&6; } +if test "$have_c99_bool" = yes ; then +{ echo "$as_me:$LINENO: checking for _Bool" >&5 +echo $ECHO_N "checking for _Bool... $ECHO_C" >&6; } +if test "${ac_cv_type__Bool+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef _Bool ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type__Bool=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type__Bool=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5 +echo "${ECHO_T}$ac_cv_type__Bool" >&6; } + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ echo "$as_me:$LINENO: checking size of _Bool" >&5 +echo $ECHO_N "checking size of _Bool... $ECHO_C" >&6; } +if test "${ac_cv_sizeof__Bool+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef _Bool ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=0 ac_mid=0 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef _Bool ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef _Bool ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=-1 ac_mid=-1 + while :; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef _Bool ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo= ac_hi= +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef _Bool ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof__Bool=$ac_lo;; +'') if test "$ac_cv_type__Bool" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (_Bool) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (_Bool) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof__Bool=0 + fi ;; +esac +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + typedef _Bool ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof__Bool=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type__Bool" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (_Bool) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (_Bool) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof__Bool=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof__Bool" >&5 +echo "${ECHO_T}$ac_cv_sizeof__Bool" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF__BOOL $ac_cv_sizeof__Bool +_ACEOF + + +fi + { echo "$as_me:$LINENO: checking for uintptr_t" >&5 echo $ECHO_N "checking for uintptr_t... $ECHO_C" >&6; } if test "${ac_cv_type_uintptr_t+set}" = set; then Modified: python/branches/p3yk/configure.in ============================================================================== --- python/branches/p3yk/configure.in (original) +++ python/branches/p3yk/configure.in Thu Feb 1 19:02:27 2007 @@ -1218,6 +1218,17 @@ AC_CHECK_SIZEOF(long long, 8) fi +AC_MSG_CHECKING(for _Bool support) +have_c99_bool=no +AC_TRY_COMPILE([], [_Bool x; x = (_Bool)0;], [ + AC_DEFINE(HAVE_C99_BOOL, 1, [Define this if you have the type _Bool.]) + have_c99_bool=yes +]) +AC_MSG_RESULT($have_c99_bool) +if test "$have_c99_bool" = yes ; then +AC_CHECK_SIZEOF(_Bool, 1) +fi + AC_CHECK_TYPES(uintptr_t, [AC_CHECK_SIZEOF(uintptr_t, 4)], [], [#ifdef HAVE_STDINT_H Modified: python/branches/p3yk/pyconfig.h.in ============================================================================== --- python/branches/p3yk/pyconfig.h.in (original) +++ python/branches/p3yk/pyconfig.h.in Thu Feb 1 19:02:27 2007 @@ -64,6 +64,9 @@ /* Define if pthread_sigmask() does not work on your system. */ #undef HAVE_BROKEN_PTHREAD_SIGMASK +/* Define this if you have the type _Bool. */ +#undef HAVE_C99_BOOL + /* Define to 1 if you have the `chown' function. */ #undef HAVE_CHOWN @@ -835,6 +838,9 @@ /* The size of a `wchar_t', as computed by sizeof. */ #undef SIZEOF_WCHAR_T +/* The size of a `_Bool', as computed by sizeof. */ +#undef SIZEOF__BOOL + /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS From python-checkins at python.org Thu Feb 1 19:57:07 2007 From: python-checkins at python.org (phillip.eby) Date: Thu, 1 Feb 2007 19:57:07 +0100 (CET) Subject: [Python-checkins] r53611 - sandbox/trunk/setuptools/setuptools/command/easy_install.py Message-ID: <20070201185707.80FF41E4017@bag.python.org> Author: phillip.eby Date: Thu Feb 1 19:57:06 2007 New Revision: 53611 Modified: sandbox/trunk/setuptools/setuptools/command/easy_install.py Log: Fixed mangling line endings when an old-style source script came from Windows. Modified: sandbox/trunk/setuptools/setuptools/command/easy_install.py ============================================================================== --- sandbox/trunk/setuptools/setuptools/command/easy_install.py (original) +++ sandbox/trunk/setuptools/setuptools/command/easy_install.py Thu Feb 1 19:57:06 2007 @@ -373,7 +373,7 @@ for script_name in dist.metadata_listdir('scripts'): self.install_script( dist, script_name, - dist.get_metadata('scripts/'+script_name).replace('\r','\n') + '\n'.join(dist.get_metadata('scripts/'+script_name).splitlines()) ) self.install_wrapper_scripts(dist) From python-checkins at python.org Thu Feb 1 20:03:19 2007 From: python-checkins at python.org (phillip.eby) Date: Thu, 1 Feb 2007 20:03:19 +0100 (CET) Subject: [Python-checkins] r53612 - in sandbox/branches/setuptools-0.6: EasyInstall.txt setuptools/command/easy_install.py Message-ID: <20070201190319.5710B1E4006@bag.python.org> Author: phillip.eby Date: Thu Feb 1 20:03:18 2007 New Revision: 53612 Modified: sandbox/branches/setuptools-0.6/EasyInstall.txt sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py Log: Fixed distutils-style scripts originally built on Windows having their line endings doubled when installed on any platform. (backport) Modified: sandbox/branches/setuptools-0.6/EasyInstall.txt ============================================================================== --- sandbox/branches/setuptools-0.6/EasyInstall.txt (original) +++ sandbox/branches/setuptools-0.6/EasyInstall.txt Thu Feb 1 20:03:18 2007 @@ -1198,7 +1198,10 @@ * EasyInstall no longer aborts the installation process if a URL it wants to retrieve can't be downloaded, unless the URL is an actual package download. Instead, it issues a warning and tries to keep going. - + + * Fixed distutils-style scripts originally built on Windows having their line + endings doubled when installed on any platform. + 0.6c5 * Fixed ``.dll`` files on Cygwin not having executable permisions when an egg is installed unzipped. Modified: sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py ============================================================================== --- sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py (original) +++ sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py Thu Feb 1 20:03:18 2007 @@ -373,7 +373,7 @@ for script_name in dist.metadata_listdir('scripts'): self.install_script( dist, script_name, - dist.get_metadata('scripts/'+script_name).replace('\r','\n') + '\n'.join(dist.get_metadata('scripts/'+script_name).splitlines()) ) self.install_wrapper_scripts(dist) From python-checkins at python.org Thu Feb 1 20:50:30 2007 From: python-checkins at python.org (brett.cannon) Date: Thu, 1 Feb 2007 20:50:30 +0100 (CET) Subject: [Python-checkins] r53613 - in python/branches/bcannon-objcap: BRANCHNEWS Python/pythonrun.c Message-ID: <20070201195030.D91C81E4009@bag.python.org> Author: brett.cannon Date: Thu Feb 1 20:50:30 2007 New Revision: 53613 Modified: python/branches/bcannon-objcap/BRANCHNEWS python/branches/bcannon-objcap/Python/pythonrun.c Log: Clear sys.path_importer_cache. Modified: python/branches/bcannon-objcap/BRANCHNEWS ============================================================================== --- python/branches/bcannon-objcap/BRANCHNEWS (original) +++ python/branches/bcannon-objcap/BRANCHNEWS Thu Feb 1 20:50:30 2007 @@ -8,6 +8,8 @@ Core and builtins ----------------- +* Clear out sys.path_importer_cache. + * Force 'warnings' to be cached by the C code. * Make importing the sys module after it has been completely deleted use the Modified: python/branches/bcannon-objcap/Python/pythonrun.c ============================================================================== --- python/branches/bcannon-objcap/Python/pythonrun.c (original) +++ python/branches/bcannon-objcap/Python/pythonrun.c Thu Feb 1 20:50:30 2007 @@ -367,8 +367,8 @@ Incremental codecs fail. * _codecs Exposed by codecs. - * warnings (hide: needs sys._getframe()) - Warnings reset otherwise. + * warnings (cache in C code) + Warnings reset otherwise. Requires 'sys' module to work. */ /* Get the 'warnings' module cached away at the C level. */ PyModule_GetWarningsModule(); @@ -407,6 +407,10 @@ PyDict_SetItemString(interp->modules, ".hidden", hidden_modules); PyDict_SetItemString(interp->sysdict, "modules", interp->modules); + + /* Clear out sys.path_importer_cache. */ + PyDict_Clear(PyDict_GetItemString(interp->sysdict, + "path_importer_cache")); } From python-checkins at python.org Thu Feb 1 20:59:49 2007 From: python-checkins at python.org (phillip.eby) Date: Thu, 1 Feb 2007 20:59:49 +0100 (CET) Subject: [Python-checkins] r53614 - sandbox/trunk/setuptools/setuptools/command/easy_install.py Message-ID: <20070201195949.BC10E1E4009@bag.python.org> Author: phillip.eby Date: Thu Feb 1 20:59:49 2007 New Revision: 53614 Modified: sandbox/trunk/setuptools/setuptools/command/easy_install.py Log: Fix script language detection so that scripts built on Windows are correctly identified as still being Python code! Modified: sandbox/trunk/setuptools/setuptools/command/easy_install.py ============================================================================== --- sandbox/trunk/setuptools/setuptools/command/easy_install.py (original) +++ sandbox/trunk/setuptools/setuptools/command/easy_install.py Thu Feb 1 20:59:49 2007 @@ -373,7 +373,7 @@ for script_name in dist.metadata_listdir('scripts'): self.install_script( dist, script_name, - '\n'.join(dist.get_metadata('scripts/'+script_name).splitlines()) + dist.get_metadata('scripts/'+script_name) ) self.install_wrapper_scripts(dist) @@ -593,7 +593,7 @@ "import pkg_resources\n" "pkg_resources.run_script(%(spec)r, %(script_name)r)\n" ) % locals() - self.write_script(script_name, script_text) + self.write_script(script_name, script_text, 'b') def write_script(self, script_name, contents, mode="t", blockers=()): """Write an executable file to the scripts directory""" @@ -1518,22 +1518,16 @@ def is_python_script(script_text, filename): """Is this text, as a whole, a Python script? (as opposed to shell/bat/etc. """ - if script_text.startswith('#!'): - # It begins with a '#!' line, so check if 'python' is in it somewhere - from distutils.command.build_scripts import first_line_re - lines = script_text.splitlines() - - if first_line_re.match(lines[0]): - return True # It's got a python "#!" line, consider it Python - else: - return False # It's some other scripting language - if filename.endswith('.py') or filename.endswith('.pyw'): return True # extension says it's Python if is_python(script_text, filename): return True # it's syntactically valid Python + if script_text.startswith('#!'): + # It begins with a '#!' line, so check if 'python' is in it somewhere + return 'python' in script_text.splitlines()[0].lower() + return False # Not any Python I can recognize @@ -1556,6 +1550,12 @@ + + + + + + def get_script_args(dist, executable=sys_executable, wininst=False): """Yield write_script() argument tuples for a distribution's entrypoints""" spec = str(dist.as_requirement()) From python-checkins at python.org Thu Feb 1 21:03:41 2007 From: python-checkins at python.org (phillip.eby) Date: Thu, 1 Feb 2007 21:03:41 +0100 (CET) Subject: [Python-checkins] r53615 - sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py Message-ID: <20070201200341.943A31E400A@bag.python.org> Author: phillip.eby Date: Thu Feb 1 21:03:39 2007 New Revision: 53615 Modified: sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py Log: Fix script language detection problem (backport from trunk) Modified: sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py ============================================================================== --- sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py (original) +++ sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py Thu Feb 1 21:03:39 2007 @@ -373,7 +373,7 @@ for script_name in dist.metadata_listdir('scripts'): self.install_script( dist, script_name, - '\n'.join(dist.get_metadata('scripts/'+script_name).splitlines()) + dist.get_metadata('scripts/'+script_name) ) self.install_wrapper_scripts(dist) @@ -593,7 +593,7 @@ "import pkg_resources\n" "pkg_resources.run_script(%(spec)r, %(script_name)r)\n" ) % locals() - self.write_script(script_name, script_text) + self.write_script(script_name, script_text, 'b') def write_script(self, script_name, contents, mode="t", blockers=()): """Write an executable file to the scripts directory""" @@ -1518,22 +1518,16 @@ def is_python_script(script_text, filename): """Is this text, as a whole, a Python script? (as opposed to shell/bat/etc. """ - if script_text.startswith('#!'): - # It begins with a '#!' line, so check if 'python' is in it somewhere - from distutils.command.build_scripts import first_line_re - lines = script_text.splitlines() - - if first_line_re.match(lines[0]): - return True # It's got a python "#!" line, consider it Python - else: - return False # It's some other scripting language - if filename.endswith('.py') or filename.endswith('.pyw'): return True # extension says it's Python if is_python(script_text, filename): return True # it's syntactically valid Python + if script_text.startswith('#!'): + # It begins with a '#!' line, so check if 'python' is in it somewhere + return 'python' in script_text.splitlines()[0].lower() + return False # Not any Python I can recognize @@ -1556,6 +1550,12 @@ + + + + + + def get_script_args(dist, executable=sys_executable, wininst=False): """Yield write_script() argument tuples for a distribution's entrypoints""" spec = str(dist.as_requirement()) From python-checkins at python.org Thu Feb 1 21:53:45 2007 From: python-checkins at python.org (brett.cannon) Date: Thu, 1 Feb 2007 21:53:45 +0100 (CET) Subject: [Python-checkins] r53616 - in python/branches/bcannon-objcap: BRANCHNEWS Python/pythonrun.c Message-ID: <20070201205345.430341E4006@bag.python.org> Author: brett.cannon Date: Thu Feb 1 21:53:44 2007 New Revision: 53616 Modified: python/branches/bcannon-objcap/BRANCHNEWS python/branches/bcannon-objcap/Python/pythonrun.c Log: Start using importlib for imports. Required moving other modules into .hidden for support reasons. Need to tweak importlib to block imports starting with '.'. Modified: python/branches/bcannon-objcap/BRANCHNEWS ============================================================================== --- python/branches/bcannon-objcap/BRANCHNEWS (original) +++ python/branches/bcannon-objcap/BRANCHNEWS Thu Feb 1 21:53:44 2007 @@ -8,6 +8,10 @@ Core and builtins ----------------- +* Use an instance of importlib.Import as what __import__ delegates to. This + necessitates storing a large chunk of modules into sys.modules['.hidden'] so + that importlib can keep working. + * Clear out sys.path_importer_cache. * Force 'warnings' to be cached by the C code. Modified: python/branches/bcannon-objcap/Python/pythonrun.c ============================================================================== --- python/branches/bcannon-objcap/Python/pythonrun.c (original) +++ python/branches/bcannon-objcap/Python/pythonrun.c Thu Feb 1 21:53:44 2007 @@ -333,24 +333,32 @@ { PyInterpreterState *interp; Py_ssize_t module_count, x; - PyObject* module_names_list; - PyObject* hidden_modules; + PyObject *module_names_list; + PyObject *hidden_modules; + PyObject *import_module; + PyObject *import_callable; Py_InitializeEx(1); interp = PyThreadState_GET()->interp; + import_module = PyImport_ImportModule("importlib"); + + import_callable = PyObject_CallMethod(import_module, "Import", ""); + /* Store import machinery somewhere so that a reference is held as needed. */ - PyDict_SetItemString(interp->sysdict, "import_", - PyDict_GetItemString(interp->builtins, "__import__")); + PyDict_SetItemString(interp->sysdict, "import_", import_callable); PyDict_SetItemString(interp->builtins, "__import__", PyDict_GetItemString(interp->sysdict, "import_delegate")); + Py_DECREF(import_module); + Py_DECREF(import_callable); + /* Clear out sys.modules. - Some modules must be kept around (at least for now; **XXX need to do - a security audit of each one!): + Some modules must be kept around in order for Python to function + properly. * __builtin__ Lose this and Python will not run. @@ -369,6 +377,9 @@ Exposed by codecs. * warnings (cache in C code) Warnings reset otherwise. Requires 'sys' module to work. + + All other modules are kept in the '.hidden' dict in sys.modules for + use by importlib. */ /* Get the 'warnings' module cached away at the C level. */ PyModule_GetWarningsModule(); @@ -388,21 +399,18 @@ (strcmp(module_name, "_codecs") == 0)) { continue; } - /* Modules that *must* stay but can be invisible. */ - /*else if ((strcmp(module_name, "warnings") == 0)) { + /* All other modules must be stored away for importlib. */ + else { PyObject *module = PyDict_GetItemString(interp->modules, module_name); PyDict_SetItemString(hidden_modules, module_name, module); PyDict_DelItemString(interp->modules, module_name); - }*/ - /* Everything else can go. */ - else { - PyDict_DelItemString(interp->modules, module_name); } } - /* Store away modules that must stick around but should not be exposed. + /* Store away modules that must stick around but should not be exposed; + this is done for importlib's benefit. */ PyDict_SetItemString(interp->modules, ".hidden", hidden_modules); From python-checkins at python.org Thu Feb 1 22:01:24 2007 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 1 Feb 2007 22:01:24 +0100 (CET) Subject: [Python-checkins] r53617 - in python/branches/release25-maint: Misc/NEWS Objects/setobject.c Message-ID: <20070201210124.B1F221E4011@bag.python.org> Author: raymond.hettinger Date: Thu Feb 1 22:01:21 2007 New Revision: 53617 Modified: python/branches/release25-maint/Misc/NEWS python/branches/release25-maint/Objects/setobject.c Log: Bug #1648179: set.update() not recognizing __iter__ overrides in dict subclasses. Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Thu Feb 1 22:01:21 2007 @@ -16,6 +16,9 @@ a weakref on itself during a __del__ call for new-style classes (classic classes still have the bug). +- Bug #1648179: set.update() did not recognize an overridden __iter__ + method in subclasses of dict. + - Bug #1579370: Make PyTraceBack_Here use the current thread, not the frame's thread state. Modified: python/branches/release25-maint/Objects/setobject.c ============================================================================== --- python/branches/release25-maint/Objects/setobject.c (original) +++ python/branches/release25-maint/Objects/setobject.c Thu Feb 1 22:01:21 2007 @@ -915,7 +915,7 @@ if (PyAnySet_Check(other)) return set_merge(so, other); - if (PyDict_Check(other)) { + if (PyDict_CheckExact(other)) { PyObject *value; Py_ssize_t pos = 0; while (PyDict_Next(other, &pos, &key, &value)) { @@ -1363,7 +1363,7 @@ setentry *entry; Py_ssize_t pos = 0; - if (!PyAnySet_Check(other) && !PyDict_Check(other)) { + if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) { result = set_copy(so); if (result == NULL) return NULL; @@ -1377,7 +1377,7 @@ if (result == NULL) return NULL; - if (PyDict_Check(other)) { + if (PyDict_CheckExact(other)) { while (set_next(so, &pos, &entry)) { setentry entrycopy; entrycopy.hash = entry->hash; @@ -1450,7 +1450,7 @@ if ((PyObject *)so == other) return set_clear(so); - if (PyDict_Check(other)) { + if (PyDict_CheckExact(other)) { PyObject *value; int rv; while (PyDict_Next(other, &pos, &key, &value)) { From python-checkins at python.org Thu Feb 1 22:03:00 2007 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 1 Feb 2007 22:03:00 +0100 (CET) Subject: [Python-checkins] r53618 - python/trunk/Objects/setobject.c Message-ID: <20070201210300.31F8F1E400B@bag.python.org> Author: raymond.hettinger Date: Thu Feb 1 22:02:59 2007 New Revision: 53618 Modified: python/trunk/Objects/setobject.c Log: Bug #1648179: set.update() not recognizing __iter__ overrides in dict subclasses. Modified: python/trunk/Objects/setobject.c ============================================================================== --- python/trunk/Objects/setobject.c (original) +++ python/trunk/Objects/setobject.c Thu Feb 1 22:02:59 2007 @@ -915,7 +915,7 @@ if (PyAnySet_Check(other)) return set_merge(so, other); - if (PyDict_Check(other)) { + if (PyDict_CheckExact(other)) { PyObject *value; Py_ssize_t pos = 0; while (PyDict_Next(other, &pos, &key, &value)) { @@ -1363,7 +1363,7 @@ setentry *entry; Py_ssize_t pos = 0; - if (!PyAnySet_Check(other) && !PyDict_Check(other)) { + if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) { result = set_copy(so); if (result == NULL) return NULL; @@ -1377,7 +1377,7 @@ if (result == NULL) return NULL; - if (PyDict_Check(other)) { + if (PyDict_CheckExact(other)) { while (set_next(so, &pos, &entry)) { setentry entrycopy; entrycopy.hash = entry->hash; @@ -1450,7 +1450,7 @@ if ((PyObject *)so == other) return set_clear(so); - if (PyDict_Check(other)) { + if (PyDict_CheckExact(other)) { PyObject *value; int rv; while (PyDict_Next(other, &pos, &key, &value)) { From python-checkins at python.org Thu Feb 1 22:03:08 2007 From: python-checkins at python.org (andrew.kuchling) Date: Thu, 1 Feb 2007 22:03:08 +0100 (CET) Subject: [Python-checkins] r53619 - peps/trunk/pep-0008.txt Message-ID: <20070201210308.1FE4A1E4006@bag.python.org> Author: andrew.kuchling Date: Thu Feb 1 22:03:07 2007 New Revision: 53619 Modified: peps/trunk/pep-0008.txt Log: Be stricter about string exceptions Modified: peps/trunk/pep-0008.txt ============================================================================== --- peps/trunk/pep-0008.txt (original) +++ peps/trunk/pep-0008.txt Thu Feb 1 22:03:07 2007 @@ -641,9 +641,8 @@ - Use class-based exceptions. - String exceptions in new code are strongly discouraged, as they will - eventually (in Python 2.5) be deprecated and then (in Python 3000 or - perhaps sooner) removed. + String exceptions in new code are forbidden, because this language + feature is being removed in Python 2.6. Modules or packages should define their own domain-specific base exception class, which should be subclassed from the built-in Exception From python-checkins at python.org Thu Feb 1 22:04:20 2007 From: python-checkins at python.org (andrew.kuchling) Date: Thu, 1 Feb 2007 22:04:20 +0100 (CET) Subject: [Python-checkins] r53620 - peps/trunk/pep-0008.txt Message-ID: <20070201210420.24BC91E4007@bag.python.org> Author: andrew.kuchling Date: Thu Feb 1 22:04:19 2007 New Revision: 53620 Modified: peps/trunk/pep-0008.txt Log: Wording fix Modified: peps/trunk/pep-0008.txt ============================================================================== --- peps/trunk/pep-0008.txt (original) +++ peps/trunk/pep-0008.txt Thu Feb 1 22:04:19 2007 @@ -628,7 +628,7 @@ in-place string concatenation for statements in the form a+=b or a=a+b. Those statements run more slowly in Jython. In performance sensitive parts of the library, the ''.join() form should be used instead. This - will assure that concatenation occurs in linear time across various + will ensure that concatenation occurs in linear time across various implementations. - Comparisons to singletons like None should always be done with From python-checkins at python.org Thu Feb 1 22:10:22 2007 From: python-checkins at python.org (andrew.kuchling) Date: Thu, 1 Feb 2007 22:10:22 +0100 (CET) Subject: [Python-checkins] r53621 - peps/trunk/pep-0008.txt Message-ID: <20070201211022.F17E51E4006@bag.python.org> Author: andrew.kuchling Date: Thu Feb 1 22:09:28 2007 New Revision: 53621 Modified: peps/trunk/pep-0008.txt Log: Mention bare except: clauses in PEP 8; see the python-dev archive around Dec. 22 2007 for a short discussion Modified: peps/trunk/pep-0008.txt ============================================================================== --- peps/trunk/pep-0008.txt (original) +++ peps/trunk/pep-0008.txt Thu Feb 1 22:09:28 2007 @@ -663,6 +663,32 @@ continuation characters thanks to the containing parentheses. The older form will be removed in Python 3000. + - When catching exceptions, mention specific exceptions + whenever possible instead of using a bare 'except:' clause. + + For example, use: + + try: + import platform_specific_module + except ImportError: + platform_specific_module = None + + A bare 'except:' clause will catch SystemExit and KeyboardInterrupt + exceptions, making it harder to interrupt a program with Control-C, + and can disguise other problems. If you want to catch all + exceptions that signal program errors, use 'except StandardError:'. + + A good rule of thumb is to limit use of bare 'except' clauses to two + cases: + + 1) If the exception handler will be printing out or logging + the traceback; at least the user will be aware that an + error has occurred. + + 2) If the code needs to do some cleanup work, but then lets + the exception propagate upwards with 'raise'. + 'try...finally' is a better way to handle this case. + - Use string methods instead of the string module. String methods are always much faster and share the same API with From fdrake at acm.org Thu Feb 1 22:16:59 2007 From: fdrake at acm.org (Fred L. Drake, Jr.) Date: Thu, 1 Feb 2007 16:16:59 -0500 Subject: [Python-checkins] r53621 - peps/trunk/pep-0008.txt In-Reply-To: <20070201211022.F17E51E4006@bag.python.org> References: <20070201211022.F17E51E4006@bag.python.org> Message-ID: <200702011616.59728.fdrake@acm.org> On Thursday 01 February 2007 16:10, andrew.kuchling wrote: > Author: andrew.kuchling > Date: Thu Feb 1 22:09:28 2007 > New Revision: 53621 ... > Mention bare except: clauses in PEP 8; see the python-dev archive around > Dec. 22 2007 for a short discussion Now that's forward-looking! ;-) -Fred -- Fred L. Drake, Jr. From buildbot at python.org Thu Feb 1 23:22:13 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 01 Feb 2007 22:22:13 +0000 Subject: [Python-checkins] buildbot warnings in x86 Ubuntu edgy (icc) 2.5 Message-ID: <20070201222214.1FC581E4006@bag.python.org> The Buildbot has detected a new failure of x86 Ubuntu edgy (icc) 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520Ubuntu%2520edgy%2520%2528icc%2529%25202.5/builds/151 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_timeout ====================================================================== FAIL: testConnectTimeout (test.test_timeout.TimeoutTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/Buildbot/2.5.baxter-ubuntu/build/Lib/test/test_timeout.py", line 128, in testConnectTimeout %(_delta, self.fuzz, _timeout)) AssertionError: timeout (3.5154) is more than 2 seconds more than expected (0.001) sincerely, -The Buildbot From python-checkins at python.org Fri Feb 2 00:15:48 2007 From: python-checkins at python.org (brett.cannon) Date: Fri, 2 Feb 2007 00:15:48 +0100 (CET) Subject: [Python-checkins] r53622 - sandbox/trunk/import_in_py/importlib.py sandbox/trunk/import_in_py/test_importlib.py Message-ID: <20070201231548.D3A981E4016@bag.python.org> Author: brett.cannon Date: Fri Feb 2 00:15:47 2007 New Revision: 53622 Modified: sandbox/trunk/import_in_py/importlib.py sandbox/trunk/import_in_py/test_importlib.py Log: Abstract out getting a module from the cache, sys.modules. Allows for more fine-grained control over whether the existence of a module in sys.modules should allow for it to be returned or should be blocked for security reasons. Modified: sandbox/trunk/import_in_py/importlib.py ============================================================================== --- sandbox/trunk/import_in_py/importlib.py (original) +++ sandbox/trunk/import_in_py/importlib.py Fri Feb 2 00:15:47 2007 @@ -692,6 +692,16 @@ return loader else: raise ImportError("No module found named %s" % name) + + def module_from_cache(self, name): + """Try to return the named module from sys.modules. + + Return False if the module is not in the cache. + """ + if name in sys.modules: + return sys.modules[name] + else: + return False def _import_module(self, name, path=None): """Import the specified module with no handling of parent modules. @@ -700,12 +710,12 @@ import was attempted and failed) then ImportError is raised. """ - if name in sys.modules: - value = sys.modules[name] - if value is None: + cached_module = self.module_from_cache(name) + if cached_module is not False: + if cached_module is None: raise ImportError("relative import redirect") else: - return value + return cached_module try: # Attempt to find a loader on sys.meta_path. loader = self._search_meta_path(name, path) Modified: sandbox/trunk/import_in_py/test_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/test_importlib.py (original) +++ sandbox/trunk/import_in_py/test_importlib.py Fri Feb 2 00:15:47 2007 @@ -1141,6 +1141,17 @@ for level in (-1, 0): self.failUnlessRaises(ValueError, self.importer, '', {}, {}, level) + def test_module_from_cache(self): + # If a value is in sys.modules it should be returned (no matter the + # object type), else return False. + value = "a 'module'" + mod_name = "module name" + sys.modules[mod_name] = value + returned = self.importer.module_from_cache(mod_name) + self.failUnless(returned is value) + returned = self.importer.module_from_cache(mod_name + 'asdfeddf') + self.failUnless(returned is False) + class ImportMetaPathTests(ImportHelper): From buildbot at python.org Fri Feb 2 00:26:42 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 01 Feb 2007 23:26:42 +0000 Subject: [Python-checkins] buildbot warnings in x86 Ubuntu edgy (icc) trunk Message-ID: <20070201232642.31A161E4006@bag.python.org> The Buildbot has detected a new failure of x86 Ubuntu edgy (icc) trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520Ubuntu%2520edgy%2520%2528icc%2529%2520trunk/builds/1159 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_timeout sincerely, -The Buildbot From python-checkins at python.org Fri Feb 2 01:27:14 2007 From: python-checkins at python.org (brett.cannon) Date: Fri, 2 Feb 2007 01:27:14 +0100 (CET) Subject: [Python-checkins] r53623 - sandbox/trunk/import_in_py/controlled_importlib.py sandbox/trunk/import_in_py/test_controlled_importlib.py Message-ID: <20070202002714.17FE81E4006@bag.python.org> Author: brett.cannon Date: Fri Feb 2 01:27:13 2007 New Revision: 53623 Added: sandbox/trunk/import_in_py/controlled_importlib.py (contents, props changed) sandbox/trunk/import_in_py/test_controlled_importlib.py (contents, props changed) Log: Begin implementation of a controlling import that usees whitelisting to restrict what can and cannot be imported. Added: sandbox/trunk/import_in_py/controlled_importlib.py ============================================================================== --- (empty file) +++ sandbox/trunk/import_in_py/controlled_importlib.py Fri Feb 2 01:27:13 2007 @@ -0,0 +1,86 @@ +"""Create a controllable import. + +One should be able to do several things to control imports: + + * Whitelisting of modules based on name and type + + built-ins + + frozen + + extensions + * Block all modules based on type + + .pyc + * Allow all modules of a certain type + + .py +""" +import importlib +import sys + +class Whitelister(object): + + """Whitelist the finding and/or loading of modules.""" + + def __init__(self, whitelist, *args, **kwargs): + """Store whitelist and continue on with instantiation.""" + self._whitelist = frozenset(whitelist) + super(Whitelister, self).__init__(*args, **kwargs) + + def check_name(self, name): + """Check a module name against the whitelist, returning True if it + passes or False otherwise.""" + if name in self._whitelist: + return True + return False + + def find_module(self, name, path=None): + """If the module name passes the whitelist, allow the finding of the + modules to continue, otherwise return None.""" + if self.check_name(name): + return super(Whitelister, self).find_module(name, path) + return None + + def load_module(self, name): + """If the module names passes the whitelist, allow the loading of the + module to continue, otherwise raise ImportError.""" + if self.check_name(name): + return super(Whitelister, self).load_module(name) + raise ImportError("cannot import module") + + +class WhitelistBuiltin(Whitelister, importlib.BuiltinImporter): + + """Whitelisting importer/loader for built-in modules.""" + + pass + + +class WhitelistFrozen(Whitelister, importlib.FrozenImporter): + + """Whitelisting importer/loader for frozen modules.""" + + pass + + +class ControlledImport(importlib.Import): + + """Represent a controllable version of import that allows for more + fine-grained control over what can and cannot be imported.""" + + def __init__(self, safe_builtins, safe_frozen, safe_extensions): + """Set up importation where built-in, frozen, and extension modules + must be whitelisted and .pyc files are completely blocked + while all. py files are allowed.""" + # Clear out any traces of the previous import machinery. + sys.path_importer_cache.clear() + # Whitelist built-in and frozen modules on sys.meta_path. + # XXX + # Whitelist extension modules on sys.path. + # XXX + # Allow all .py files but not .pyc files on sys.path. + # XXX + + def module_from_cache(self, name): + """Override so that any module name starting with a dot raises + ImportError.""" + if name.startswith('.'): + raise ImportError("module names starting with '.' cannot be " + "imported") + return importlib.Import.module_from_cache(self, name) Added: sandbox/trunk/import_in_py/test_controlled_importlib.py ============================================================================== --- (empty file) +++ sandbox/trunk/import_in_py/test_controlled_importlib.py Fri Feb 2 01:27:13 2007 @@ -0,0 +1,117 @@ +import controlled_importlib + +import StringIO +import sys +import unittest +from test import test_support + + +class DummyImporterLoader(object): + + def find_module(self, name, path=None): + return True + + def load_module(self, name): + return True + +class DummyWhitelist(controlled_importlib.Whitelister, DummyImporterLoader): + + pass + + +class WhitelistTests(unittest.TestCase): + + """Test the general whitelisting mechanism.""" + + def test_whitelist_module(self): + # A direct module name should be allowed. + whitelist = 'ok_mod' + imp_load = DummyWhitelist([whitelist]) + self.failUnless(imp_load.find_module(whitelist) is True) + self.failUnless(imp_load.find_module('fdssdf') is None) + self.failUnless(imp_load.load_module(whitelist) is True) + self.failUnlessRaises(ImportError, imp_load.load_module, 'asdfadsf') + + def test_whitelist_list(self): + # When the whitelist is a list it should be able to properly whitelist + # no matter where a module is listed. + whitelist1 = 'A' + whitelist2 = 'B' + imp_load = DummyWhitelist([whitelist1, whitelist2]) + for whitelist in (whitelist1, whitelist2): + self.failUnless(imp_load.find_module(whitelist) is True) + self.failUnless(imp_load.load_module(whitelist) is True) + + def test_block_partial_name(self): + # A module that happens to be a prefix of a whitelisted module or has a + # whitelisted module as a prefix should still be blocked. + whitelist = 'mod' + imp_load = DummyWhitelist([whitelist]) + # Module has a whitelisted module as a prefix. + self.failUnless(imp_load.find_module(whitelist+'2') is None) + self.failUnlessRaises(ImportError, imp_load.load_module, whitelist+'2') + # Module is a prefix of a whitelisted module. + self.failUnless(imp_load.find_module(whitelist[:-1]) is None) + self.failUnlessRaises(ImportError, imp_load.load_module, + whitelist[:-1]) + + def test_package(self): + # Whitelisting a package does not automatically allow the submodules. + whitelist = 'pkg' + imp_load = DummyWhitelist([whitelist]) + mod = whitelist + '.' + 'mod' + self.failUnless(imp_load.find_module(mod) is None) + self.failUnlessRaises(ImportError, imp_load.load_module, mod) + + +class WhitelistBuiltinTests(unittest.TestCase): + + """Test the whitelisting support for built-in modules.""" + + def setUp(self): + self.whitelist = sys.builtin_module_names[0] + self.blacklist = sys.builtin_module_names[1] + + def test_whitelist(self): + # Only modules on the whitelist should be allowed to be imported. + # Everything else should return None. + imp_load = controlled_importlib.WhitelistBuiltin([self.whitelist]) + # Importer + self.failUnless(imp_load.find_module(self.whitelist) is not None) + self.failUnless(imp_load.find_module(self.blacklist) is None) + # Loader + self.failUnless(imp_load.load_module(self.whitelist)) + self.failUnlessRaises(ImportError, imp_load.load_module, + self.blacklist) + + +class WhitelistFrozenTests(unittest.TestCase): + + """Test whitelisting of frozen modules.""" + + def setUp(self): + sys.stdout = StringIO.StringIO() + self.whitelist = '__phello__' + self.blacklist = ('__hello__', '__phello__.spam') + + def tearDown(self): + sys.stdout = sys.__stdout__ + + def test_whitelist(self): + imp_load = controlled_importlib.WhitelistFrozen([self.whitelist]) + self.failUnless(imp_load.find_module(self.whitelist) is not None) + self.failUnless(imp_load.load_module(self.whitelist)) + for blacklist in self.blacklist: + self.failUnless(imp_load.find_module(blacklist) is None) + self.failUnlessRaises(ImportError, imp_load.load_module, blacklist) + + + +def test_main(): + test_support.run_unittest(WhitelistTests, + WhitelistBuiltinTests, + WhitelistFrozenTests) + + +if __name__ == '__main__': + test_main() From buildbot at python.org Fri Feb 2 07:41:08 2007 From: buildbot at python.org (buildbot at python.org) Date: Fri, 02 Feb 2007 06:41:08 +0000 Subject: [Python-checkins] buildbot failure in MIPS Debian 2.5 Message-ID: <20070202064108.E5EEE1E4011@bag.python.org> The Buildbot has detected a new failure of MIPS Debian 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/MIPS%2520Debian%25202.5/builds/125 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'James': test Build Source Stamp: [branch sytem] net Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From python-checkins at python.org Fri Feb 2 20:06:37 2007 From: python-checkins at python.org (peter.astrand) Date: Fri, 2 Feb 2007 20:06:37 +0100 (CET) Subject: [Python-checkins] r53624 - python/trunk/Lib/subprocess.py Message-ID: <20070202190637.642981E4009@bag.python.org> Author: peter.astrand Date: Fri Feb 2 20:06:36 2007 New Revision: 53624 Modified: python/trunk/Lib/subprocess.py Log: We had several if statements checking the value of a fd. This is unsafe, since valid fds might be zero. We should check for not None instead. Modified: python/trunk/Lib/subprocess.py ============================================================================== --- python/trunk/Lib/subprocess.py (original) +++ python/trunk/Lib/subprocess.py Fri Feb 2 20:06:36 2007 @@ -592,14 +592,14 @@ c2pread, c2pwrite, errread, errwrite) - if p2cwrite: + if p2cwrite is not None: self.stdin = os.fdopen(p2cwrite, 'wb', bufsize) - if c2pread: + if c2pread is not None: if universal_newlines: self.stdout = os.fdopen(c2pread, 'rU', bufsize) else: self.stdout = os.fdopen(c2pread, 'rb', bufsize) - if errread: + if errread is not None: if universal_newlines: self.stderr = os.fdopen(errread, 'rU', bufsize) else: @@ -986,29 +986,29 @@ # Child try: # Close parent's pipe ends - if p2cwrite: + if p2cwrite is not None: os.close(p2cwrite) - if c2pread: + if c2pread is not None: os.close(c2pread) - if errread: + if errread is not None: os.close(errread) os.close(errpipe_read) # Dup fds for child - if p2cread: + if p2cread is not None: os.dup2(p2cread, 0) - if c2pwrite: + if c2pwrite is not None: os.dup2(c2pwrite, 1) - if errwrite: + if errwrite is not None: os.dup2(errwrite, 2) # Close pipe fds. Make sure we don't close the same # fd more than once, or standard fds. - if p2cread and p2cread not in (0,): + if p2cread is not None and p2cread not in (0,): os.close(p2cread) - if c2pwrite and c2pwrite not in (p2cread, 1): + if c2pwrite is not None and c2pwrite not in (p2cread, 1): os.close(c2pwrite) - if errwrite and errwrite not in (p2cread, c2pwrite, 2): + if errwrite is not None and errwrite not in (p2cread, c2pwrite, 2): os.close(errwrite) # Close all other fds, if asked for @@ -1041,11 +1041,11 @@ # Parent os.close(errpipe_write) - if p2cread and p2cwrite: + if p2cread is not None and p2cwrite is not None: os.close(p2cread) - if c2pwrite and c2pread: + if c2pwrite is not None and c2pread is not None: os.close(c2pwrite) - if errwrite and errread: + if errwrite is not None and errread is not None: os.close(errwrite) # Wait for exec to fail or succeed; possibly raising exception From buildbot at python.org Fri Feb 2 20:46:46 2007 From: buildbot at python.org (buildbot at python.org) Date: Fri, 02 Feb 2007 19:46:46 +0000 Subject: [Python-checkins] buildbot warnings in x86 XP trunk Message-ID: <20070202194646.437171E4012@bag.python.org> The Buildbot has detected a new failure of x86 XP trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520XP%2520trunk/builds/185 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: peter.astrand Build had warnings: warnings failed slave lost sincerely, -The Buildbot From python-checkins at python.org Sat Feb 3 06:18:41 2007 From: python-checkins at python.org (brett.cannon) Date: Sat, 3 Feb 2007 06:18:41 +0100 (CET) Subject: [Python-checkins] r53625 - sandbox/trunk/import_in_py/controlled_importlib.py sandbox/trunk/import_in_py/importlib.py sandbox/trunk/import_in_py/test_controlled_importlib.py sandbox/trunk/import_in_py/test_importlib.py Message-ID: <20070203051841.A079C1E4009@bag.python.org> Author: brett.cannon Date: Sat Feb 3 06:18:40 2007 New Revision: 53625 Modified: sandbox/trunk/import_in_py/controlled_importlib.py sandbox/trunk/import_in_py/importlib.py sandbox/trunk/import_in_py/test_controlled_importlib.py sandbox/trunk/import_in_py/test_importlib.py Log: Add a post-import method. This allows for the stripping of __loader__ from newly imported modules so that the global namespace of the loader is not exposed. Also add tests for module_from_cache. Modified: sandbox/trunk/import_in_py/controlled_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/controlled_importlib.py (original) +++ sandbox/trunk/import_in_py/controlled_importlib.py Sat Feb 3 06:18:40 2007 @@ -84,3 +84,12 @@ raise ImportError("module names starting with '.' cannot be " "imported") return importlib.Import.module_from_cache(self, name) + + def post_import(self, module): + """Strip off the __loader__ attribute so that the object's global + namespace is not exposed.""" + try: + del module.__loader__ + except AttributeError: + pass + return module Modified: sandbox/trunk/import_in_py/importlib.py ============================================================================== --- sandbox/trunk/import_in_py/importlib.py (original) +++ sandbox/trunk/import_in_py/importlib.py Sat Feb 3 06:18:40 2007 @@ -702,6 +702,10 @@ return sys.modules[name] else: return False + + def post_import(self, module): + """Perform any desired post-import processing on the module.""" + return module def _import_module(self, name, path=None): """Import the specified module with no handling of parent modules. @@ -725,7 +729,7 @@ loader = self._search_std_path(name, path) # A loader was found. It is the loader's responsibility to have put an # entry in sys.modules. - return loader.load_module(name) + return self.post_import(loader.load_module(name)) def _import_full_module(self, name): """Import a module along with its parent modules and set into Modified: sandbox/trunk/import_in_py/test_controlled_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/test_controlled_importlib.py (original) +++ sandbox/trunk/import_in_py/test_controlled_importlib.py Sat Feb 3 06:18:40 2007 @@ -1,5 +1,7 @@ import controlled_importlib +import mock_importlib +from contextlib import contextmanager import StringIO import sys import unittest @@ -106,11 +108,77 @@ self.failUnlessRaises(ImportError, imp_load.load_module, blacklist) + at contextmanager +def mutate_sys_modules(module, name): + try: + old_module = sys.modules.get(name) + sys.modules[name] = module + yield + finally: + if old_module: + sys.modules[name] = old_module + else: + del sys.modules[name] + + +class ControlledImportMethodTests(unittest.TestCase): + + """Test explicit methods of ControlledImport.""" + + def setUp(self): + self.import_ = controlled_importlib.ControlledImport([], [], []) + + def test_module_from_cache(self): + # Importing of module names with a leading dot should not occur. + module = 'module' + module_name = '.blocked' + assert module_name.startswith('.') + with mutate_sys_modules(module, module_name): + self.failUnlessRaises(ImportError, self.import_.module_from_cache, + module_name) + + def test_post_import(self): + # Any __loader__ attribute should be indiscriminately removed. + module = mock_importlib.MockModule() + self.failUnless(self.import_.post_import(module) is module) + module.__loader__ = None + stripped_module = self.import_.post_import(module) + self.failUnless(stripped_module is module) + self.failUnless(not hasattr(stripped_module, '__loader__')) + + +class ControlledImportUsageTests(unittest.TestCase): + + """Make sure that usage of ControlledImport works properly.""" + + def test_block_dot_modules(self): + # Modules with a leading dot should not be imported. + pass + + def test_builtin_whitelisting(self): + pass + + def test_frozen_whitelisting(self): + pass + + def test_extension_whitelisting(self): + pass + + def test_pyc_blocking(self): + pass + + def test_py(self): + # XXX try importing something with the same name as a built-in that is + # not whitelisted. + pass + def test_main(): test_support.run_unittest(WhitelistTests, WhitelistBuiltinTests, - WhitelistFrozenTests) + WhitelistFrozenTests, + ControlledImportMethodTests, + ControlledImportUsageTests) if __name__ == '__main__': Modified: sandbox/trunk/import_in_py/test_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/test_importlib.py (original) +++ sandbox/trunk/import_in_py/test_importlib.py Sat Feb 3 06:18:40 2007 @@ -1152,6 +1152,12 @@ returned = self.importer.module_from_cache(mod_name + 'asdfeddf') self.failUnless(returned is False) + def test_post_import(self): + # Post-import processing should do nothing but return the module + # unscathed. + module = "mod" + self.failUnless(self.importer.post_import(module) is module) + class ImportMetaPathTests(ImportHelper): From python-checkins at python.org Sat Feb 3 06:20:26 2007 From: python-checkins at python.org (brett.cannon) Date: Sat, 3 Feb 2007 06:20:26 +0100 (CET) Subject: [Python-checkins] r53626 - sandbox/trunk/import_in_py/test_controlled_importlib.py Message-ID: <20070203052026.E3E761E4009@bag.python.org> Author: brett.cannon Date: Sat Feb 3 06:20:26 2007 New Revision: 53626 Modified: sandbox/trunk/import_in_py/test_controlled_importlib.py Log: Note some specifics on what to test when checking for __loader__ removal in integration tests. Modified: sandbox/trunk/import_in_py/test_controlled_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/test_controlled_importlib.py (original) +++ sandbox/trunk/import_in_py/test_controlled_importlib.py Sat Feb 3 06:20:26 2007 @@ -172,6 +172,10 @@ # not whitelisted. pass + def test_no_loader_attribute(self): + # No __loader__ attribute should be exposed on any module or package. + # XXX check both modules, packages, and submodules. + def test_main(): test_support.run_unittest(WhitelistTests, From python-checkins at python.org Sat Feb 3 23:05:24 2007 From: python-checkins at python.org (brett.cannon) Date: Sat, 3 Feb 2007 23:05:24 +0100 (CET) Subject: [Python-checkins] r53628 - sandbox/trunk/import_in_py/controlled_importlib.py Message-ID: <20070203220524.200391E400A@bag.python.org> Author: brett.cannon Date: Sat Feb 3 23:05:21 2007 New Revision: 53628 Modified: sandbox/trunk/import_in_py/controlled_importlib.py Log: Prep the 'sys' module more in ControlledImport.__init__. Also provide default arguments. Modified: sandbox/trunk/import_in_py/controlled_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/controlled_importlib.py (original) +++ sandbox/trunk/import_in_py/controlled_importlib.py Sat Feb 3 23:05:21 2007 @@ -64,14 +64,18 @@ """Represent a controllable version of import that allows for more fine-grained control over what can and cannot be imported.""" - def __init__(self, safe_builtins, safe_frozen, safe_extensions): + def __init__(self, safe_builtins=(), safe_frozen=(), safe_extensions=()): """Set up importation where built-in, frozen, and extension modules must be whitelisted and .pyc files are completely blocked while all. py files are allowed.""" + importlib.Import.__init__(self, (), ()) # Clear out any traces of the previous import machinery. sys.path_importer_cache.clear() + sys.meta_path = [] + sys.path_hooks = [] # Whitelist built-in and frozen modules on sys.meta_path. - # XXX + sys.meta_path.append(WhitelistBuiltin(safe_builtins)) + sys.meta_path.append(WhitelistFrozen(safe_frozen)) # Whitelist extension modules on sys.path. # XXX # Allow all .py files but not .pyc files on sys.path. From python-checkins at python.org Sat Feb 3 23:08:13 2007 From: python-checkins at python.org (brett.cannon) Date: Sat, 3 Feb 2007 23:08:13 +0100 (CET) Subject: [Python-checkins] r53629 - sandbox/trunk/import_in_py/importlib.py sandbox/trunk/import_in_py/test_importlib.py Message-ID: <20070203220813.D67D41E400A@bag.python.org> Author: brett.cannon Date: Sat Feb 3 23:08:12 2007 New Revision: 53629 Modified: sandbox/trunk/import_in_py/importlib.py sandbox/trunk/import_in_py/test_importlib.py Log: Make the built-in and frozen module meta_path objects not use classmethods. Modified: sandbox/trunk/import_in_py/importlib.py ============================================================================== --- sandbox/trunk/import_in_py/importlib.py (original) +++ sandbox/trunk/import_in_py/importlib.py Sat Feb 3 23:08:12 2007 @@ -158,22 +158,19 @@ """Base class for meta_path importers for built-in and frozen modules. - Subclasses must provide the _find and _load methods. The methods are - expected to be defined on the subclass itself and not on an instance. + Subclasses must provide the _find and _load methods. """ - @classmethod - def find_module(cls, fullname, path=None): + def find_module(self, fullname, path=None): """See if a built-in or frozen module can be imported based on the specified name.""" - if cls._find(fullname): - return cls + if self._find(fullname): + return self else: return None - @classmethod - def load_module(cls, fullname): + def load_module(self, fullname): """Load a built-in or frozen module. 'imp' code for loading a built-in or frozen module handles the setting @@ -184,7 +181,7 @@ try: return sys.modules[fullname] except KeyError: - mod = cls._load(fullname) + mod = self._load(fullname) if not mod: raise ImportError("expected built-in module not loaded") return mod @@ -605,7 +602,7 @@ """ def __init__(self, default_path_hook=None, - extended_meta_path=(BuiltinImporter, FrozenImporter)): + extended_meta_path=(BuiltinImporter(), FrozenImporter())): """Store a default path hook entry and a sequence to internally extend sys.meta_path by.""" self.extended_meta_path = extended_meta_path Modified: sandbox/trunk/import_in_py/test_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/test_importlib.py (original) +++ sandbox/trunk/import_in_py/test_importlib.py Sat Feb 3 23:08:12 2007 @@ -85,7 +85,7 @@ """Test the built-in module importer.""" - importer = importlib.BuiltinImporter + importer = importlib.BuiltinImporter() module_name = 'sys' bad_module_names = ('tokenize', 'time', '__hello__') @@ -100,7 +100,7 @@ """ - importer = importlib.FrozenImporter + importer = importlib.FrozenImporter() module_name = '__hello__' bad_module_names = ('tokenize', 'time', 'sys') From python-checkins at python.org Sat Feb 3 23:09:03 2007 From: python-checkins at python.org (brett.cannon) Date: Sat, 3 Feb 2007 23:09:03 +0100 (CET) Subject: [Python-checkins] r53630 - sandbox/trunk/import_in_py/test_controlled_importlib.py Message-ID: <20070203220903.5D7631E400A@bag.python.org> Author: brett.cannon Date: Sat Feb 3 23:09:02 2007 New Revision: 53630 Modified: sandbox/trunk/import_in_py/test_controlled_importlib.py Log: Test that keys starting with a dot in sys.modules and whitelisting of built-in modules works for ControlledImport. Modified: sandbox/trunk/import_in_py/test_controlled_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/test_controlled_importlib.py (original) +++ sandbox/trunk/import_in_py/test_controlled_importlib.py Sat Feb 3 23:09:02 2007 @@ -110,6 +110,7 @@ @contextmanager def mutate_sys_modules(module, name): + """Temporarily mutate sys.modules with a new module.""" try: old_module = sys.modules.get(name) sys.modules[name] = module @@ -120,6 +121,19 @@ else: del sys.modules[name] + at contextmanager +def remove_from_sys_modules(*modules): + """Temporarily remove modules from sys.modules.""" + try: + cached = [] + for name in modules: + cached.append(sys.modules[name]) + del sys.modules[name] + yield + finally: + for name, module in zip(modules, cached): + sys.modules[name] = module + class ControlledImportMethodTests(unittest.TestCase): @@ -153,10 +167,20 @@ def test_block_dot_modules(self): # Modules with a leading dot should not be imported. - pass + import_ = controlled_importlib.ControlledImport() + module = mock_importlib.MockModule() + module_name = '.block' + with mutate_sys_modules(module, module_name): + self.failUnlessRaises(ImportError, import_, module_name, {}, {}, 0) def test_builtin_whitelisting(self): - pass + whitelist = sys.builtin_module_names[0] + blacklist = sys.builtin_module_names[1] + with remove_from_sys_modules(whitelist, blacklist): + import_ = controlled_importlib.ControlledImport([whitelist]) + module = import_(whitelist, {}, {}, 0) + self.failUnlessEqual(module.__name__, whitelist) + self.failUnlessRaises(ImportError, import_, blacklist, {}, {}, 0) def test_frozen_whitelisting(self): pass @@ -175,6 +199,7 @@ def test_no_loader_attribute(self): # No __loader__ attribute should be exposed on any module or package. # XXX check both modules, packages, and submodules. + pass def test_main(): From python-checkins at python.org Sat Feb 3 23:44:49 2007 From: python-checkins at python.org (brett.cannon) Date: Sat, 3 Feb 2007 23:44:49 +0100 (CET) Subject: [Python-checkins] r53631 - sandbox/trunk/import_in_py/test_controlled_importlib.py Message-ID: <20070203224449.9596F1E400A@bag.python.org> Author: brett.cannon Date: Sat Feb 3 23:44:47 2007 New Revision: 53631 Modified: sandbox/trunk/import_in_py/test_controlled_importlib.py Log: Test whitelisting of frozen modules. Also use frozen modules to test that inra-package relative importing does not break past whitelisting. Modified: sandbox/trunk/import_in_py/test_controlled_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/test_controlled_importlib.py (original) +++ sandbox/trunk/import_in_py/test_controlled_importlib.py Sat Feb 3 23:44:47 2007 @@ -1,7 +1,7 @@ import controlled_importlib import mock_importlib -from contextlib import contextmanager +from contextlib import contextmanager, nested import StringIO import sys import unittest @@ -127,13 +127,25 @@ try: cached = [] for name in modules: - cached.append(sys.modules[name]) - del sys.modules[name] + if name in sys.modules: + cached.append(sys.modules[name]) + del sys.modules[name] yield finally: for name, module in zip(modules, cached): sys.modules[name] = module + at contextmanager +def temp_setattr(obj, attribute, value): + """Temporarily set an attribute on an object.""" + try: + if hasattr(obj, attribute): + old_value = getattr(obj, attribute) + setattr(obj, attribute, value) + yield value + finally: + setattr(obj, attribute, old_value) + class ControlledImportMethodTests(unittest.TestCase): @@ -171,19 +183,27 @@ module = mock_importlib.MockModule() module_name = '.block' with mutate_sys_modules(module, module_name): - self.failUnlessRaises(ImportError, import_, module_name, {}, {}, 0) + self.failUnlessRaises(ImportError, import_, module_name, level=0) def test_builtin_whitelisting(self): whitelist = sys.builtin_module_names[0] blacklist = sys.builtin_module_names[1] with remove_from_sys_modules(whitelist, blacklist): import_ = controlled_importlib.ControlledImport([whitelist]) - module = import_(whitelist, {}, {}, 0) + module = import_(whitelist, level=0) self.failUnlessEqual(module.__name__, whitelist) - self.failUnlessRaises(ImportError, import_, blacklist, {}, {}, 0) + self.failUnlessRaises(ImportError, import_, blacklist, level=0) def test_frozen_whitelisting(self): - pass + whitelist = '__phello__' + blacklist = ('__hello__', '__phello__.spam') + with nested(temp_setattr(sys, 'stdout', StringIO.StringIO()), + remove_from_sys_modules(whitelist, *blacklist)): + import_ = controlled_importlib.ControlledImport((), [whitelist]) + module = import_(whitelist, level=0) + self.failUnlessEqual(module.__name__, whitelist) + for blacklisted in blacklist: + self.failUnlessRaises(ImportError, import_, blacklisted, level=0) def test_extension_whitelisting(self): pass @@ -201,6 +221,20 @@ # XXX check both modules, packages, and submodules. pass + def test_relative_import(self): + # A relative import within a package should not be able to circumvent + # whitelisting. + whitelist ='__phello__' + blacklist = '__phello__.spam' + blacklist_module = blacklist.split('.')[1] + with nested(temp_setattr(sys, 'stdout', StringIO.StringIO()), + remove_from_sys_modules(whitelist, blacklist)): + import_ = controlled_importlib.ControlledImport((), [whitelist]) + pkg = import_(whitelist, level=0) + pkg_fromlist = import_('', pkg.__dict__, {}, [blacklist_module], 1) + assert pkg_fromlist.__name__ == whitelist + self.failUnless(not hasattr(pkg_fromlist, blacklist_module)) + def test_main(): test_support.run_unittest(WhitelistTests, From buildbot at python.org Sun Feb 4 00:31:09 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 03 Feb 2007 23:31:09 +0000 Subject: [Python-checkins] buildbot failure in g4 osx.4 2.5 Message-ID: <20070203233109.30D391E401C@bag.python.org> The Buildbot has detected a new failure of g4 osx.4 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/g4%2520osx.4%25202.5/builds/195 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Adrian': Reilly Build Source Stamp: [branch Dallas] Danny Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Sun Feb 4 00:32:12 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 03 Feb 2007 23:32:12 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.5 Message-ID: <20070203233216.208E41E4020@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520gentoo%25202.5/builds/205 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Eddy': Derick Build Source Stamp: [branch Aubrey] Brody Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Sun Feb 4 00:32:26 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 03 Feb 2007 23:32:26 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 2.5 Message-ID: <20070203233226.71C441E4017@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%2520solaris10%2520gcc%25202.5/builds/197 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Antony': Lawrence Build Source Stamp: [branch Nico] Cale Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Sun Feb 4 00:34:51 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 03 Feb 2007 23:34:51 +0000 Subject: [Python-checkins] buildbot failure in x86 XP 2.5 Message-ID: <20070203233451.4CC051E400A@bag.python.org> The Buildbot has detected a new failure of x86 XP 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520XP%25202.5/builds/107 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Jordan': Amari Build Source Stamp: [branch Dillan] Kristofer Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Sun Feb 4 00:40:24 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 03 Feb 2007 23:40:24 +0000 Subject: [Python-checkins] buildbot failure in x86 OpenBSD 2.5 Message-ID: <20070203234024.7F31A1E400A@bag.python.org> The Buildbot has detected a new failure of x86 OpenBSD 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520OpenBSD%25202.5/builds/187 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Tariq': Lee Build Source Stamp: [branch Michael] Timothy Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Sun Feb 4 00:45:31 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 03 Feb 2007 23:45:31 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 2.5 Message-ID: <20070203234531.666131E400C@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%2520gentoo%25202.5/builds/208 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Morgan': Trevon Build Source Stamp: [branch Lazaro] Cameron Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From python-checkins at python.org Sun Feb 4 02:04:07 2007 From: python-checkins at python.org (brett.cannon) Date: Sun, 4 Feb 2007 02:04:07 +0100 (CET) Subject: [Python-checkins] r53632 - sandbox/trunk/import_in_py/importlib.py sandbox/trunk/import_in_py/test_controlled_importlib.py Message-ID: <20070204010407.305511E400A@bag.python.org> Author: brett.cannon Date: Sun Feb 4 02:04:05 2007 New Revision: 53632 Modified: sandbox/trunk/import_in_py/importlib.py sandbox/trunk/import_in_py/test_controlled_importlib.py Log: Touch up some docstrings and comments. Modified: sandbox/trunk/import_in_py/importlib.py ============================================================================== --- sandbox/trunk/import_in_py/importlib.py (original) +++ sandbox/trunk/import_in_py/importlib.py Sun Feb 4 02:04:05 2007 @@ -270,6 +270,8 @@ If the module's name is dotted then only search for the trailing module's name on the path entry. An importer is already created for each directory in the __path__ attribute for a package. + + 'path' is ignored as that is meant for meta_path entries only. """ tail_module = fullname.rsplit('.', 1)[-1] @@ -462,10 +464,10 @@ package location of 'package'. The loader needs to implement several methods in order to this handler - to be able to load needed data. A key point with some of these methods - is the idea of opaque code objects which are not directly touched by - the handler but are passed back to the loader so as to allow for a way - to keep state: + to be able to load the needed data. A key point with some of these + methods is the idea of opaque code objects which are not directly + touched by the handler but are passed back to the loader so as to allow + for a way to keep state: * split_path(path) Take in an opaque path object and split it into a base path and a Modified: sandbox/trunk/import_in_py/test_controlled_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/test_controlled_importlib.py (original) +++ sandbox/trunk/import_in_py/test_controlled_importlib.py Sun Feb 4 02:04:05 2007 @@ -206,9 +206,11 @@ self.failUnlessRaises(ImportError, import_, blacklisted, level=0) def test_extension_whitelisting(self): + # XXX pass def test_pyc_blocking(self): + # XXX pass def test_py(self): From python-checkins at python.org Sun Feb 4 04:33:46 2007 From: python-checkins at python.org (brett.cannon) Date: Sun, 4 Feb 2007 04:33:46 +0100 (CET) Subject: [Python-checkins] r53633 - sandbox/trunk/import_in_py/importlib.py sandbox/trunk/import_in_py/mock_importlib.py sandbox/trunk/import_in_py/test_importlib.py Message-ID: <20070204033346.03D131E400A@bag.python.org> Author: brett.cannon Date: Sun Feb 4 04:33:38 2007 New Revision: 53633 Modified: sandbox/trunk/import_in_py/importlib.py sandbox/trunk/import_in_py/mock_importlib.py sandbox/trunk/import_in_py/test_importlib.py Log: Add the cannot_handle method for handlers. This gives handlers a way to say they will not handle a module based on its name. This has been introduced for the purpose of allowing a whitelisting of modules based on the handler and not the importer/loader. Modified: sandbox/trunk/import_in_py/importlib.py ============================================================================== --- sandbox/trunk/import_in_py/importlib.py (original) +++ sandbox/trunk/import_in_py/importlib.py Sun Feb 4 04:33:38 2007 @@ -277,6 +277,8 @@ tail_module = fullname.rsplit('.', 1)[-1] package_directory = os.path.join(self.path_entry, tail_module) for handler in self.handlers: + if handler.cannot_handle(fullname): + continue for file_ext in handler.handles: # XXX Backwards-incompatible to use anything but .py/.pyc # files for __init__? @@ -326,6 +328,8 @@ deal with initializing the module passed to it. """ + if self.handler.cannot_handle(fullname): + raise ImportError("cannot load") try: module = self.handler.handle_code(self, fullname, self.file_path, self.package) @@ -424,6 +428,11 @@ else: self.bytecode_handles = bytecode_handles self.handles = self.bytecode_handles + self.source_handles + + def cannot_handle(self, name): + """Allow the handler to tell an importer whether it does not + want to handle a module.""" + return False def new_module(self, name): """Retun a new module to be initialized (with __name__ set).""" @@ -570,6 +579,11 @@ """Set 'handles'.""" self.handles = tuple(suffix[0] for suffix in imp.get_suffixes() if suffix[2] == imp.C_EXTENSION) + + def cannot_handle(self, name): + """Tell an importer whether the handler cannot handle a specific + module.""" + return False def handle_code(self, loader, mod_name, extension_path, package=None): """Import an extension module.""" Modified: sandbox/trunk/import_in_py/mock_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/mock_importlib.py (original) +++ sandbox/trunk/import_in_py/mock_importlib.py Sun Feb 4 04:33:38 2007 @@ -32,6 +32,9 @@ def __init__(self, *handles): self.handles = handles + + def cannot_handle(self, name): + return False def handle_code(self, loader, mod_name, path, package=None): """Mock implementation of a handler. Modified: sandbox/trunk/import_in_py/test_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/test_importlib.py (original) +++ sandbox/trunk/import_in_py/test_importlib.py Sun Feb 4 04:33:38 2007 @@ -495,6 +495,7 @@ def test_sys_module_cleared_on_error(self): # Any entry made for module into sys.modules should be cleared upon error. class RaiseErrorHandler(object): + def cannot_handle(*args): return False def handle_code(*args): raise ImportError @@ -602,6 +603,10 @@ self.failUnlessEqual(self.handler.source_handles, source) self.failUnlessEqual(self.handler.bytecode_handles, bytecode) self.failUnlessEqual(self.handler.handles, bytecode + source) + + def test_cannot_handle(self): + # Should always return False. + self.failUnless(not self.handler.cannot_handle('asdfddss')) def test_new_module(self): # Should return a new module with the proper value for __name__. @@ -796,6 +801,10 @@ self.ext_path = os.path.join(entry, ext_paths[0]) self.module_name = os.path.splitext(os.path.split(self.ext_path)[1])[0] self.loader = mock_importlib.MockHandler() + + def test_cannot_handle(self): + # Should always return False. + self.failUnless(not self.handler.cannot_handle('asdfdd')) def test_handle_code(self): # Make sure an extension module can be loaded. From python-checkins at python.org Mon Feb 5 02:24:26 2007 From: python-checkins at python.org (thomas.wouters) Date: Mon, 5 Feb 2007 02:24:26 +0100 (CET) Subject: [Python-checkins] r53634 - in python/branches/p3yk: Doc/howto/TODO Doc/howto/curses.tex Doc/howto/doanddont.tex Doc/howto/regex.tex Doc/lib/libexcs.tex Doc/lib/libimageop.tex Doc/lib/libmailbox.tex Doc/ref/ref4.tex Doc/tut/tut.tex Doc/whatsnew/whatsnew26.tex Lib/CGIHTTPServer.py Lib/_strptime.py Lib/compiler/pycodegen.py Lib/compiler/transformer.py Lib/cookielib.py Lib/dumbdbm.py Lib/dummy_thread.py Lib/dummy_threading.py Lib/email/charset.py Lib/encodings/aliases.py Lib/ftplib.py Lib/httplib.py Lib/idlelib/CodeContext.py Lib/lib-tk/tkSimpleDialog.py Lib/mailbox.py Lib/platform.py Lib/pty.py Lib/subprocess.py Lib/test/test_cfgparser.py Lib/test/test_compiler.py Lib/test/test_dumbdbm.py Lib/test/test_exceptions.py Lib/test/test_gzip.py Lib/test/test_mailbox.py Lib/test/test_old_mailbox.py Lib/test/test_pep352.py Lib/test/test_pty.py Lib/test/test_resource.py Lib/test/test_set.py Lib/test/test_strptime.py Lib/test/test_struct.py Lib/test/test_support.py Modules/_ctypes/cfield.c Modules/posixmodule.c Objects/setobject.c Python/ceval.c Message-ID: <20070205012426.3D9891E4002@bag.python.org> Author: thomas.wouters Date: Mon Feb 5 02:24:16 2007 New Revision: 53634 Modified: python/branches/p3yk/ (props changed) python/branches/p3yk/Doc/howto/TODO python/branches/p3yk/Doc/howto/curses.tex python/branches/p3yk/Doc/howto/doanddont.tex python/branches/p3yk/Doc/howto/regex.tex python/branches/p3yk/Doc/lib/libexcs.tex python/branches/p3yk/Doc/lib/libimageop.tex python/branches/p3yk/Doc/lib/libmailbox.tex python/branches/p3yk/Doc/ref/ref4.tex python/branches/p3yk/Doc/tut/tut.tex python/branches/p3yk/Doc/whatsnew/whatsnew26.tex python/branches/p3yk/Lib/CGIHTTPServer.py python/branches/p3yk/Lib/_strptime.py python/branches/p3yk/Lib/compiler/pycodegen.py python/branches/p3yk/Lib/compiler/transformer.py python/branches/p3yk/Lib/cookielib.py python/branches/p3yk/Lib/dumbdbm.py python/branches/p3yk/Lib/dummy_thread.py python/branches/p3yk/Lib/dummy_threading.py python/branches/p3yk/Lib/email/charset.py python/branches/p3yk/Lib/encodings/aliases.py python/branches/p3yk/Lib/ftplib.py python/branches/p3yk/Lib/httplib.py python/branches/p3yk/Lib/idlelib/CodeContext.py python/branches/p3yk/Lib/lib-tk/tkSimpleDialog.py python/branches/p3yk/Lib/mailbox.py python/branches/p3yk/Lib/platform.py python/branches/p3yk/Lib/pty.py python/branches/p3yk/Lib/subprocess.py python/branches/p3yk/Lib/test/test_cfgparser.py python/branches/p3yk/Lib/test/test_compiler.py python/branches/p3yk/Lib/test/test_dumbdbm.py python/branches/p3yk/Lib/test/test_exceptions.py python/branches/p3yk/Lib/test/test_gzip.py python/branches/p3yk/Lib/test/test_mailbox.py python/branches/p3yk/Lib/test/test_old_mailbox.py python/branches/p3yk/Lib/test/test_pep352.py python/branches/p3yk/Lib/test/test_pty.py python/branches/p3yk/Lib/test/test_resource.py python/branches/p3yk/Lib/test/test_set.py python/branches/p3yk/Lib/test/test_strptime.py python/branches/p3yk/Lib/test/test_struct.py python/branches/p3yk/Lib/test/test_support.py python/branches/p3yk/Modules/_ctypes/cfield.c python/branches/p3yk/Modules/posixmodule.c python/branches/p3yk/Objects/setobject.c python/branches/p3yk/Python/ceval.c Log: Merged revisions 53538-53622 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r53545 | andrew.kuchling | 2007-01-24 21:06:41 +0100 (Wed, 24 Jan 2007) | 1 line Strengthen warning about using lock() ........ r53556 | thomas.heller | 2007-01-25 19:34:14 +0100 (Thu, 25 Jan 2007) | 3 lines Fix for #1643874: When calling SysAllocString, create a PyCObject which will eventually call SysFreeString to free the BSTR resource. ........ r53563 | andrew.kuchling | 2007-01-25 21:02:13 +0100 (Thu, 25 Jan 2007) | 1 line Add item ........ r53564 | brett.cannon | 2007-01-25 21:22:02 +0100 (Thu, 25 Jan 2007) | 8 lines Fix time.strptime's %U support. Basically rewrote the algorithm to be more generic so that one only has to shift certain values based on whether the week was specified to start on Monday or Sunday. Cut out a lot of edge case code compared to the previous version. Also broke algorithm out into its own function (that is private to the module). Fixes bug #1643943 (thanks Biran Nahas for the report). ........ r53570 | brett.cannon | 2007-01-26 00:30:39 +0100 (Fri, 26 Jan 2007) | 4 lines Remove specific mention of my name and email address from modules. Not really needed and all bug reports should go to the bug tracker, not directly to me. Plus I am not the only person to have edited these files at this point. ........ r53573 | fred.drake | 2007-01-26 17:28:44 +0100 (Fri, 26 Jan 2007) | 1 line fix typo (extraneous ")") ........ r53575 | georg.brandl | 2007-01-27 18:43:02 +0100 (Sat, 27 Jan 2007) | 4 lines Patch #1638243: the compiler package is now able to correctly compile a with statement; previously, executing code containing a with statement compiled by the compiler package crashed the interpreter. ........ r53578 | georg.brandl | 2007-01-27 18:59:42 +0100 (Sat, 27 Jan 2007) | 3 lines Patch #1634778: add missing encoding aliases for iso8859_15 and iso8859_16. ........ r53579 | georg.brandl | 2007-01-27 20:38:50 +0100 (Sat, 27 Jan 2007) | 2 lines Bug #1645944: os.access now returns bool but docstring is not updated ........ r53590 | brett.cannon | 2007-01-28 21:58:00 +0100 (Sun, 28 Jan 2007) | 2 lines Use the thread lock's context manager instead of a try/finally statement. ........ r53591 | brett.cannon | 2007-01-29 05:41:44 +0100 (Mon, 29 Jan 2007) | 2 lines Add a test for slicing an exception. ........ r53594 | andrew.kuchling | 2007-01-29 21:21:43 +0100 (Mon, 29 Jan 2007) | 1 line Minor edits to the curses HOWTO ........ r53596 | andrew.kuchling | 2007-01-29 21:55:40 +0100 (Mon, 29 Jan 2007) | 1 line Various minor edits ........ r53597 | andrew.kuchling | 2007-01-29 22:28:48 +0100 (Mon, 29 Jan 2007) | 1 line More edits ........ r53601 | tim.peters | 2007-01-30 04:03:46 +0100 (Tue, 30 Jan 2007) | 2 lines Whitespace normalization. ........ r53603 | georg.brandl | 2007-01-30 21:21:30 +0100 (Tue, 30 Jan 2007) | 2 lines Bug #1648191: typo in docs. ........ r53605 | brett.cannon | 2007-01-30 22:34:36 +0100 (Tue, 30 Jan 2007) | 8 lines No more raising of string exceptions! The next step of PEP 352 (for 2.6) causes raising a string exception to trigger a TypeError. Trying to catch a string exception raises a DeprecationWarning. References to string exceptions has been removed from the docs since they are now just an error. ........ r53618 | raymond.hettinger | 2007-02-01 22:02:59 +0100 (Thu, 01 Feb 2007) | 1 line Bug #1648179: set.update() not recognizing __iter__ overrides in dict subclasses. ........ Modified: python/branches/p3yk/Doc/howto/TODO ============================================================================== --- python/branches/p3yk/Doc/howto/TODO (original) +++ python/branches/p3yk/Doc/howto/TODO Mon Feb 5 02:24:16 2007 @@ -1,7 +1,7 @@ Short-term tasks: - Quick revision pass to make HOWTOs match the current state of Python: -curses doanddont regex sockets sorting + Quick revision pass to make HOWTOs match the current state of Python +doanddont regex sockets Medium-term tasks: Revisit the regex howto. Modified: python/branches/p3yk/Doc/howto/curses.tex ============================================================================== --- python/branches/p3yk/Doc/howto/curses.tex (original) +++ python/branches/p3yk/Doc/howto/curses.tex Mon Feb 5 02:24:16 2007 @@ -2,7 +2,7 @@ \title{Curses Programming with Python} -\release{2.01} +\release{2.02} \author{A.M. Kuchling, Eric S. Raymond} \authoraddress{\email{amk at amk.ca}, \email{esr at thyrsus.com}} @@ -147,10 +147,10 @@ In Python you can avoid these complications and make debugging much easier by importing the module \module{curses.wrapper}. It supplies a -function \function{wrapper} that takes a hook argument. It does the +\function{wrapper()} function that takes a callable. It does the initializations described above, and also initializes colors if color -support is present. It then runs your hook, and then finally -deinitializes appropriately. The hook is called inside a try-catch +support is present. It then runs your provided callable and finally +deinitializes appropriately. The callable is called inside a try-catch clause which catches exceptions, performs curses deinitialization, and then passes the exception upwards. Thus, your terminal won't be left in a funny state on exception. @@ -159,7 +159,7 @@ Windows are the basic abstraction in curses. A window object represents a rectangular area of the screen, and supports various - methods to display text, erase it, allow the user to input strings, +methods to display text, erase it, allow the user to input strings, and so forth. The \code{stdscr} object returned by the \function{initscr()} function @@ -223,14 +223,14 @@ The \function{refresh()} call displays a section of the pad in the rectangle extending from coordinate (5,5) to coordinate (20,75) on the -screen;the upper left corner of the displayed section is coordinate +screen; the upper left corner of the displayed section is coordinate (0,0) on the pad. Beyond that difference, pads are exactly like ordinary windows and support the same methods. If you have multiple windows and pads on screen there is a more efficient way to go, which will prevent annoying screen flicker at -refresh time. Use the methods \method{noutrefresh()} and/or -\method{noutrefresh()} of each window to update the data structure +refresh time. Use the \method{noutrefresh()} method +of each window to update the data structure representing the desired state of the screen; then change the physical screen to match the desired state in one go with the function \function{doupdate()}. The normal \method{refresh()} method calls @@ -254,9 +254,9 @@ \begin{tableii}{|c|l|}{textrm}{Form}{Description} \lineii{\var{str} or \var{ch}}{Display the string \var{str} or -character \var{ch}} +character \var{ch} at the current position} \lineii{\var{str} or \var{ch}, \var{attr}}{Display the string \var{str} or -character \var{ch}, using attribute \var{attr}} +character \var{ch}, using attribute \var{attr} at the current position} \lineii{\var{y}, \var{x}, \var{str} or \var{ch}} {Move to position \var{y,x} within the window, and display \var{str} or \var{ch}} @@ -271,7 +271,7 @@ The \function{addstr()} function takes a Python string as the value to be displayed, while the \function{addch()} functions take a character, -which can be either a Python string of length 1, or an integer. If +which can be either a Python string of length 1 or an integer. If it's a string, you're limited to displaying characters between 0 and 255. SVr4 curses provides constants for extension characters; these constants are integers greater than 255. For example, @@ -331,15 +331,15 @@ provide it, The most common such terminal is probably the Linux console, followed by color xterms. -To use color, you must call the \function{start_color()} function -soon after calling \function{initscr()}, to initialize the default -color set (the \function{curses.wrapper.wrapper()} function does this +To use color, you must call the \function{start_color()} function soon +after calling \function{initscr()}, to initialize the default color +set (the \function{curses.wrapper.wrapper()} function does this automatically). Once that's done, the \function{has_colors()} function returns TRUE if the terminal in use can actually display -color. (Note from AMK: curses uses the American spelling -'color', instead of the Canadian/British spelling 'colour'. If you're -like me, you'll have to resign yourself to misspelling it for the sake -of these functions.) +color. (Note: curses uses the American spelling 'color', instead of +the Canadian/British spelling 'colour'. If you're used to the British +spelling, you'll have to resign yourself to misspelling it for the +sake of these functions.) The curses library maintains a finite number of color pairs, containing a foreground (or text) color and a background color. You @@ -400,18 +400,19 @@ lack. The most common way to get input to a window is to use its -\method{getch()} method. that pauses, and waits for the user to hit -a key, displaying it if \function{echo()} has been called earlier. -You can optionally specify a coordinate to which the cursor should be -moved before pausing. +\method{getch()} method. \method{getch()} pauses and waits for the +user to hit a key, displaying it if \function{echo()} has been called +earlier. You can optionally specify a coordinate to which the cursor +should be moved before pausing. It's possible to change this behavior with the method \method{nodelay()}. After \method{nodelay(1)}, \method{getch()} for -the window becomes non-blocking and returns ERR (-1) when no input is -ready. There's also a \function{halfdelay()} function, which can be -used to (in effect) set a timer on each \method{getch()}; if no input -becomes available within the number of milliseconds specified as the -argument to \function{halfdelay()}, curses throws an exception. +the window becomes non-blocking and returns \code{curses.ERR} (a value +of -1) when no input is ready. There's also a \function{halfdelay()} +function, which can be used to (in effect) set a timer on each +\method{getch()}; if no input becomes available within the number of +milliseconds specified as the argument to \function{halfdelay()}, +curses raises an exception. The \method{getch()} method returns an integer; if it's between 0 and 255, it represents the ASCII code of the key pressed. Values greater Modified: python/branches/p3yk/Doc/howto/doanddont.tex ============================================================================== --- python/branches/p3yk/Doc/howto/doanddont.tex (original) +++ python/branches/p3yk/Doc/howto/doanddont.tex Mon Feb 5 02:24:16 2007 @@ -32,7 +32,7 @@ \subsubsection{Inside Function Definitions} \code{from module import *} is {\em invalid} inside function definitions. -While many versions of Python do no check for the invalidity, it does not +While many versions of Python do not check for the invalidity, it does not make it more valid, no more then having a smart lawyer makes a man innocent. Do not use it like that ever. Even in versions where it was accepted, it made the function execution slower, because the compiler could not be certain Modified: python/branches/p3yk/Doc/howto/regex.tex ============================================================================== --- python/branches/p3yk/Doc/howto/regex.tex (original) +++ python/branches/p3yk/Doc/howto/regex.tex Mon Feb 5 02:24:16 2007 @@ -34,17 +34,18 @@ The \module{re} module was added in Python 1.5, and provides Perl-style regular expression patterns. Earlier versions of Python came with the \module{regex} module, which provided Emacs-style -patterns. \module{regex} module was removed in Python 2.5. +patterns. The \module{regex} module was removed completely in Python 2.5. -Regular expressions (or REs) are essentially a tiny, highly -specialized programming language embedded inside Python and made -available through the \module{re} module. Using this little language, -you specify the rules for the set of possible strings that you want to -match; this set might contain English sentences, or e-mail addresses, -or TeX commands, or anything you like. You can then ask questions -such as ``Does this string match the pattern?'', or ``Is there a match -for the pattern anywhere in this string?''. You can also use REs to -modify a string or to split it apart in various ways. +Regular expressions (called REs, or regexes, or regex patterns) are +essentially a tiny, highly specialized programming language embedded +inside Python and made available through the \module{re} module. +Using this little language, you specify the rules for the set of +possible strings that you want to match; this set might contain +English sentences, or e-mail addresses, or TeX commands, or anything +you like. You can then ask questions such as ``Does this string match +the pattern?'', or ``Is there a match for the pattern anywhere in this +string?''. You can also use REs to modify a string or to split it +apart in various ways. Regular expression patterns are compiled into a series of bytecodes which are then executed by a matching engine written in C. For @@ -80,11 +81,12 @@ would let this RE match \samp{Test} or \samp{TEST} as well; more about this later.) -There are exceptions to this rule; some characters are -special, and don't match themselves. Instead, they signal that some -out-of-the-ordinary thing should be matched, or they affect other -portions of the RE by repeating them. Much of this document is -devoted to discussing various metacharacters and what they do. +There are exceptions to this rule; some characters are special +\dfn{metacharacters}, and don't match themselves. Instead, they +signal that some out-of-the-ordinary thing should be matched, or they +affect other portions of the RE by repeating them or changing their +meaning. Much of this document is devoted to discussing various +metacharacters and what they do. Here's a complete list of the metacharacters; their meanings will be discussed in the rest of this HOWTO. @@ -111,9 +113,10 @@ usually a metacharacter, but inside a character class it's stripped of its special nature. -You can match the characters not within a range by \dfn{complementing} -the set. This is indicated by including a \character{\^} as the first -character of the class; \character{\^} elsewhere will simply match the +You can match the characters not listed within the class by +\dfn{complementing} the set. This is indicated by including a +\character{\^} as the first character of the class; \character{\^} +outside a character class will simply match the \character{\^} character. For example, \verb|[^5]| will match any character except \character{5}. @@ -176,7 +179,7 @@ For example, \regexp{ca*t} will match \samp{ct} (0 \samp{a} characters), \samp{cat} (1 \samp{a}), \samp{caaat} (3 \samp{a} characters), and so forth. The RE engine has various internal -limitations stemming from the size of C's \code{int} type, that will +limitations stemming from the size of C's \code{int} type that will prevent it from matching over 2 billion \samp{a} characters; you probably don't have enough memory to construct a string that large, so you shouldn't run into that limit. @@ -238,9 +241,9 @@ You can omit either \var{m} or \var{n}; in that case, a reasonable value is assumed for the missing value. Omitting \var{m} is -interpreted as a lower limit of 0, while omitting \var{n} results in an -upper bound of infinity --- actually, the 2 billion limit mentioned -earlier, but that might as well be infinity. +interpreted as a lower limit of 0, while omitting \var{n} results in +an upper bound of infinity --- actually, the upper bound is the +2-billion limit mentioned earlier, but that might as well be infinity. Readers of a reductionist bent may notice that the three other qualifiers can all be expressed using this notation. \regexp{\{0,\}} is the same @@ -285,7 +288,7 @@ no need to bloat the language specification by including them.) Instead, the \module{re} module is simply a C extension module included with Python, just like the \module{socket} or \module{zlib} -module. +modules. Putting REs in strings keeps the Python language simpler, but has one disadvantage which is the topic of the next section. @@ -326,7 +329,7 @@ a string literal prefixed with \character{r}, so \code{r"\e n"} is a two-character string containing \character{\e} and \character{n}, while \code{"\e n"} is a one-character string containing a newline. -Frequently regular expressions will be expressed in Python +Regular expressions will often be written in Python code using this raw string notation. \begin{tableii}{c|c}{code}{Regular String}{Raw string} @@ -368,9 +371,9 @@ \file{redemo.py} can be quite useful when trying to debug a complicated RE. Phil Schwartz's \ulink{Kodos}{http://www.phil-schwartz.com/kodos.spy} is also an interactive -tool for developing and testing RE patterns. This HOWTO will use the -standard Python interpreter for its examples. +tool for developing and testing RE patterns. +This HOWTO uses the standard Python interpreter for its examples. First, run the Python interpreter, import the \module{re} module, and compile a RE: @@ -401,7 +404,7 @@ later use. \begin{verbatim} ->>> m = p.match( 'tempo') +>>> m = p.match('tempo') >>> print m <_sre.SRE_Match object at 80c4f68> \end{verbatim} @@ -472,9 +475,9 @@ \end{verbatim} \method{findall()} has to create the entire list before it can be -returned as the result. In Python 2.2, the \method{finditer()} method -is also available, returning a sequence of \class{MatchObject} instances -as an iterator. +returned as the result. The \method{finditer()} method returns a +sequence of \class{MatchObject} instances as an +iterator.\footnote{Introduced in Python 2.2.2.} \begin{verbatim} >>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...') @@ -491,13 +494,13 @@ \subsection{Module-Level Functions} -You don't have to produce a \class{RegexObject} and call its methods; +You don't have to create a \class{RegexObject} and call its methods; the \module{re} module also provides top-level functions called -\function{match()}, \function{search()}, \function{sub()}, and so -forth. These functions take the same arguments as the corresponding -\class{RegexObject} method, with the RE string added as the first -argument, and still return either \code{None} or a \class{MatchObject} -instance. +\function{match()}, \function{search()}, \function{findall()}, +\function{sub()}, and so forth. These functions take the same +arguments as the corresponding \class{RegexObject} method, with the RE +string added as the first argument, and still return either +\code{None} or a \class{MatchObject} instance. \begin{verbatim} >>> print re.match(r'From\s+', 'Fromage amk') @@ -514,7 +517,7 @@ Should you use these module-level functions, or should you get the \class{RegexObject} and call its methods yourself? That choice depends on how frequently the RE will be used, and on your personal -coding style. If a RE is being used at only one point in the code, +coding style. If the RE is being used at only one point in the code, then the module functions are probably more convenient. If a program contains a lot of regular expressions, or re-uses the same ones in several locations, then it might be worthwhile to collect all the @@ -537,7 +540,7 @@ Compilation flags let you modify some aspects of how regular expressions work. Flags are available in the \module{re} module under -two names, a long name such as \constant{IGNORECASE}, and a short, +two names, a long name such as \constant{IGNORECASE} and a short, one-letter form such as \constant{I}. (If you're familiar with Perl's pattern modifiers, the one-letter forms use the same letters; the short form of \constant{re.VERBOSE} is \constant{re.X}, for example.) @@ -617,7 +620,7 @@ format them. When this flag has been specified, whitespace within the RE string is ignored, except when the whitespace is in a character class or preceded by an unescaped backslash; this lets you organize -and indent the RE more clearly. It also enables you to put comments +and indent the RE more clearly. This flag also lets you put comments within a RE that will be ignored by the engine; comments are marked by a \character{\#} that's neither in a character class or preceded by an unescaped backslash. @@ -629,18 +632,19 @@ charref = re.compile(r""" &[#] # Start of a numeric entity reference ( - [0-9]+[^0-9] # Decimal form - | 0[0-7]+[^0-7] # Octal form - | x[0-9a-fA-F]+[^0-9a-fA-F] # Hexadecimal form + 0[0-7]+ # Octal form + | [0-9]+ # Decimal form + | x[0-9a-fA-F]+ # Hexadecimal form ) + ; # Trailing semicolon """, re.VERBOSE) \end{verbatim} Without the verbose setting, the RE would look like this: \begin{verbatim} -charref = re.compile("&#([0-9]+[^0-9]" - "|0[0-7]+[^0-7]" - "|x[0-9a-fA-F]+[^0-9a-fA-F])") +charref = re.compile("&#(0[0-7]+" + "|[0-9]+" + "|x[0-9a-fA-F]+);") \end{verbatim} In the above example, Python's automatic concatenation of string @@ -722,12 +726,12 @@ \item[\regexp{\e A}] Matches only at the start of the string. When not in \constant{MULTILINE} mode, \regexp{\e A} and \regexp{\^} are -effectively the same. In \constant{MULTILINE} mode, however, they're -different; \regexp{\e A} still matches only at the beginning of the +effectively the same. In \constant{MULTILINE} mode, they're +different: \regexp{\e A} still matches only at the beginning of the string, but \regexp{\^} may match at any location inside the string that follows a newline character. -\item[\regexp{\e Z}]Matches only at the end of the string. +\item[\regexp{\e Z}] Matches only at the end of the string. \item[\regexp{\e b}] Word boundary. This is a zero-width assertion that matches only at the @@ -782,14 +786,23 @@ strings by writing a RE divided into several subgroups which match different components of interest. For example, an RFC-822 header line is divided into a header name and a value, separated by a -\character{:}. This can be handled by writing a regular expression +\character{:}, like this: + +\begin{verbatim} +From: author at example.com +User-Agent: Thunderbird 1.5.0.9 (X11/20061227) +MIME-Version: 1.0 +To: editor at example.com +\end{verbatim} + +This can be handled by writing a regular expression which matches an entire header line, and has one group which matches the header name, and another group which matches the header's value. Groups are marked by the \character{(}, \character{)} metacharacters. \character{(} and \character{)} have much the same meaning as they do in mathematical expressions; they group together the expressions -contained inside them. For example, you can repeat the contents of a +contained inside them, and you can repeat the contents of a group with a repeating qualifier, such as \regexp{*}, \regexp{+}, \regexp{?}, or \regexp{\{\var{m},\var{n}\}}. For example, \regexp{(ab)*} will match zero or more repetitions of \samp{ab}. @@ -881,12 +894,13 @@ syntax for regular expression extensions, so we'll look at that first. Perl 5 added several additional features to standard regular -expressions, and the Python \module{re} module supports most of them. -It would have been difficult to choose new single-keystroke -metacharacters or new special sequences beginning with \samp{\e} to -represent the new features without making Perl's regular expressions -confusingly different from standard REs. If you chose \samp{\&} as a -new metacharacter, for example, old expressions would be assuming that +expressions, and the Python \module{re} module supports most of them. +It would have been difficult to choose new +single-keystroke metacharacters or new special sequences beginning +with \samp{\e} to represent the new features without making Perl's +regular expressions confusingly different from standard REs. If you +chose \samp{\&} as a new metacharacter, for example, old expressions +would be assuming that \samp{\&} was a regular character and wouldn't have escaped it by writing \regexp{\e \&} or \regexp{[\&]}. @@ -913,15 +927,15 @@ to the features that simplify working with groups in complex REs. Since groups are numbered from left to right and a complex expression may use many groups, it can become difficult to keep track of the -correct numbering, and modifying such a complex RE is annoying. -Insert a new group near the beginning, and you change the numbers of +correct numbering. Modifying such a complex RE is annoying, too: +insert a new group near the beginning and you change the numbers of everything that follows it. -First, sometimes you'll want to use a group to collect a part of a -regular expression, but aren't interested in retrieving the group's -contents. You can make this fact explicit by using a non-capturing -group: \regexp{(?:...)}, where you can put any other regular -expression inside the parentheses. +Sometimes you'll want to use a group to collect a part of a regular +expression, but aren't interested in retrieving the group's contents. +You can make this fact explicit by using a non-capturing group: +\regexp{(?:...)}, where you can replace the \regexp{...} +with any other regular expression. \begin{verbatim} >>> m = re.match("([abc])+", "abc") @@ -937,23 +951,23 @@ capturing group; you can put anything inside it, repeat it with a repetition metacharacter such as \samp{*}, and nest it within other groups (capturing or non-capturing). \regexp{(?:...)} is particularly -useful when modifying an existing group, since you can add new groups +useful when modifying an existing pattern, since you can add new groups without changing how all the other groups are numbered. It should be mentioned that there's no performance difference in searching between capturing and non-capturing groups; neither form is any faster than the other. -The second, and more significant, feature is named groups; instead of +A more significant feature is named groups: instead of referring to them by numbers, groups can be referenced by a name. The syntax for a named group is one of the Python-specific extensions: \regexp{(?P<\var{name}>...)}. \var{name} is, obviously, the name of -the group. Except for associating a name with a group, named groups -also behave identically to capturing groups. The \class{MatchObject} -methods that deal with capturing groups all accept either integers, to -refer to groups by number, or a string containing the group name. -Named groups are still given numbers, so you can retrieve information -about a group in two ways: +the group. Named groups also behave exactly like capturing groups, +and additionally associate a name with a group. The +\class{MatchObject} methods that deal with capturing groups all accept +either integers that refer to the group by number or strings that +contain the desired group's name. Named groups are still given +numbers, so you can retrieve information about a group in two ways: \begin{verbatim} >>> p = re.compile(r'(?P\b\w+\b)') @@ -980,11 +994,11 @@ It's obviously much easier to retrieve \code{m.group('zonem')}, instead of having to remember to retrieve group 9. -Since the syntax for backreferences, in an expression like -\regexp{(...)\e 1}, refers to the number of the group there's +The syntax for backreferences in an expression such as +\regexp{(...)\e 1} refers to the number of the group. There's naturally a variant that uses the group name instead of the number. -This is also a Python extension: \regexp{(?P=\var{name})} indicates -that the contents of the group called \var{name} should again be found +This is another Python extension: \regexp{(?P=\var{name})} indicates +that the contents of the group called \var{name} should again be matched at the current point. The regular expression for finding doubled words, \regexp{(\e b\e w+)\e s+\e 1} can also be written as \regexp{(?P\e b\e w+)\e s+(?P=word)}: @@ -1014,11 +1028,11 @@ \emph{doesn't} match at the current position in the string. \end{itemize} -An example will help make this concrete by demonstrating a case -where a lookahead is useful. Consider a simple pattern to match a -filename and split it apart into a base name and an extension, -separated by a \samp{.}. For example, in \samp{news.rc}, \samp{news} -is the base name, and \samp{rc} is the filename's extension. +To make this concrete, let's look at a case where a lookahead is +useful. Consider a simple pattern to match a filename and split it +apart into a base name and an extension, separated by a \samp{.}. For +example, in \samp{news.rc}, \samp{news} is the base name, and +\samp{rc} is the filename's extension. The pattern to match this is quite simple: @@ -1065,12 +1079,12 @@ exclude both \samp{bat} and \samp{exe} as extensions, the pattern would get even more complicated and confusing. -A negative lookahead cuts through all this: +A negative lookahead cuts through all this confusion: \regexp{.*[.](?!bat\$).*\$} % $ -The lookahead means: if the expression \regexp{bat} doesn't match at +The negative lookahead means: if the expression \regexp{bat} doesn't match at this point, try the rest of the pattern; if \regexp{bat\$} does match, the whole pattern will fail. The trailing \regexp{\$} is required to ensure that something like \samp{sample.batch}, where the extension @@ -1087,7 +1101,7 @@ \section{Modifying Strings} Up to this point, we've simply performed searches against a static -string. Regular expressions are also commonly used to modify a string +string. Regular expressions are also commonly used to modify strings in various ways, using the following \class{RegexObject} methods: \begin{tableii}{c|l}{code}{Method/Attribute}{Purpose} Modified: python/branches/p3yk/Doc/lib/libexcs.tex ============================================================================== --- python/branches/p3yk/Doc/lib/libexcs.tex (original) +++ python/branches/p3yk/Doc/lib/libexcs.tex Mon Feb 5 02:24:16 2007 @@ -10,22 +10,6 @@ provided in the built-in namespace as well as the \module{exceptions} module. -\begin{notice} -In past versions of Python string exceptions were supported. In -Python 1.5 and newer versions, all standard exceptions have been -converted to class objects and users are encouraged to do the same. -String exceptions will raise a \code{DeprecationWarning} in Python 2.5 and -newer. -In future versions, support for string exceptions will be removed. - -Two distinct string objects with the same value are considered different -exceptions. This is done to force programmers to use exception names -rather than their string value when specifying exception handlers. -The string value of all built-in exceptions is their name, but this is -not a requirement for user-defined exceptions or exceptions defined by -library modules. -\end{notice} - For class exceptions, in a \keyword{try}\stindex{try} statement with an \keyword{except}\stindex{except} clause that mentions a particular class, that clause also handles any exception classes derived from Modified: python/branches/p3yk/Doc/lib/libimageop.tex ============================================================================== --- python/branches/p3yk/Doc/lib/libimageop.tex (original) +++ python/branches/p3yk/Doc/lib/libimageop.tex Mon Feb 5 02:24:16 2007 @@ -19,7 +19,7 @@ \begin{funcdesc}{crop}{image, psize, width, height, x0, y0, x1, y1} -Return the selected part of \var{image}, which should by +Return the selected part of \var{image}, which should be \var{width} by \var{height} in size and consist of pixels of \var{psize} bytes. \var{x0}, \var{y0}, \var{x1} and \var{y1} are like the \function{gl.lrectread()} parameters, i.e.\ the boundary is Modified: python/branches/p3yk/Doc/lib/libmailbox.tex ============================================================================== --- python/branches/p3yk/Doc/lib/libmailbox.tex (original) +++ python/branches/p3yk/Doc/lib/libmailbox.tex Mon Feb 5 02:24:16 2007 @@ -58,14 +58,18 @@ \exception{KeyError} exception if the corresponding message is subsequently removed. -Be very cautious when modifying mailboxes that might also be changed -by some other process. The safest mailbox format to use for such -tasks is Maildir; try to avoid using single-file formats such as mbox -for concurrent writing. If you're modifying a mailbox, no matter what -the format, you must lock it by calling the \method{lock()} and -\method{unlock()} methods before making any changes. Failing to lock -the mailbox runs the risk of losing data if some other process makes -changes to the mailbox while your Python code is running. +\begin{notice}[warning] +Be very cautious when modifying mailboxes that might be +simultaneously changed by some other process. The safest mailbox +format to use for such tasks is Maildir; try to avoid using +single-file formats such as mbox for concurrent writing. If you're +modifying a mailbox, you +\emph{must} lock it by calling the \method{lock()} and +\method{unlock()} methods \emph{before} reading any messages in the file +or making any changes by adding or deleting a message. Failing to +lock the mailbox runs the risk of losing messages or corrupting the entire +mailbox. +\end{notice} \class{Mailbox} instances have the following methods: Modified: python/branches/p3yk/Doc/ref/ref4.tex ============================================================================== --- python/branches/p3yk/Doc/ref/ref4.tex (original) +++ python/branches/p3yk/Doc/ref/ref4.tex Mon Feb 5 02:24:16 2007 @@ -197,10 +197,6 @@ value can be raised along with the identifying string which can be passed to the handler. -\deprecated{2.5}{String exceptions should not be used in new code. -They will not be supported in a future version of Python. Old code -should be rewritten to use class exceptions instead.} - \begin{notice}[warning] Messages to exceptions are not part of the Python API. Their contents may change from one version of Python to the next without warning and should not Modified: python/branches/p3yk/Doc/tut/tut.tex ============================================================================== --- python/branches/p3yk/Doc/tut/tut.tex (original) +++ python/branches/p3yk/Doc/tut/tut.tex Mon Feb 5 02:24:16 2007 @@ -1991,7 +1991,7 @@ There is a way to remove an item from a list given its index instead of its value: the \keyword{del} statement. This differs from the -\method{pop()}) method which returns a value. The \keyword{del} +\method{pop()} method which returns a value. The \keyword{del} statement can also be used to remove slices from a list or clear the entire list (which we did earlier by assignment of an empty list to the slice). For example: Modified: python/branches/p3yk/Doc/whatsnew/whatsnew26.tex ============================================================================== --- python/branches/p3yk/Doc/whatsnew/whatsnew26.tex (original) +++ python/branches/p3yk/Doc/whatsnew/whatsnew26.tex Mon Feb 5 02:24:16 2007 @@ -72,6 +72,12 @@ This class supports an interface identical to the existing \class{SMTP} class. (Contributed by Monty Taylor.) +\item The \module{test.test_support} module now contains a +\function{EnvironmentVarGuard} context manager that +supports temporarily changing environment variables and +automatically restores them to their old values. +(Contributed by Brett Cannon.) + \end{itemize} Modified: python/branches/p3yk/Lib/CGIHTTPServer.py ============================================================================== --- python/branches/p3yk/Lib/CGIHTTPServer.py (original) +++ python/branches/p3yk/Lib/CGIHTTPServer.py Mon Feb 5 02:24:16 2007 @@ -107,7 +107,7 @@ """Execute a CGI script.""" path = self.path dir, rest = self.cgi_info - + i = path.find('/', len(dir) + 1) while i >= 0: nextdir = path[:i] Modified: python/branches/p3yk/Lib/_strptime.py ============================================================================== --- python/branches/p3yk/Lib/_strptime.py (original) +++ python/branches/p3yk/Lib/_strptime.py Mon Feb 5 02:24:16 2007 @@ -22,9 +22,6 @@ except: from dummy_thread import allocate_lock as _thread_allocate_lock -__author__ = "Brett Cannon" -__email__ = "brett at python.org" - __all__ = ['strptime'] def _getlang(): @@ -273,11 +270,31 @@ _CACHE_MAX_SIZE = 5 # Max number of regexes stored in _regex_cache _regex_cache = {} +def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon): + """Calculate the Julian day based on the year, week of the year, and day of + the week, with week_start_day representing whether the week of the year + assumes the week starts on Sunday or Monday (6 or 0).""" + first_weekday = datetime_date(year, 1, 1).weekday() + # If we are dealing with the %U directive (week starts on Sunday), it's + # easier to just shift the view to Sunday being the first day of the + # week. + if not week_starts_Mon: + first_weekday = (first_weekday + 1) % 7 + day_of_week = (day_of_week + 1) % 7 + # Need to watch out for a week 0 (when the first day of the year is not + # the same as that specified by %U or %W). + week_0_length = (7 - first_weekday) % 7 + if week_of_year == 0: + return 1 + day_of_week - first_weekday + else: + days_to_week = week_0_length + (7 * (week_of_year - 1)) + return 1 + days_to_week + day_of_week + + def strptime(data_string, format="%a %b %d %H:%M:%S %Y"): """Return a time struct based on the input string and the format string.""" global _TimeRE_cache, _regex_cache - _cache_lock.acquire() - try: + with _cache_lock: time_re = _TimeRE_cache locale_time = time_re.locale_time if _getlang() != locale_time.lang: @@ -302,8 +319,6 @@ except IndexError: raise ValueError("stray %% in format '%s'" % format) _regex_cache[format] = format_regex - finally: - _cache_lock.release() found = format_regex.match(data_string) if not found: raise ValueError("time data %r does not match format %r" % @@ -385,10 +400,10 @@ elif group_key in ('U', 'W'): week_of_year = int(found_dict[group_key]) if group_key == 'U': - # U starts week on Sunday + # U starts week on Sunday. week_of_year_start = 6 else: - # W starts week on Monday + # W starts week on Monday. week_of_year_start = 0 elif group_key == 'Z': # Since -1 is default value only need to worry about setting tz if @@ -406,42 +421,20 @@ tz = value break # If we know the week of the year and what day of that week, we can figure - # out the Julian day of the year - # Calculations below assume 0 is a Monday + # out the Julian day of the year. if julian == -1 and week_of_year != -1 and weekday != -1: - # Calculate how many days in week 0 - first_weekday = datetime_date(year, 1, 1).weekday() - preceeding_days = 7 - first_weekday - if preceeding_days == 7: - preceeding_days = 0 - # Adjust for U directive so that calculations are not dependent on - # directive used to figure out week of year - if weekday == 6 and week_of_year_start == 6: - week_of_year -= 1 - # If a year starts and ends on a Monday but a week is specified to - # start on a Sunday we need to up the week to counter-balance the fact - # that with %W that first Monday starts week 1 while with %U that is - # week 0 and thus shifts everything by a week - if weekday == 0 and first_weekday == 0 and week_of_year_start == 6: - week_of_year += 1 - # If in week 0, then just figure out how many days from Jan 1 to day of - # week specified, else calculate by multiplying week of year by 7, - # adding in days in week 0, and the number of days from Monday to the - # day of the week - if week_of_year == 0: - julian = 1 + weekday - first_weekday - else: - days_to_week = preceeding_days + (7 * (week_of_year - 1)) - julian = 1 + days_to_week + weekday + week_starts_Mon = True if week_of_year_start == 0 else False + julian = _calc_julian_from_U_or_W(year, week_of_year, weekday, + week_starts_Mon) # Cannot pre-calculate datetime_date() since can change in Julian - #calculation and thus could have different value for the day of the week - #calculation + # 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 + # be accurate. datetime_result = datetime_date.fromordinal((julian - 1) + datetime_date(year, 1, 1).toordinal()) year = datetime_result.year month = datetime_result.month Modified: python/branches/p3yk/Lib/compiler/pycodegen.py ============================================================================== --- python/branches/p3yk/Lib/compiler/pycodegen.py (original) +++ python/branches/p3yk/Lib/compiler/pycodegen.py Mon Feb 5 02:24:16 2007 @@ -914,6 +914,8 @@ self.emit('LOAD_CONST', None) self.nextBlock(final) self.setups.push((END_FINALLY, final)) + self._implicitNameOp('LOAD', exitvar) + self._implicitNameOp('DELETE', exitvar) self.emit('WITH_CLEANUP') self.emit('END_FINALLY') self.setups.pop() Modified: python/branches/p3yk/Lib/compiler/transformer.py ============================================================================== --- python/branches/p3yk/Lib/compiler/transformer.py (original) +++ python/branches/p3yk/Lib/compiler/transformer.py Mon Feb 5 02:24:16 2007 @@ -1018,7 +1018,7 @@ if nodelist[2][0] == token.COLON: var = None else: - var = self.com_node(nodelist[2]) + var = self.com_assign(nodelist[2][2], OP_ASSIGN) return With(expr, var, body, lineno=nodelist[0][2]) def com_with_var(self, nodelist): Modified: python/branches/p3yk/Lib/cookielib.py ============================================================================== --- python/branches/p3yk/Lib/cookielib.py (original) +++ python/branches/p3yk/Lib/cookielib.py Mon Feb 5 02:24:16 2007 @@ -1318,26 +1318,26 @@ self._cookies_lock.acquire() try: - self._policy._now = self._now = int(time.time()) + self._policy._now = self._now = int(time.time()) + + cookies = self._cookies_for_request(request) - cookies = self._cookies_for_request(request) + attrs = self._cookie_attrs(cookies) + if attrs: + if not request.has_header("Cookie"): + request.add_unredirected_header( + "Cookie", "; ".join(attrs)) + + # if necessary, advertise that we know RFC 2965 + if (self._policy.rfc2965 and not self._policy.hide_cookie2 and + not request.has_header("Cookie2")): + for cookie in cookies: + if cookie.version != 1: + request.add_unredirected_header("Cookie2", '$Version="1"') + break - attrs = self._cookie_attrs(cookies) - if attrs: - if not request.has_header("Cookie"): - request.add_unredirected_header( - "Cookie", "; ".join(attrs)) - - # if necessary, advertise that we know RFC 2965 - if (self._policy.rfc2965 and not self._policy.hide_cookie2 and - not request.has_header("Cookie2")): - for cookie in cookies: - if cookie.version != 1: - request.add_unredirected_header("Cookie2", '$Version="1"') - break - finally: - self._cookies_lock.release() + self._cookies_lock.release() self.clear_expired_cookies() @@ -1609,7 +1609,7 @@ if self._policy.set_ok(cookie, request): self.set_cookie(cookie) - + finally: self._cookies_lock.release() @@ -1632,14 +1632,14 @@ _debug("extract_cookies: %s", response.info()) self._cookies_lock.acquire() try: - self._policy._now = self._now = int(time.time()) + self._policy._now = self._now = int(time.time()) - for cookie in self.make_cookies(response, request): - if self._policy.set_ok(cookie, request): - _debug(" setting cookie: %s", cookie) - self.set_cookie(cookie) + for cookie in self.make_cookies(response, request): + if self._policy.set_ok(cookie, request): + _debug(" setting cookie: %s", cookie) + self.set_cookie(cookie) finally: - self._cookies_lock.release() + self._cookies_lock.release() def clear(self, domain=None, path=None, name=None): """Clear some cookies. @@ -1677,11 +1677,11 @@ """ self._cookies_lock.acquire() try: - for cookie in self: - if cookie.discard: - self.clear(cookie.domain, cookie.path, cookie.name) + for cookie in self: + if cookie.discard: + self.clear(cookie.domain, cookie.path, cookie.name) finally: - self._cookies_lock.release() + self._cookies_lock.release() def clear_expired_cookies(self): """Discard all expired cookies. @@ -1695,12 +1695,12 @@ """ self._cookies_lock.acquire() try: - now = time.time() - for cookie in self: - if cookie.is_expired(now): - self.clear(cookie.domain, cookie.path, cookie.name) + now = time.time() + for cookie in self: + if cookie.is_expired(now): + self.clear(cookie.domain, cookie.path, cookie.name) finally: - self._cookies_lock.release() + self._cookies_lock.release() def __iter__(self): return deepvalues(self._cookies) @@ -1774,16 +1774,16 @@ self._cookies_lock.acquire() try: - old_state = copy.deepcopy(self._cookies) - self._cookies = {} - try: - self.load(filename, ignore_discard, ignore_expires) - except (LoadError, IOError): - self._cookies = old_state - raise + old_state = copy.deepcopy(self._cookies) + self._cookies = {} + try: + self.load(filename, ignore_discard, ignore_expires) + except (LoadError, IOError): + self._cookies = old_state + raise finally: - self._cookies_lock.release() + self._cookies_lock.release() from _LWPCookieJar import LWPCookieJar, lwp_cookie_str from _MozillaCookieJar import MozillaCookieJar Modified: python/branches/p3yk/Lib/dumbdbm.py ============================================================================== --- python/branches/p3yk/Lib/dumbdbm.py (original) +++ python/branches/p3yk/Lib/dumbdbm.py Mon Feb 5 02:24:16 2007 @@ -243,5 +243,5 @@ else: # Turn off any bits that are set in the umask mode = mode & (~um) - + return _Database(file, mode) Modified: python/branches/p3yk/Lib/dummy_thread.py ============================================================================== --- python/branches/p3yk/Lib/dummy_thread.py (original) +++ python/branches/p3yk/Lib/dummy_thread.py Mon Feb 5 02:24:16 2007 @@ -11,11 +11,8 @@ import dummy_thread as thread """ -__author__ = "Brett Cannon" -__email__ = "brett at python.org" - -# Exports only things specified by thread documentation -# (skipping obsolete synonyms allocate(), start_new(), exit_thread()) +# Exports only things specified by thread documentation; +# skipping obsolete synonyms allocate(), start_new(), exit_thread(). __all__ = ['error', 'start_new_thread', 'exit', 'get_ident', 'allocate_lock', 'interrupt_main', 'LockType'] Modified: python/branches/p3yk/Lib/dummy_threading.py ============================================================================== --- python/branches/p3yk/Lib/dummy_threading.py (original) +++ python/branches/p3yk/Lib/dummy_threading.py Mon Feb 5 02:24:16 2007 @@ -5,11 +5,6 @@ directly imported it would have made all subsequent imports succeed regardless of whether ``thread`` was available which is not desired. -:Author: Brett Cannon -:Contact: brett at python.org - -XXX: Try to get rid of ``_dummy_threading``. - """ from sys import modules as sys_modules Modified: python/branches/p3yk/Lib/email/charset.py ============================================================================== --- python/branches/p3yk/Lib/email/charset.py (original) +++ python/branches/p3yk/Lib/email/charset.py Mon Feb 5 02:24:16 2007 @@ -46,6 +46,7 @@ 'iso-8859-13': (QP, QP, None), 'iso-8859-14': (QP, QP, None), 'iso-8859-15': (QP, QP, None), + 'iso-8859-16': (QP, QP, None), 'windows-1252':(QP, QP, None), 'viscii': (QP, QP, None), 'us-ascii': (None, None, None), @@ -81,6 +82,8 @@ 'latin-8': 'iso-8859-14', 'latin_9': 'iso-8859-15', 'latin-9': 'iso-8859-15', + 'latin_10':'iso-8859-16', + 'latin-10':'iso-8859-16', 'cp949': 'ks_c_5601-1987', 'euc_jp': 'euc-jp', 'euc_kr': 'euc-kr', Modified: python/branches/p3yk/Lib/encodings/aliases.py ============================================================================== --- python/branches/p3yk/Lib/encodings/aliases.py (original) +++ python/branches/p3yk/Lib/encodings/aliases.py Mon Feb 5 02:24:16 2007 @@ -301,6 +301,8 @@ # iso8859_13 codec 'iso_8859_13' : 'iso8859_13', + 'l7' : 'iso8859_13', + 'latin7' : 'iso8859_13', # iso8859_14 codec 'iso_8859_14' : 'iso8859_14', @@ -312,6 +314,8 @@ # iso8859_15 codec 'iso_8859_15' : 'iso8859_15', + 'l9' : 'iso8859_15', + 'latin9' : 'iso8859_15', # iso8859_16 codec 'iso_8859_16' : 'iso8859_16', Modified: python/branches/p3yk/Lib/ftplib.py ============================================================================== --- python/branches/p3yk/Lib/ftplib.py (original) +++ python/branches/p3yk/Lib/ftplib.py Mon Feb 5 02:24:16 2007 @@ -333,7 +333,7 @@ # 1xx or error messages for LIST), so we just discard # this response. if resp[0] == '2': - resp = self.getresp() + resp = self.getresp() if resp[0] != '1': raise error_reply, resp else: @@ -343,7 +343,7 @@ resp = self.sendcmd(cmd) # See above. if resp[0] == '2': - resp = self.getresp() + resp = self.getresp() if resp[0] != '1': raise error_reply, resp conn, sockaddr = sock.accept() Modified: python/branches/p3yk/Lib/httplib.py ============================================================================== --- python/branches/p3yk/Lib/httplib.py (original) +++ python/branches/p3yk/Lib/httplib.py Mon Feb 5 02:24:16 2007 @@ -899,7 +899,7 @@ except (AttributeError, OSError): # Don't send a length if this failed if self.debuglevel > 0: print "Cannot stat!!" - + if thelen is not None: self.putheader('Content-Length',thelen) for hdr, value in headers.iteritems(): Modified: python/branches/p3yk/Lib/idlelib/CodeContext.py ============================================================================== --- python/branches/p3yk/Lib/idlelib/CodeContext.py (original) +++ python/branches/p3yk/Lib/idlelib/CodeContext.py Mon Feb 5 02:24:16 2007 @@ -71,7 +71,7 @@ # # To avoid possible errors, all references to the inner workings # of Tk are executed inside try/except blocks. - + widgets_for_width_calc = self.editwin.text, self.editwin.text_frame # calculate the required vertical padding @@ -113,7 +113,7 @@ # above it. self.label.pack(side="top", fill="x", expand=False, before=self.editwin.text_frame) - + else: self.label.destroy() self.label = None Modified: python/branches/p3yk/Lib/lib-tk/tkSimpleDialog.py ============================================================================== --- python/branches/p3yk/Lib/lib-tk/tkSimpleDialog.py (original) +++ python/branches/p3yk/Lib/lib-tk/tkSimpleDialog.py Mon Feb 5 02:24:16 2007 @@ -50,9 +50,9 @@ # If the master is not viewable, don't # make the child transient, or else it # would be opened withdrawn - if parent.winfo_viewable(): + if parent.winfo_viewable(): self.transient(parent) - + if title: self.title(title) Modified: python/branches/p3yk/Lib/mailbox.py ============================================================================== --- python/branches/p3yk/Lib/mailbox.py (original) +++ python/branches/p3yk/Lib/mailbox.py Mon Feb 5 02:24:16 2007 @@ -569,7 +569,7 @@ # already have been generated (and presumably has been modified # by adding or deleting an item). assert self._toc is not None - + # Check length of self._file; if it's changed, some other process # has modified the mailbox since we scanned it. self._file.seek(0, 2) @@ -578,7 +578,7 @@ raise ExternalClashError('Size of mailbox file changed ' '(expected %i, found %i)' % (self._file_length, cur_len)) - + new_file = _create_temporary(self._path) try: new_toc = {} @@ -1219,7 +1219,7 @@ self._next_key = len(self._toc) self._file.seek(0, 2) self._file_length = self._file.tell() - + def _pre_mailbox_hook(self, f): """Called before writing the mailbox to file f.""" f.write('BABYL OPTIONS:%sVersion: 5%sLabels:%s%s\037' % Modified: python/branches/p3yk/Lib/platform.py ============================================================================== --- python/branches/p3yk/Lib/platform.py (original) +++ python/branches/p3yk/Lib/platform.py Mon Feb 5 02:24:16 2007 @@ -236,7 +236,7 @@ '[^(]*(?:\((.+)\))?') # See also http://www.novell.com/coolsolutions/feature/11251.html -# and http://linuxmafia.com/faq/Admin/release-files.html +# and http://linuxmafia.com/faq/Admin/release-files.html # and http://data.linux-ntfs.org/rpm/whichrpm # and http://www.die.net/doc/linux/man/man1/lsb_release.1.html @@ -245,7 +245,7 @@ 'gentoo', 'UnitedLinux') def _parse_release_file(firstline): - + # Parse the first line m = _lsb_release_version.match(firstline) if m is not None: @@ -268,7 +268,7 @@ return '', version, id def _test_parse_release_file(): - + for input, output in ( # Examples of release file contents: ('SuSE Linux 9.3 (x86-64)', ('SuSE Linux ', '9.3', 'x86-64')) @@ -324,7 +324,7 @@ break else: return _dist_try_harder(distname,version,id) - + # Read the first line f = open('/etc/'+file, 'r') firstline = f.readline() @@ -340,7 +340,7 @@ return distname, version, id # To maintain backwards compatibility: - + def dist(distname='',version='',id='', supported_dists=_supported_dists): @@ -1358,7 +1358,7 @@ If not available, an empty string is returned. """ - + return _sys_version()[2] def python_revision(): Modified: python/branches/p3yk/Lib/pty.py ============================================================================== --- python/branches/p3yk/Lib/pty.py (original) +++ python/branches/p3yk/Lib/pty.py Mon Feb 5 02:24:16 2007 @@ -123,7 +123,7 @@ os.close(tmp_fd) else: os.close(slave_fd) - + # Parent and child process. return pid, master_fd Modified: python/branches/p3yk/Lib/subprocess.py ============================================================================== --- python/branches/p3yk/Lib/subprocess.py (original) +++ python/branches/p3yk/Lib/subprocess.py Mon Feb 5 02:24:16 2007 @@ -1121,7 +1121,7 @@ # we can write up to PIPE_BUF bytes without risk # blocking. POSIX defines PIPE_BUF >= 512 bytes_written = os.write(self.stdin.fileno(), buffer(input, input_offset, 512)) - input_offset += bytes_written + input_offset += bytes_written if input_offset >= len(input): self.stdin.close() write_set.remove(self.stdin) Modified: python/branches/p3yk/Lib/test/test_cfgparser.py ============================================================================== --- python/branches/p3yk/Lib/test/test_cfgparser.py (original) +++ python/branches/p3yk/Lib/test/test_cfgparser.py Mon Feb 5 02:24:16 2007 @@ -15,7 +15,7 @@ result = self.data.keys() result.sort() return result - + def values(self): result = self.items() return [i[1] for i in values] @@ -446,12 +446,12 @@ "o2=3\n" "o1=4\n" "[a]\n" - "k=v\n") + "k=v\n") output = StringIO.StringIO() self.cf.write(output) self.assertEquals(output.getvalue(), "[a]\n" - "k = v\n\n" + "k = v\n\n" "[b]\n" "o1 = 4\n" "o2 = 3\n" Modified: python/branches/p3yk/Lib/test/test_compiler.py ============================================================================== --- python/branches/p3yk/Lib/test/test_compiler.py (original) +++ python/branches/p3yk/Lib/test/test_compiler.py Mon Feb 5 02:24:16 2007 @@ -7,6 +7,12 @@ # How much time in seconds can pass before we print a 'Still working' message. _PRINT_WORKING_MSG_INTERVAL = 5 * 60 +class TrivialContext(object): + def __enter__(self): + return self + def __exit__(self, *exc_info): + pass + class CompilerTest(unittest.TestCase): def testCompileLibrary(self): @@ -157,6 +163,31 @@ exec(c, dct) self.assertEquals(dct['f'].func_annotations, expected) + def testWith(self): + # SF bug 1638243 + c = compiler.compile('from __future__ import with_statement\n' + 'def f():\n' + ' with TrivialContext():\n' + ' return 1\n' + 'result = f()', + '', + 'exec' ) + dct = {'TrivialContext': TrivialContext} + exec(c, dct) + self.assertEquals(dct.get('result'), 1) + + def testWithAss(self): + c = compiler.compile('from __future__ import with_statement\n' + 'def f():\n' + ' with TrivialContext() as tc:\n' + ' return 1\n' + 'result = f()', + '', + 'exec' ) + dct = {'TrivialContext': TrivialContext} + exec(c, dct) + self.assertEquals(dct.get('result'), 1) + NOLINENO = (compiler.ast.Module, compiler.ast.Stmt, compiler.ast.Discard) Modified: python/branches/p3yk/Lib/test/test_dumbdbm.py ============================================================================== --- python/branches/p3yk/Lib/test/test_dumbdbm.py (original) +++ python/branches/p3yk/Lib/test/test_dumbdbm.py Mon Feb 5 02:24:16 2007 @@ -49,7 +49,7 @@ f.close() finally: os.umask(old_umask) - + expected_mode = 0635 if os.name != 'posix': # Windows only supports setting the read-only attribute. @@ -61,7 +61,7 @@ self.assertEqual(stat.S_IMODE(st.st_mode), expected_mode) st = os.stat(_fname + '.dir') self.assertEqual(stat.S_IMODE(st.st_mode), expected_mode) - + def test_close_twice(self): f = dumbdbm.open(_fname) f['a'] = 'b' Modified: python/branches/p3yk/Lib/test/test_exceptions.py ============================================================================== --- python/branches/p3yk/Lib/test/test_exceptions.py (original) +++ python/branches/p3yk/Lib/test/test_exceptions.py Mon Feb 5 02:24:16 2007 @@ -311,6 +311,13 @@ 'pickled "%r", attribute "%s' % (e, checkArgName)) + def testSlicing(self): + # Test that you can slice an exception directly instead of requiring + # going through the 'args' attribute. + args = (1, 2, 3) + exc = BaseException(*args) + self.failUnlessEqual(exc[:], args) + def testKeywordArgs(self): # test that builtin exception don't take keyword args, # but user-defined subclasses can if they want Modified: python/branches/p3yk/Lib/test/test_gzip.py ============================================================================== --- python/branches/p3yk/Lib/test/test_gzip.py (original) +++ python/branches/p3yk/Lib/test/test_gzip.py Mon Feb 5 02:24:16 2007 @@ -138,7 +138,7 @@ y = f.read(10) f.close() self.assertEquals(y, data1[20:30]) - + def test_seek_write(self): # Try seek, write test f = gzip.GzipFile(self.filename, 'w') Modified: python/branches/p3yk/Lib/test/test_mailbox.py ============================================================================== --- python/branches/p3yk/Lib/test/test_mailbox.py (original) +++ python/branches/p3yk/Lib/test/test_mailbox.py Mon Feb 5 02:24:16 2007 @@ -674,11 +674,11 @@ box = self._factory(self._path, factory=dummy_factory) folder = box.add_folder('folder1') self.assert_(folder._factory is dummy_factory) - + folder1_alias = box.get_folder('folder1') self.assert_(folder1_alias._factory is dummy_factory) - + class _TestMboxMMDF(TestMailbox): @@ -798,7 +798,7 @@ def dummy_factory (s): return None self._box = self._factory(self._path, dummy_factory) - + new_folder = self._box.add_folder('foo.bar') folder0 = self._box.get_folder('foo.bar') folder0.add(self._template % 'bar') @@ -894,7 +894,7 @@ self.assert_(self._box.get_sequences() == {'foo':[1, 2, 3, 4, 5], 'unseen':[1], 'bar':[3], 'replied':[3]}) - + def _get_lock_path(self): return os.path.join(self._path, '.mh_sequences.lock') Modified: python/branches/p3yk/Lib/test/test_old_mailbox.py ============================================================================== --- python/branches/p3yk/Lib/test/test_old_mailbox.py (original) +++ python/branches/p3yk/Lib/test/test_old_mailbox.py Mon Feb 5 02:24:16 2007 @@ -116,7 +116,7 @@ def tearDown(self): os.unlink(self._path) - + def test_from_regex (self): # Testing new regex from bug #1633678 f = open(self._path, 'w') Modified: python/branches/p3yk/Lib/test/test_pep352.py ============================================================================== --- python/branches/p3yk/Lib/test/test_pep352.py (original) +++ python/branches/p3yk/Lib/test/test_pep352.py Mon Feb 5 02:24:16 2007 @@ -2,7 +2,7 @@ import __builtin__ import exceptions import warnings -from test.test_support import run_unittest +from test.test_support import run_unittest, guard_warnings_filter import os from platform import system as platform_system @@ -113,13 +113,11 @@ """Test usage of exceptions""" - def setUp(self): - self._filters = warnings.filters[:] - - def tearDown(self): - warnings.filters = self._filters[:] - def test_raise_new_style_non_exception(self): + # You cannot raise a new-style class that does not inherit from + # BaseException; the ability was not possible until BaseException's + # introduction so no need to support new-style objects that do not + # inherit from it. class NewStyleClass(object): pass try: @@ -127,13 +125,51 @@ except TypeError: pass except: - self.fail("unable to raise new-style class") + self.fail("able to raise new-style class") try: raise NewStyleClass() except TypeError: pass except: - self.fail("unable to raise new-style class instance") + self.fail("able to raise new-style class instance") + + def test_raise_string(self): + # Raising a string raises TypeError. + try: + raise "spam" + except TypeError: + pass + except: + self.fail("was able to raise a string exception") + + def test_catch_string(self): + # Catching a string should trigger a DeprecationWarning. + with guard_warnings_filter(): + warnings.resetwarnings() + warnings.filterwarnings("error") + str_exc = "spam" + try: + try: + raise StandardError + except str_exc: + pass + except DeprecationWarning: + pass + except StandardError: + self.fail("catching a string exception did not raise " + "DeprecationWarning") + # Make sure that even if the string exception is listed in a tuple + # that a warning is raised. + try: + try: + raise StandardError + except (AssertionError, str_exc): + pass + except DeprecationWarning: + pass + except StandardError: + self.fail("catching a string exception specified in a tuple did " + "not raise DeprecationWarning") def test_main(): run_unittest(ExceptionClassTests, UsageTests) Modified: python/branches/p3yk/Lib/test/test_pty.py ============================================================================== --- python/branches/p3yk/Lib/test/test_pty.py (original) +++ python/branches/p3yk/Lib/test/test_pty.py Mon Feb 5 02:24:16 2007 @@ -120,7 +120,7 @@ ##if False and lines != ['In child, calling os.setsid()', ## 'Good: OSError was raised.', '']: ## raise TestFailed("Unexpected output from child: %r" % line) - + (pid, status) = os.waitpid(pid, 0) res = status >> 8 debug("Child (%d) exited with status %d (%d)."%(pid, res, status)) @@ -140,8 +140,8 @@ ## pass ##else: ## raise TestFailed("Read from master_fd did not raise exception") - - + + os.close(master_fd) # pty.fork() passed. Modified: python/branches/p3yk/Lib/test/test_resource.py ============================================================================== --- python/branches/p3yk/Lib/test/test_resource.py (original) +++ python/branches/p3yk/Lib/test/test_resource.py Mon Feb 5 02:24:16 2007 @@ -15,7 +15,7 @@ self.assertRaises(TypeError, resource.setrlimit, 42, 42, 42) def test_fsize_ismax(self): - + try: (cur, max) = resource.getrlimit(resource.RLIMIT_FSIZE) except AttributeError: @@ -39,7 +39,7 @@ # versions of Python were terminated by an uncaught SIGXFSZ, but # pythonrun.c has been fixed to ignore that exception. If so, the # write() should return EFBIG when the limit is exceeded. - + # At least one platform has an unlimited RLIMIT_FSIZE and attempts # to change it raise ValueError instead. try: Modified: python/branches/p3yk/Lib/test/test_set.py ============================================================================== --- python/branches/p3yk/Lib/test/test_set.py (original) +++ python/branches/p3yk/Lib/test/test_set.py Mon Feb 5 02:24:16 2007 @@ -481,7 +481,7 @@ set.__init__(self, iterable) class TestSetSubclassWithKeywordArgs(TestSet): - + def test_keywords_in_subclass(self): 'SF bug #1486663 -- this used to erroneously raise a TypeError' SetSubclassWithKeywordArgs(newarg=1) @@ -1464,7 +1464,7 @@ test_classes = ( TestSet, TestSetSubclass, - TestSetSubclassWithKeywordArgs, + TestSetSubclassWithKeywordArgs, TestFrozenSet, TestFrozenSetSubclass, TestSetOfSets, Modified: python/branches/p3yk/Lib/test/test_strptime.py ============================================================================== --- python/branches/p3yk/Lib/test/test_strptime.py (original) +++ python/branches/p3yk/Lib/test/test_strptime.py Mon Feb 5 02:24:16 2007 @@ -463,6 +463,10 @@ "of the year") test_helper((1917, 12, 31), "Dec 31 on Monday with year starting and " "ending on Monday") + test_helper((2007, 01, 07), "First Sunday of 2007") + test_helper((2007, 01, 14), "Second Sunday of 2007") + test_helper((2006, 12, 31), "Last Sunday of 2006") + test_helper((2006, 12, 24), "Second to last Sunday of 2006") class CacheTests(unittest.TestCase): Modified: python/branches/p3yk/Lib/test/test_struct.py ============================================================================== --- python/branches/p3yk/Lib/test/test_struct.py (original) +++ python/branches/p3yk/Lib/test/test_struct.py Mon Feb 5 02:24:16 2007 @@ -119,7 +119,7 @@ cp, bp, hp, ip, lp, fp, dp, tp = struct.unpack(format, s) if (cp != c or bp != b or hp != h or ip != i or lp != l or int(100 * fp) != int(100 * f) or int(100 * dp) != int(100 * d) or - tp != t): + tp != t): # ^^^ calculate only to two decimal places raise TestFailed, "unpack/pack not transitive (%s, %s)" % ( str(format), str((cp, bp, hp, ip, lp, fp, dp, tp))) @@ -160,11 +160,11 @@ ('f', -2.0, '\300\000\000\000', '\000\000\000\300', 0), ('d', -2.0, '\300\000\000\000\000\000\000\000', '\000\000\000\000\000\000\000\300', 0), - ('t', 0, '\0', '\0', 0), - ('t', 3, '\1', '\1', 1), - ('t', True, '\1', '\1', 0), - ('t', [], '\0', '\0', 1), - ('t', (1,), '\1', '\1', 1), + ('t', 0, '\0', '\0', 0), + ('t', 3, '\1', '\1', 1), + ('t', True, '\1', '\1', 0), + ('t', [], '\0', '\0', 1), + ('t', (1,), '\1', '\1', 1), ] for fmt, arg, big, lil, asy in tests: @@ -621,48 +621,48 @@ test_pack_into_fn() def test_bool(): - for prefix in tuple("<>!=")+('',): - false = (), [], [], '', 0 - true = [1], 'test', 5, -1, 0xffffffff+1, 0xffffffff/2 - - falseFormat = prefix + 't' * len(false) - if verbose: - print 'trying bool pack/unpack on', false, 'using format', falseFormat - packedFalse = struct.pack(falseFormat, *false) - unpackedFalse = struct.unpack(falseFormat, packedFalse) - - trueFormat = prefix + 't' * len(true) - if verbose: - print 'trying bool pack/unpack on', true, 'using format', trueFormat - packedTrue = struct.pack(trueFormat, *true) - unpackedTrue = struct.unpack(trueFormat, packedTrue) - - if len(true) != len(unpackedTrue): - raise TestFailed('unpacked true array is not of same size as input') - if len(false) != len(unpackedFalse): - raise TestFailed('unpacked false array is not of same size as input') - - for t in unpackedFalse: - if t is not False: - raise TestFailed('%r did not unpack as False' % t) - for t in unpackedTrue: - if t is not True: - raise TestFailed('%r did not unpack as false' % t) - - if prefix and verbose: - print 'trying size of bool with format %r' % (prefix+'t') - packed = struct.pack(prefix+'t', 1) - - if len(packed) != struct.calcsize(prefix+'t'): - raise TestFailed('packed length is not equal to calculated size') - - if len(packed) != 1 and prefix: - raise TestFailed('encoded bool is not one byte: %r' % packed) - elif not prefix and verbose: - print 'size of bool in native format is %i' % (len(packed)) - - for c in '\x01\x7f\xff\x0f\xf0': - if struct.unpack('>t', c)[0] is not True: - raise TestFailed('%c did not unpack as True' % c) + for prefix in tuple("<>!=")+('',): + false = (), [], [], '', 0 + true = [1], 'test', 5, -1, 0xffffffff+1, 0xffffffff/2 + + falseFormat = prefix + 't' * len(false) + if verbose: + print 'trying bool pack/unpack on', false, 'using format', falseFormat + packedFalse = struct.pack(falseFormat, *false) + unpackedFalse = struct.unpack(falseFormat, packedFalse) + + trueFormat = prefix + 't' * len(true) + if verbose: + print 'trying bool pack/unpack on', true, 'using format', trueFormat + packedTrue = struct.pack(trueFormat, *true) + unpackedTrue = struct.unpack(trueFormat, packedTrue) + + if len(true) != len(unpackedTrue): + raise TestFailed('unpacked true array is not of same size as input') + if len(false) != len(unpackedFalse): + raise TestFailed('unpacked false array is not of same size as input') + + for t in unpackedFalse: + if t is not False: + raise TestFailed('%r did not unpack as False' % t) + for t in unpackedTrue: + if t is not True: + raise TestFailed('%r did not unpack as false' % t) + + if prefix and verbose: + print 'trying size of bool with format %r' % (prefix+'t') + packed = struct.pack(prefix+'t', 1) + + if len(packed) != struct.calcsize(prefix+'t'): + raise TestFailed('packed length is not equal to calculated size') + + if len(packed) != 1 and prefix: + raise TestFailed('encoded bool is not one byte: %r' % packed) + elif not prefix and verbose: + print 'size of bool in native format is %i' % (len(packed)) + + for c in '\x01\x7f\xff\x0f\xf0': + if struct.unpack('>t', c)[0] is not True: + raise TestFailed('%c did not unpack as True' % c) test_bool() Modified: python/branches/p3yk/Lib/test/test_support.py ============================================================================== --- python/branches/p3yk/Lib/test/test_support.py (original) +++ python/branches/p3yk/Lib/test/test_support.py Mon Feb 5 02:24:16 2007 @@ -270,7 +270,7 @@ print >> get_original_stdout(), '\tfetching %s ...' % url fn, _ = urllib.urlretrieve(url, filename) return open(fn) - + @contextmanager def guard_warnings_filter(): """Guard the warnings filter from being permanently changed.""" Modified: python/branches/p3yk/Modules/_ctypes/cfield.c ============================================================================== --- python/branches/p3yk/Modules/_ctypes/cfield.c (original) +++ python/branches/p3yk/Modules/_ctypes/cfield.c Mon Feb 5 02:24:16 2007 @@ -1432,10 +1432,19 @@ #endif #ifdef MS_WIN32 +/* We cannot use SysFreeString as the PyCObject_FromVoidPtr + because of different calling convention +*/ +static void _my_SysFreeString(void *p) +{ + SysFreeString((BSTR)p); +} + static PyObject * BSTR_set(void *ptr, PyObject *value, unsigned size) { BSTR bstr; + PyObject *result; /* convert value into a PyUnicodeObject or NULL */ if (Py_None == value) { @@ -1463,15 +1472,19 @@ } else bstr = NULL; - /* free the previous contents, if any */ - if (*(BSTR *)ptr) - SysFreeString(*(BSTR *)ptr); - - /* and store it */ - *(BSTR *)ptr = bstr; + if (bstr) { + result = PyCObject_FromVoidPtr((void *)bstr, _my_SysFreeString); + if (result == NULL) { + SysFreeString(bstr); + return NULL; + } + } else { + result = Py_None; + Py_INCREF(result); + } - /* We don't need to keep any other object */ - _RET(value); + *(BSTR *)ptr = bstr; + return result; } Modified: python/branches/p3yk/Modules/posixmodule.c ============================================================================== --- python/branches/p3yk/Modules/posixmodule.c (original) +++ python/branches/p3yk/Modules/posixmodule.c Mon Feb 5 02:24:16 2007 @@ -1462,7 +1462,7 @@ /* POSIX methods */ PyDoc_STRVAR(posix_access__doc__, -"access(path, mode) -> 1 if granted, 0 otherwise\n\n\ +"access(path, mode) -> True if granted, False otherwise\n\n\ Use the real uid/gid to test for access to a path. Note that most\n\ operations will use the effective uid/gid, therefore this routine can\n\ be used in a suid/sgid environment to test if the invoking user has the\n\ Modified: python/branches/p3yk/Objects/setobject.c ============================================================================== --- python/branches/p3yk/Objects/setobject.c (original) +++ python/branches/p3yk/Objects/setobject.c Mon Feb 5 02:24:16 2007 @@ -935,7 +935,7 @@ if (PyAnySet_Check(other)) return set_merge(so, other); - if (PyDict_Check(other)) { + if (PyDict_CheckExact(other)) { PyObject *value; Py_ssize_t pos = 0; while (PyDict_Next(other, &pos, &key, &value)) { @@ -1383,7 +1383,7 @@ setentry *entry; Py_ssize_t pos = 0; - if (!PyAnySet_Check(other) && !PyDict_Check(other)) { + if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) { result = set_copy(so); if (result == NULL) return NULL; @@ -1397,7 +1397,7 @@ if (result == NULL) return NULL; - if (PyDict_Check(other)) { + if (PyDict_CheckExact(other)) { while (set_next(so, &pos, &entry)) { setentry entrycopy; entrycopy.hash = entry->hash; @@ -1470,7 +1470,7 @@ if ((PyObject *)so == other) return set_clear(so); - if (PyDict_Check(other)) { + if (PyDict_CheckExact(other)) { PyObject *value; int rv; while (PyDict_Next(other, &pos, &key, &value)) { Modified: python/branches/p3yk/Python/ceval.c ============================================================================== --- python/branches/p3yk/Python/ceval.c (original) +++ python/branches/p3yk/Python/ceval.c Mon Feb 5 02:24:16 2007 @@ -2174,8 +2174,9 @@ case SETUP_LOOP: case SETUP_EXCEPT: case SETUP_FINALLY: - /* NOTE: If you add any new block-setup opcodes that are not try/except/finally - handlers, you may need to update the PyGen_NeedsFinalizing() function. */ + /* NOTE: If you add any new block-setup opcodes that are + not try/except/finally handlers, you may need to + update the PyGen_NeedsFinalizing() function. */ PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg, STACK_LEVEL()); @@ -4010,6 +4011,35 @@ res = !res; break; case PyCmp_EXC_MATCH: + if (PyTuple_Check(w)) { + Py_ssize_t i, length; + length = PyTuple_Size(w); + for (i = 0; i < length; i += 1) { + PyObject *exc = PyTuple_GET_ITEM(w, i); + if (PyString_Check(exc)) { + int ret_val; + ret_val = PyErr_WarnEx( + PyExc_DeprecationWarning, + "catching of string " + "exceptions is " + "deprecated", 1); + if (ret_val == -1) + return NULL; + } + } + } + else { + if (PyString_Check(w)) { + int ret_val; + ret_val = PyErr_WarnEx( + PyExc_DeprecationWarning, + "catching of string " + "exceptions is deprecated", + 1); + if (ret_val == -1) + return NULL; + } + } res = PyErr_GivenExceptionMatches(v, w); break; default: From python-checkins at python.org Mon Feb 5 07:03:19 2007 From: python-checkins at python.org (kurt.kaiser) Date: Mon, 5 Feb 2007 07:03:19 +0100 (CET) Subject: [Python-checkins] r53635 - python/trunk/Lib/idlelib/NEWS.txt python/trunk/Lib/idlelib/configHandler.py Message-ID: <20070205060319.DBAAC1E4002@bag.python.org> Author: kurt.kaiser Date: Mon Feb 5 07:03:18 2007 New Revision: 53635 Modified: python/trunk/Lib/idlelib/NEWS.txt python/trunk/Lib/idlelib/configHandler.py Log: Add 'raw' support to configHandler. Patch 1650174 Tal Einat. Modified: python/trunk/Lib/idlelib/NEWS.txt ============================================================================== --- python/trunk/Lib/idlelib/NEWS.txt (original) +++ python/trunk/Lib/idlelib/NEWS.txt Mon Feb 5 07:03:18 2007 @@ -3,6 +3,8 @@ *Release date: XX-XXX-200X* +- Add 'raw' support to configHandler. Patch 1650174 Tal Einat. + - Avoid hang when encountering a duplicate in a completion list. Bug 1571112. - Patch #1362975: Rework CodeContext indentation algorithm to Modified: python/trunk/Lib/idlelib/configHandler.py ============================================================================== --- python/trunk/Lib/idlelib/configHandler.py (original) +++ python/trunk/Lib/idlelib/configHandler.py Mon Feb 5 07:03:18 2007 @@ -39,22 +39,19 @@ self.file=cfgFile ConfigParser.__init__(self,defaults=cfgDefaults) - def Get(self, section, option, type=None, default=None): + def Get(self, section, option, type=None, default=None, raw=False): """ Get an option value for given section/option or return default. If type is specified, return as type. """ + if not self.has_option(section, option): + return default if type=='bool': - getVal=self.getboolean + return self.getboolean(section, option) elif type=='int': - getVal=self.getint - else: - getVal=self.get - if self.has_option(section,option): - #return getVal(section, option, raw, vars, default) - return getVal(section, option) + return self.getint(section, option) else: - return default + return self.get(section, option, raw=raw) def GetOptionList(self,section): """ @@ -219,7 +216,7 @@ return userDir def GetOption(self, configType, section, option, default=None, type=None, - warn_on_default=True): + warn_on_default=True, raw=False): """ Get an option value for given config type and given general configuration section/option or return a default. If type is specified, @@ -233,9 +230,11 @@ """ if self.userCfg[configType].has_option(section,option): - return self.userCfg[configType].Get(section, option, type=type) + return self.userCfg[configType].Get(section, option, + type=type, raw=raw) elif self.defaultCfg[configType].has_option(section,option): - return self.defaultCfg[configType].Get(section, option, type=type) + return self.defaultCfg[configType].Get(section, option, + type=type, raw=raw) else: #returning default, print warning if warn_on_default: warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' From python-checkins at python.org Mon Feb 5 22:42:38 2007 From: python-checkins at python.org (brett.cannon) Date: Mon, 5 Feb 2007 22:42:38 +0100 (CET) Subject: [Python-checkins] r53636 - sandbox/trunk/import_in_py/controlled_importlib.py sandbox/trunk/import_in_py/test_controlled_importlib.py Message-ID: <20070205214238.C2CFB1E400B@bag.python.org> Author: brett.cannon Date: Mon Feb 5 22:42:38 2007 New Revision: 53636 Modified: sandbox/trunk/import_in_py/controlled_importlib.py sandbox/trunk/import_in_py/test_controlled_importlib.py Log: Add whitelisting support for extension modules. Modified: sandbox/trunk/import_in_py/controlled_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/controlled_importlib.py (original) +++ sandbox/trunk/import_in_py/controlled_importlib.py Mon Feb 5 22:42:38 2007 @@ -58,6 +58,25 @@ pass +class WhitelistExtHandler(importlib.ExtensionFileHandler): + + """Add whitelisting to the extension module handler.""" + + def __init__(self, whitelist): + self._whitelist = frozenset(whitelist) + super(WhitelistExtHandler, self).__init__() + + def cannot_handle(self, name): + if name in self._whitelist: + return False + return True + + def handle_code(self, loader, mod_name, extension_path, package=None): + if mod_name in self._whitelist: + return super(WhitelistExtHandler, self).handle_code(loder, mod_name, + extension_path, package) + raise ImportError("not allowed to load module") + class ControlledImport(importlib.Import): Modified: sandbox/trunk/import_in_py/test_controlled_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/test_controlled_importlib.py (original) +++ sandbox/trunk/import_in_py/test_controlled_importlib.py Mon Feb 5 22:42:38 2007 @@ -1,7 +1,9 @@ import controlled_importlib +import importlib import mock_importlib from contextlib import contextmanager, nested +import os import StringIO import sys import unittest @@ -108,6 +110,55 @@ self.failUnlessRaises(ImportError, imp_load.load_module, blacklist) +class ExtensionHelper(unittest.TestCase): + + whitelist = 'time' + blacklist = 'datetime' + + def setUp(self): + self.imp_load = controlled_importlib.WhitelistExtHandler([self.whitelist]) + + +class WhitelistExtensionsTests(ExtensionHelper): + + """Test the whitelisting of extension modules.""" + + def test_cannot_handle(self): + # Should return False for modules on the whitelist, True otherwise. + self.failUnless(not self.imp_load.cannot_handle(self.whitelist)) + self.failUnless(self.imp_load.cannot_handle(self.blacklist)) + + def handle_code(self): + # Should raise ImportError if the module is not whitelisted, otherwise + # return the module. + module = self.imp_load.handle_code(None, self.whitelist, + self.imp_load.handles[0]) + self.failUnlessEqual(module.__name__, self.whitelist) + self.failUnlessRaises(ImportError, self.imp_load.handle_code, None, + self.blacklist, self.imp_load.handles[0]) + + +class FileSystemImporterTests(ExtensionHelper): + + """Make sure that the filesystem importer respects what the handler's + cannot_handle method says.""" + + def test_find_module(self): + # Make sure that when the handler is used in a filesystem importer that + # whitelisting is still respected for find_module. + for entry in sys.path: + blacklist_filename = self.blacklist + self.imp_load.handles[0] + blacklist_path = os.path.join(entry, blacklist_filename) + if os.path.exists(blacklist_path): + sys_entry = entry + break + else: + raise test_support.TestSkipped("sys.path empty") + importer = importlib.FileSystemImporter(sys_entry, self.imp_load) + self.failUnless(importer.find_module(self.whitelist)) + self.failUnless(importer.find_module(self.blacklist) is None) + + @contextmanager def mutate_sys_modules(module, name): """Temporarily mutate sys.modules with a new module.""" @@ -242,6 +293,8 @@ test_support.run_unittest(WhitelistTests, WhitelistBuiltinTests, WhitelistFrozenTests, + WhitelistExtensionsTests, + FileSystemImporterTests, ControlledImportMethodTests, ControlledImportUsageTests) From python-checkins at python.org Mon Feb 5 23:01:59 2007 From: python-checkins at python.org (collin.winter) Date: Mon, 5 Feb 2007 23:01:59 +0100 (CET) Subject: [Python-checkins] r53637 - peps/trunk/pep-0000.txt peps/trunk/pep-3109.txt Message-ID: <20070205220159.5AEB81E401C@bag.python.org> Author: collin.winter Date: Mon Feb 5 23:01:58 2007 New Revision: 53637 Added: peps/trunk/pep-3109.txt (contents, props changed) Modified: peps/trunk/pep-0000.txt Log: Add PEP 3109: Raising Exceptions in Python 3000 Modified: peps/trunk/pep-0000.txt ============================================================================== --- peps/trunk/pep-0000.txt (original) +++ peps/trunk/pep-0000.txt Mon Feb 5 23:01:58 2007 @@ -107,6 +107,7 @@ S 3106 Revamping dict.keys(), .values() and .items() GvR S 3107 Function Annotations Winter, Lownds I 3108 Standard Library Reorganization Cannon + I 3109 Raising Exceptions in Python 3000 Winter Finished PEPs (done, implemented in Subversion) @@ -447,6 +448,7 @@ S 3106 Revamping dict.keys(), .values() and .items() GvR S 3107 Function Annotations Winter, Lownds I 3108 Standard Library Reorganization Cannon + I 3109 Raising Exceptions in Python 3000 Winter Key Added: peps/trunk/pep-3109.txt ============================================================================== --- (empty file) +++ peps/trunk/pep-3109.txt Mon Feb 5 23:01:58 2007 @@ -0,0 +1,286 @@ +PEP: 3109 +Title: Raising Exceptions in Python 3000 +Version: $Revision$ +Last-Modified: $Date$ +Author: Collin Winter +Status: Draft +Type: Standards Track +Content-Type: text/x-rst +Created: 19-Jan-2006 +Python-Version: 3.0 +Post-History: + + +Abstract +======== + +This PEP introduces changes to Python's mechanisms for raising +exceptions intended to reduce both line noise and the size of the +language. + + +Rationale +========= + +One of Python's guiding maxims is "there should be one -- and +preferably only one -- obvious way to do it" [#zen]_. Python 2.x's +``raise`` statement violates this principle, permitting multiple +ways of expressing the same thought. For example, these statements +are equivalent: :: + + raise E, V + + raise E(V) + +There is a third form of the ``raise`` statement, allowing arbitrary +tracebacks to be attached to an exception [#grammar]_: :: + + raise E, V, T + +where T is a traceback. As specified in PEP 344 [#pep344]_, +exception objects in Python 3.x will possess a ``__traceback__`` +attribute, admitting this translation of the three-expression +``raise`` statement: :: + + raise E, V, T + +is translated to :: + + e = E(V) + e.__traceback__ = T + raise e + +Using these translations, we can reduce the ``raise`` statement from +four forms to two: + +1. ``raise`` (with no arguments) is used to re-raise the active + exception in an ``except`` suite. + +2. ``raise EXCEPTION`` is used to raise a new exception. This form has + two sub-variants: ``EXCEPTION`` may be an exception class or an + instance of an exception class; valid exception classes are + BaseException and its subclasses [#pep352]_. If ``EXCEPTION`` + is a subclass, it will be called with no arguments to obtain + an exception instance. + + To raise anything else is an error. + +There is a further, more tangible benefit to be obtained through this +consolidation, as noted by A.M. Kuchling [#amk-line-noise]_. :: + + PEP 8 doesn't express any preference between the + two forms of raise statements: + raise ValueError, 'blah' + raise ValueError("blah") + + I like the second form better, because if the exception arguments + are long or include string formatting, you don't need to use line + continuation characters because of the containing parens. + +The BDFL has concurred [#guido-declaration]_ and endorsed the +consolidation of the several ``raise`` forms. + + +Grammar Changes +=============== + +In Python 3, the grammar for ``raise`` statements will change +from [#grammar]_ :: + + raise_stmt: 'raise' [test [',' test [',' test]]] + +to :: + + raise_stmt: 'raise' [test] + + +Changes to Builtin Types +======================== + +Because of its relation to exception raising, the signature for the +``throw()`` method on generator objects will change, dropping the +optional second and third parameters. The signature thus changes +from [#throw-sig]_ :: + + generator.throw(E, [V, [T]]) + +to :: + + generator.throw(EXCEPTION) + +Where ``EXCEPTION`` is either a subclass of ``BaseException`` or an +instance of a subclass of ``BaseException``. + + +Semantic Changes +================ + +In Python 2, the following ``raise`` statement is legal :: + + raise ((E1, (E2, E3)), E4), V + +The interpreter will take the tuple's first element as the exception +type (recursively), making the above fully equivalent to :: + + raise E1, V + +As of Python 3.0, support for raising tuples like this will be +dropped. This change will bring ``raise`` statements into line with +the ``throw()`` method on generator objects, which already disallows +this. + + +Compatibility Issues +==================== + +All two- and three-expression ``raise`` statements will require +modification, as will all two- and three-expression ``throw()`` calls +on generators. Fortunately, the translation from Python 2.x to +Python 3.x in this case is simple and can be handled mechanically +by Guido van Rossum's 2to3 utility [#2to3]_ using the ``raise`` and +``throw`` fixers ([#raise-fixer]_, [#throw-fixer]_). + +The following translations will be performed: + +1. Zero- and one-expression ``raise`` statements will be left + intact. + +2. Two-expression ``raise`` statements will be converted from :: + + raise E, V + + to :: + + raise E(V) + + Two-expression ``throw()`` calls will be converted from :: + + generator.throw(E, V) + + to :: + + generator.throw(E(V)) + + See point #5 for a caveat to this transformation. + +3. Three-expression ``raise`` statements will be converted from :: + + raise E, V, T + + to :: + + e = E(V) + e.__traceback__ = T + raise e + + Three-expression ``throw()`` calls will be converted from :: + + generator.throw(E, V, T) + + to :: + + e = E(V) + e.__traceback__ = T + generator.throw(e) + + See point #5 for a caveat to this transformation. + +4. Two- and three-expression ``raise`` statements where ``E`` is a + tuple literal can be converted automatically using ``2to3``'s + ``raise`` fixer. ``raise`` statements where ``E`` is a non-literal + tuple, e.g., the result of a function call, will need to be + converted manually. + +5. Two- and three-expression ``raise`` statements where ``E`` is an + exception class and ``V`` is an exception instance will need + special attention. These cases break down into two camps: + + 1. ``raise E, V`` as a long-hand version of the zero-argument + ``raise`` statement. As an example, assuming F is a subclass + of E :: + + try: + something() + except F as V: + raise F(V) + except E as V: + handle(V) + + This would be better expressed as :: + + try: + something() + except F: + raise + except E as V: + handle(V) + + 2. ``raise E, V`` as a way of "casting" an exception to another + class. Taking an example from + distutils.compiler.unixcompiler :: + + try: + self.spawn(pp_args) + except DistutilsExecError as msg: + raise CompileError(msg) + + This would be better expressed as :: + + try: + self.spawn(pp_args) + except DistutilsExecError as msg: + raise CompileError from msg + + Using the ``raise ... from ...`` syntax introduced in + PEP 344. + + +References +========== + +.. [#zen] + http://www.python.org/dev/peps/pep-0020/ + +.. [#grammar] + http://www.python.org/doc/current/ref/raise.html + +.. [#throw-sig] + http://www.python.org/dev/peps/pep-0342/ + +.. [#pep344] + http://www.python.org/dev/peps/pep-0344/ + +.. [#pep352] + http://www.python.org/dev/peps/pep-0352/ + +.. [#amk-line-noise] + http://mail.python.org/pipermail/python-dev/2005-August/055187.html + +.. [#guido-declaration] + http://mail.python.org/pipermail/python-dev/2005-August/055190.html + +.. [#2to3] + http://svn.python.org/view/sandbox/trunk/2to3/ + +.. [#raise-fixer] + http://svn.python.org/view/sandbox/trunk/2to3/fixes/fix_raise.py + +.. [#throw-fixer] + http://svn.python.org/view/sandbox/trunk/2to3/fixes/fix_throw.py + + +Copyright +========= + +This document has been placed in the public domain. + + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + coding: utf-8 + End: From python-checkins at python.org Mon Feb 5 23:05:47 2007 From: python-checkins at python.org (collin.winter) Date: Mon, 5 Feb 2007 23:05:47 +0100 (CET) Subject: [Python-checkins] r53638 - peps/trunk/pep-0000.txt peps/trunk/pep-3110.txt Message-ID: <20070205220547.B14C71E401C@bag.python.org> Author: collin.winter Date: Mon Feb 5 23:05:46 2007 New Revision: 53638 Added: peps/trunk/pep-3110.txt (contents, props changed) Modified: peps/trunk/pep-0000.txt Log: Add PEP 3110: Catching Exceptions in Python 3000 Modified: peps/trunk/pep-0000.txt ============================================================================== --- peps/trunk/pep-0000.txt (original) +++ peps/trunk/pep-0000.txt Mon Feb 5 23:05:46 2007 @@ -108,6 +108,7 @@ S 3107 Function Annotations Winter, Lownds I 3108 Standard Library Reorganization Cannon I 3109 Raising Exceptions in Python 3000 Winter + I 3110 Catching Exceptions in Python 3000 Winter Finished PEPs (done, implemented in Subversion) @@ -449,6 +450,7 @@ S 3107 Function Annotations Winter, Lownds I 3108 Standard Library Reorganization Cannon I 3109 Raising Exceptions in Python 3000 Winter + I 3110 Catching Exceptions in Python 3000 Winter Key Added: peps/trunk/pep-3110.txt ============================================================================== --- (empty file) +++ peps/trunk/pep-3110.txt Mon Feb 5 23:05:46 2007 @@ -0,0 +1,287 @@ +PEP: 3110 +Title: Catching Exceptions in Python 3000 +Version: $Revision$ +Last-Modified: $Date$ +Author: Collin Winter +Status: Draft +Type: Standards Track +Content-Type: text/x-rst +Created: 16-Jan-2006 +Python-Version: 3.0 +Post-History: + + +Abstract +======== + +This PEP introduces changes intended to help eliminate ambiguities +in Python's grammar, simplify exception classes, simplify garbage +collection for exceptions and reduce the size of the language in +Python 3.0. + + +Rationale +========= + +1. ``except`` clauses in Python 2.x present a syntactic ambiguity + where the parser cannot differentiate whether :: + + except , : + + should be interpreted as :: + + except , : + + or :: + + except , : + + Python 2 opts for the latter semantic, at the cost of requiring the + former to be parenthesized, like so :: + + except (, ): + +2. As specified in PEP 352 [#pep352]_, the ability to treat exceptions + as tuples will be removed, meaning this code will no longer work :: + + except os.error, (errno, errstr): + + Because the automatic unpacking will no longer be possible, it is + desirable to remove the ability to use tuples as ``except`` targets. + +3. As specified in PEP 344 [#pep344]_, exception instances in Python 3 + will possess a ``__traceback__`` attribute. The Open Issues section + of that PEP includes a paragraph on garbage collection difficulties + caused by this attribute, namely a "exception -> traceback -> + stack frame -> exception" reference cycle, whereby all locals are + kept in scope until the next GC run. This PEP intends to resolve + this issue by adding a cleanup semantic to ``except`` clauses in + Python 3 whereby the target name is deleted at the end of the + ``except`` suite. + +4. In the spirit of "there should be one -- and preferably only one + -- obvious way to do it" [#zen]_, it is desirable to consolidate + duplicate functionality. To this end, the ``exc_value``, + ``exc_type`` and ``exc_traceback`` attributes of the ``sys`` + module [#sys-module]_ will be removed in favor of + ``sys.exc_info()``, which provides the same information. These + attributes are already listed in PEP 3100 [#pep3100]_ as targeted + for removal. + + +Grammar Changes +=============== + +In Python 3, the grammar for ``except`` statements will change +from [#grammar]_ :: + + except_clause: 'except' [test [',' test]] + +to :: + + except_clause: 'except' [test ['as' NAME]] + +The use of ``as`` in place of the comma token means that :: + + except AttributeError, os.error: + +can be clearly understood as a tuple of exception classes. This new +syntax was first proposed by Greg Ewing [#firstproposal]_ and +endorsed ([#firstproposal]_, [#renaming]_) by the BDFL. + +Further, the restriction of the token following ``as`` from ``test`` +to ``NAME`` means that only valid identifiers can be used as +``except`` targets. + + +Semantic Changes +================ + +In order to resolve the garbage collection issue related to PEP 344, +``except`` statements in Python 3 will generate additional bytecode to +delete the target, thus eliminating the reference cycle. +The source-to-source translation, as suggested by Phillip J. Eby +[#except-translation]_, is :: + + try: + try_body + except E as N: + except_body + ... + +gets translated to (in Python 2.5 terms) :: + + try: + try_body + except E, N: + try: + except_body + finally: + N = None + del N + ... + +An implementation has already been checked into the p3yk branch +[#translation-checkin]_. + + +Compatibility Issues +==================== + +Nearly all ``except`` clauses will need to be changed. ``except`` +clauses with identifier targets will be converted from :: + + except E, N: + +to :: + + except E as N: + +``except`` clauses with non-tuple, non-identifier targets +(e.g., ``a.b.c[d]``) will need to be converted from :: + + except E, T: + +to :: + + except E as t: + T = t + +Both of these cases can be handled by Guido van Rossum's ``2to3`` +utility [#2to3]_ using the ``except`` fixer [#exceptfixer]_. + +``except`` clauses with tuple targets will need to be converted +manually, on a case-by-case basis. These changes will usually need +to be accompanied by changes to the exception classes themselves. +While these changes generally cannot be automated, the ``2to3`` +utility is able to point out cases where the target of an ``except`` +clause is a tuple, simplifying conversion. + +Situations where it is necessary to keep an exception instance around +past the end of the ``except`` suite can be easily translated like so +:: + + try: + ... + except E as N: + ... + ... + +becomes :: + + try: + ... + except E as N: + n = N + ... + ... + +This way, when ``N`` is deleted at the end of the block, ``n`` will +persist and can be used as normal. + +Lastly, all uses of the ``sys`` module's ``exc_type``, ``exc_value`` +and ``exc_traceback`` attributes will need to be removed. They can be +replaced with ``sys.exc_info()[0]``, ``sys.exc_info()[1]`` and +``sys.exc_info()[2]`` respectively, a transformation that can be +performed by ``2to3``'s ``sysexcattrs`` fixer. + + +Open Issues +=========== + +"except" Statements in Python 2.x +----------------------------------- + +It has been proposed that the grammar for ``except`` statements be +changed to accommodate both Python 2's ``,`` and Python 3's ``as`` +between the statement's type and target portions. The grammar +would thus change from :: + + except_clause: 'except' [test [',' test]] + +to :: + + except_clause: 'except' [test [('as' | ',') test]] + +It has not been decided whether the proposed end-of-suite cleanup +semantic for ``except`` statements should be included in the 2.x +series. + + +Replacing or Dropping "sys.exc_info()" +-------------------------------------- + +The idea of dropping ``sys.exc_info()`` or replacing it with a +``sys.exception`` attribute or a ``sys.get_exception()`` function +has been raised several times on python-3000 ([#drop-excinfo]_, +[#replace-excinfo]_) and mentioned in PEP 344's "Open Issues" section. + +While a ``2to3`` fixer to replace calls to ``sys.exc_info()`` +and some attribute accesses would be trivial, it would be far more +difficult for static analysis to find and fix functions that expect +the values from ``sys.exc_info()`` as arguments. Similarly, this does +not address the need to rewrite the documentation for all APIs that +are defined in terms of ``sys.exc_info()``. + + +References +========== + +.. [#pep352] + http://www.python.org/dev/peps/pep-0352/ + +.. [#zen] + http://www.python.org/dev/peps/pep-0020/ + +.. [#sys-module] + http://docs.python.org/lib/module-sys.html + +.. [#pep3100] + http://www.python.org/dev/peps/pep-3100/ + +.. [#pep344] + http://www.python.org/dev/peps/pep-0344/ + +.. [#firstproposal] + http://mail.python.org/pipermail/python-dev/2006-March/062449.html + +.. [#renaming] + http://mail.python.org/pipermail/python-dev/2006-March/062640.html + +.. [#grammar] + http://www.python.org/doc/current/ref/try.html + +.. [#except-translation] + http://mail.python.org/pipermail/python-3000/2007-January/005395.html + +.. [#translation-checkin] + http://svn.python.org/view?rev=53342&view=rev + +.. [#2to3] + http://svn.python.org/view/sandbox/trunk/2to3/ + +.. [#exceptfixer] + http://svn.python.org/view/sandbox/trunk/2to3/fixes/fix_except.py + +.. [#drop-excinfo] + http://mail.python.org/pipermail/python-3000/2007-January/005385.html + +.. [#replace-excinfo] + http://mail.python.org/pipermail/python-3000/2007-January/005604.html + + +Copyright +========= + +This document has been placed in the public domain. + + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + coding: utf-8 + End: From python-checkins at python.org Mon Feb 5 23:16:36 2007 From: python-checkins at python.org (collin.winter) Date: Mon, 5 Feb 2007 23:16:36 +0100 (CET) Subject: [Python-checkins] r53639 - peps/trunk/pep-0000.txt Message-ID: <20070205221636.796181E4015@bag.python.org> Author: collin.winter Date: Mon Feb 5 23:16:35 2007 New Revision: 53639 Modified: peps/trunk/pep-0000.txt Log: 3110 and 3109 are standards track, not informational, PEPs Modified: peps/trunk/pep-0000.txt ============================================================================== --- peps/trunk/pep-0000.txt (original) +++ peps/trunk/pep-0000.txt Mon Feb 5 23:16:35 2007 @@ -107,8 +107,8 @@ S 3106 Revamping dict.keys(), .values() and .items() GvR S 3107 Function Annotations Winter, Lownds I 3108 Standard Library Reorganization Cannon - I 3109 Raising Exceptions in Python 3000 Winter - I 3110 Catching Exceptions in Python 3000 Winter + S 3109 Raising Exceptions in Python 3000 Winter + S 3110 Catching Exceptions in Python 3000 Winter Finished PEPs (done, implemented in Subversion) @@ -449,8 +449,8 @@ S 3106 Revamping dict.keys(), .values() and .items() GvR S 3107 Function Annotations Winter, Lownds I 3108 Standard Library Reorganization Cannon - I 3109 Raising Exceptions in Python 3000 Winter - I 3110 Catching Exceptions in Python 3000 Winter + S 3109 Raising Exceptions in Python 3000 Winter + S 3110 Catching Exceptions in Python 3000 Winter Key From python-checkins at python.org Mon Feb 5 23:20:32 2007 From: python-checkins at python.org (brett.cannon) Date: Mon, 5 Feb 2007 23:20:32 +0100 (CET) Subject: [Python-checkins] r53640 - sandbox/trunk/import_in_py/test_controlled_importlib.py Message-ID: <20070205222032.7DC7B1E4016@bag.python.org> Author: brett.cannon Date: Mon Feb 5 23:20:31 2007 New Revision: 53640 Modified: sandbox/trunk/import_in_py/test_controlled_importlib.py Log: Fix up previous extension module whitelisting and add testing in ControlledImport integration tests. Modified: sandbox/trunk/import_in_py/test_controlled_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/test_controlled_importlib.py (original) +++ sandbox/trunk/import_in_py/test_controlled_importlib.py Mon Feb 5 23:20:31 2007 @@ -118,6 +118,15 @@ def setUp(self): self.imp_load = controlled_importlib.WhitelistExtHandler([self.whitelist]) + def find_module(self, module): + for entry in sys.path: + module_filename= module + self.imp_load.handles[0] + module_path= os.path.join(entry, module_filename) + if os.path.exists(module_path): + return module_path + else: + raise test_support.TestSkipped("sys.path empty") + class WhitelistExtensionsTests(ExtensionHelper): @@ -128,14 +137,15 @@ self.failUnless(not self.imp_load.cannot_handle(self.whitelist)) self.failUnless(self.imp_load.cannot_handle(self.blacklist)) - def handle_code(self): + def test_handle_code(self): # Should raise ImportError if the module is not whitelisted, otherwise # return the module. - module = self.imp_load.handle_code(None, self.whitelist, - self.imp_load.handles[0]) + whitelist_path = self.find_module(self.whitelist) + module = self.imp_load.handle_code(None, self.whitelist, whitelist_path) self.failUnlessEqual(module.__name__, self.whitelist) + blacklist_path = self.find_module(self.blacklist) self.failUnlessRaises(ImportError, self.imp_load.handle_code, None, - self.blacklist, self.imp_load.handles[0]) + self.blacklist, blacklist_path) class FileSystemImporterTests(ExtensionHelper): @@ -146,14 +156,8 @@ def test_find_module(self): # Make sure that when the handler is used in a filesystem importer that # whitelisting is still respected for find_module. - for entry in sys.path: - blacklist_filename = self.blacklist + self.imp_load.handles[0] - blacklist_path = os.path.join(entry, blacklist_filename) - if os.path.exists(blacklist_path): - sys_entry = entry - break - else: - raise test_support.TestSkipped("sys.path empty") + blacklist_path = self.find_module(self.blacklist) + sys_entry = os.path.split(blacklist_path)[0] importer = importlib.FileSystemImporter(sys_entry, self.imp_load) self.failUnless(importer.find_module(self.whitelist)) self.failUnless(importer.find_module(self.blacklist) is None) @@ -257,8 +261,14 @@ self.failUnlessRaises(ImportError, import_, blacklisted, level=0) def test_extension_whitelisting(self): - # XXX - pass + whitelist = 'time' + blacklist = 'datetime' + with remove_from_sys_modules(whitelist, blacklist): + import_ = controlled_importlib.ControlledImport([], [], [whitelist]) + module = import_(whitelist, level=0) + self.failUnlessEqual(module.__name__, whitelist) + self.failUnlessRaises(ImportError, import_, blacklist, level=0) + def test_pyc_blocking(self): # XXX From python-checkins at python.org Tue Feb 6 00:02:17 2007 From: python-checkins at python.org (kurt.kaiser) Date: Tue, 6 Feb 2007 00:02:17 +0100 (CET) Subject: [Python-checkins] r53641 - python/trunk/Lib/idlelib/CallTips.py python/trunk/Lib/idlelib/NEWS.txt Message-ID: <20070205230217.0F0371E400D@bag.python.org> Author: kurt.kaiser Date: Tue Feb 6 00:02:16 2007 New Revision: 53641 Modified: python/trunk/Lib/idlelib/CallTips.py python/trunk/Lib/idlelib/NEWS.txt Log: 1. Calltips now 'handle' tuples in the argument list (display '' :) Suggested solution by Christos Georgiou, Bug 791968. 2. Clean up tests, were not failing when they should have been. 4. Remove some camelcase and an unneeded try/except block. Modified: python/trunk/Lib/idlelib/CallTips.py ============================================================================== --- python/trunk/Lib/idlelib/CallTips.py (original) +++ python/trunk/Lib/idlelib/CallTips.py Tue Feb 6 00:02:16 2007 @@ -3,7 +3,9 @@ Call Tips are floating windows which display function, class, and method parameter and docstring information when you type an opening parenthesis, and which disappear when you type a closing parenthesis. + """ +import re import sys import types @@ -89,6 +91,8 @@ two unrelated modules are being edited some calltips in the current module may be inoperative if the module was not the last to run. + To find methods, fetch_tip must be fed a fully qualified name. + """ try: rpcclt = self.editwin.flist.pyshell.interp.rpcclt @@ -108,7 +112,7 @@ namespace.update(__main__.__dict__) try: return eval(name, namespace) - except: + except NameError: return None def _find_constructor(class_ob): @@ -124,39 +128,37 @@ def get_arg_text(ob): """Get a string describing the arguments for the given object""" - argText = "" + arg_text = "" if ob is not None: - argOffset = 0 + arg_offset = 0 if type(ob) in (types.ClassType, types.TypeType): # Look for the highest __init__ in the class chain. fob = _find_constructor(ob) if fob is None: fob = lambda: None else: - argOffset = 1 + arg_offset = 1 elif type(ob)==types.MethodType: # bit of a hack for methods - turn it into a function # but we drop the "self" param. fob = ob.im_func - argOffset = 1 + arg_offset = 1 else: fob = ob - # Try and build one for Python defined functions + # Try to build one for Python defined functions if type(fob) in [types.FunctionType, types.LambdaType]: - try: - realArgs = fob.func_code.co_varnames[argOffset:fob.func_code.co_argcount] - defaults = fob.func_defaults or [] - defaults = list(map(lambda name: "=%s" % repr(name), defaults)) - defaults = [""] * (len(realArgs)-len(defaults)) + defaults - items = map(lambda arg, dflt: arg+dflt, realArgs, defaults) - if fob.func_code.co_flags & 0x4: - items.append("...") - if fob.func_code.co_flags & 0x8: - items.append("***") - argText = ", ".join(items) - argText = "(%s)" % argText - except: - pass + argcount = fob.func_code.co_argcount + real_args = fob.func_code.co_varnames[arg_offset:argcount] + defaults = fob.func_defaults or [] + defaults = list(map(lambda name: "=%s" % repr(name), defaults)) + defaults = [""] * (len(real_args) - len(defaults)) + defaults + items = map(lambda arg, dflt: arg + dflt, real_args, defaults) + if fob.func_code.co_flags & 0x4: + items.append("...") + if fob.func_code.co_flags & 0x8: + items.append("***") + arg_text = ", ".join(items) + arg_text = "(%s)" % re.sub("\.\d+", "", arg_text) # See if we can use the docstring doc = getattr(ob, "__doc__", "") if doc: @@ -164,10 +166,10 @@ pos = doc.find("\n") if pos < 0 or pos > 70: pos = 70 - if argText: - argText += "\n" - argText += doc[:pos] - return argText + if arg_text: + arg_text += "\n" + arg_text += doc[:pos] + return arg_text ################################################# # @@ -181,16 +183,18 @@ def t4(*args): "(...)" def t5(a, *args): "(a, ...)" def t6(a, b=None, *args, **kw): "(a, b=None, ..., ***)" + def t7((a, b), c, (d, e)): "(, c, )" - class TC: - "(a=None, ...)" - def __init__(self, a=None, *b): "(a=None, ...)" + class TC(object): + "(ai=None, ...)" + def __init__(self, ai=None, *b): "(ai=None, ...)" def t1(self): "()" - def t2(self, a, b=None): "(a, b=None)" - def t3(self, a, *args): "(a, ...)" + def t2(self, ai, b=None): "(ai, b=None)" + def t3(self, ai, *args): "(ai, ...)" def t4(self, *args): "(...)" - def t5(self, a, *args): "(a, ...)" - def t6(self, a, b=None, *args, **kw): "(a, b=None, ..., ***)" + def t5(self, ai, *args): "(ai, ...)" + def t6(self, ai, b=None, *args, **kw): "(ai, b=None, ..., ***)" + def t7(self, (ai, b), c, (d, e)): "(, c, )" def test(tests): ct = CallTips() @@ -198,15 +202,20 @@ for t in tests: expected = t.__doc__ + "\n" + t.__doc__ name = t.__name__ - arg_text = ct.fetch_tip(name) + # exercise fetch_tip(), not just get_arg_text() + try: + qualified_name = "%s.%s" % (t.im_class.__name__, name) + except AttributeError: + qualified_name = name + arg_text = ct.fetch_tip(qualified_name) if arg_text != expected: failed.append(t) - print "%s - expected %s, but got %s" % (t, expected, - get_arg_text(entity)) + fmt = "%s - expected %s, but got %s" + print fmt % (t.__name__, expected, get_arg_text(t)) print "%d of %d tests failed" % (len(failed), len(tests)) tc = TC() - tests = (t1, t2, t3, t4, t5, t6, - TC, tc.t1, tc.t2, tc.t3, tc.t4, tc.t5, tc.t6) + tests = (t1, t2, t3, t4, t5, t6, t7, + TC, tc.t1, tc.t2, tc.t3, tc.t4, tc.t5, tc.t6, tc.t7) test(tests) Modified: python/trunk/Lib/idlelib/NEWS.txt ============================================================================== --- python/trunk/Lib/idlelib/NEWS.txt (original) +++ python/trunk/Lib/idlelib/NEWS.txt Tue Feb 6 00:02:16 2007 @@ -3,6 +3,9 @@ *Release date: XX-XXX-200X* +- Calltips now 'handle' tuples in the argument list (display '' :) + Suggested solution by Christos Georgiou, Bug 791968. + - Add 'raw' support to configHandler. Patch 1650174 Tal Einat. - Avoid hang when encountering a duplicate in a completion list. Bug 1571112. From python-checkins at python.org Tue Feb 6 00:45:30 2007 From: python-checkins at python.org (brett.cannon) Date: Tue, 6 Feb 2007 00:45:30 +0100 (CET) Subject: [Python-checkins] r53642 - sandbox/trunk/import_in_py/controlled_importlib.py sandbox/trunk/import_in_py/test_controlled_importlib.py Message-ID: <20070205234530.6E5DF1E400E@bag.python.org> Author: brett.cannon Date: Tue Feb 6 00:45:29 2007 New Revision: 53642 Modified: sandbox/trunk/import_in_py/controlled_importlib.py sandbox/trunk/import_in_py/test_controlled_importlib.py Log: Add support for importing any .py file but blocking all .pyc files. That means that an entry on sys.path_hooks is now added by ControlledImport.__init__. Also added tests to make sure that __loader__ attributes are not exposed on the modules. Modified: sandbox/trunk/import_in_py/controlled_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/controlled_importlib.py (original) +++ sandbox/trunk/import_in_py/controlled_importlib.py Tue Feb 6 00:45:29 2007 @@ -73,7 +73,7 @@ def handle_code(self, loader, mod_name, extension_path, package=None): if mod_name in self._whitelist: - return super(WhitelistExtHandler, self).handle_code(loder, mod_name, + return super(WhitelistExtHandler, self).handle_code(loader, mod_name, extension_path, package) raise ImportError("not allowed to load module") @@ -96,9 +96,12 @@ sys.meta_path.append(WhitelistBuiltin(safe_builtins)) sys.meta_path.append(WhitelistFrozen(safe_frozen)) # Whitelist extension modules on sys.path. - # XXX + ext_handler = WhitelistExtHandler(safe_extensions) # Allow all .py files but not .pyc files on sys.path. - # XXX + py_handler = importlib.PyPycHandler(bytecode_handles=()) + # Put .py and extension handlers into a path_hooks factory. + fs_factory = importlib.FileSystemFactory(ext_handler, py_handler) + sys.path_hooks.append(fs_factory) def module_from_cache(self, name): """Override so that any module name starting with a dot raises Modified: sandbox/trunk/import_in_py/test_controlled_importlib.py ============================================================================== --- sandbox/trunk/import_in_py/test_controlled_importlib.py (original) +++ sandbox/trunk/import_in_py/test_controlled_importlib.py Tue Feb 6 00:45:29 2007 @@ -1,6 +1,7 @@ import controlled_importlib import importlib import mock_importlib +import test_importlib from contextlib import contextmanager, nested import os @@ -228,9 +229,13 @@ self.failUnless(not hasattr(stripped_module, '__loader__')) -class ControlledImportUsageTests(unittest.TestCase): +class ControlledImportUsageTests(test_importlib.TestPyPycPackages): """Make sure that usage of ControlledImport works properly.""" + + def setUp(self): + """Create .py and .pyc files for testing purposes.""" + super(ControlledImportUsageTests, self).setUp(faked_names=False) def test_block_dot_modules(self): # Modules with a leading dot should not be imported. @@ -271,18 +276,50 @@ def test_pyc_blocking(self): - # XXX - pass + # Importing of a .pyc file should fail. Also, no .pyc should be + # generated. + with remove_from_sys_modules(self.module_name): + import_ = controlled_importlib.ControlledImport() + os.unlink(self.py_path) + assert os.path.exists(self.pyc_path) + self.failUnlessRaises(ImportError, import_, self.module_name, + level=0) def test_py(self): - # XXX try importing something with the same name as a built-in that is - # not whitelisted. - pass + # Should be able to import a .py module. + with remove_from_sys_modules(self.module_name): + os.unlink(self.pyc_path) + import_ = controlled_importlib.ControlledImport() + self.failUnless(import_(self.module_name, level=0)) + + def test_no_pyc_creation(self): + # No .pyc file should be created by importing a .py file. + with remove_from_sys_modules(self.module_name): + os.unlink(self.pyc_path) + assert os.path.exists(self.py_path) + assert not os.path.exists(self.pyc_path) + import_ = controlled_importlib.ControlledImport() + module = import_(self.module_name, level=0) + self.failUnless(module) + self.failUnless(not os.path.exists(self.pyc_path)) def test_no_loader_attribute(self): # No __loader__ attribute should be exposed on any module or package. - # XXX check both modules, packages, and submodules. - pass + # Purposefully skipped the sub-package to make sure that implicit + # imports of dependencies does not leave __loader__ on by importing a + # module in the sub-package. + module_names = [self.top_level_module_name, self.pkg_name, + self.pkg_module_name, self.sub_pkg_module_name] + assert self.sub_pkg_name not in module_names + with remove_from_sys_modules(*module_names): + import_ = controlled_importlib.ControlledImport() + for module_name in module_names: + module = import_(module_name, level=0) + self.failUnless(not hasattr(sys.modules[module_name], + '__loader__')) + else: + self.failUnless(not hasattr(sys.modules[self.sub_pkg_name], + '__loader__')) def test_relative_import(self): # A relative import within a package should not be able to circumvent From buildbot at python.org Tue Feb 6 00:54:17 2007 From: buildbot at python.org (buildbot at python.org) Date: Mon, 05 Feb 2007 23:54:17 +0000 Subject: [Python-checkins] buildbot warnings in alpha Tru64 5.1 trunk Message-ID: <20070205235417.918BC1E400B@bag.python.org> The Buildbot has detected a new failure of alpha Tru64 5.1 trunk. Full details are available at: http://www.python.org/dev/buildbot/all/alpha%2520Tru64%25205.1%2520trunk/builds/1381 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: kurt.kaiser Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_socket sincerely, -The Buildbot From python-checkins at python.org Tue Feb 6 03:39:18 2007 From: python-checkins at python.org (collin.winter) Date: Tue, 6 Feb 2007 03:39:18 +0100 (CET) Subject: [Python-checkins] r53643 - peps/trunk/pep-3107.txt Message-ID: <20070206023918.870BC1E400B@bag.python.org> Author: collin.winter Date: Tue Feb 6 03:39:18 2007 New Revision: 53643 Modified: peps/trunk/pep-3107.txt Log: Mention that a reference implementation has been checked in Modified: peps/trunk/pep-3107.txt ============================================================================== --- peps/trunk/pep-3107.txt (original) +++ peps/trunk/pep-3107.txt Tue Feb 6 03:39:18 2007 @@ -236,8 +236,8 @@ Implementation ============== -A sample implementation for the syntax changes has been provided -[#implementation]_ by Tony Lownds. +A reference implementation has been checked into the p3yk branch +as revision 53170 [#implementation]_. Rejected Proposals @@ -297,7 +297,7 @@ http://mail.python.org/pipermail/python-3000/2006-June/002438.html .. [#implementation] - http://python.org/sf/1607548 + http://svn.python.org/view?rev=53170&view=rev .. [#grammar] http://www.python.org/doc/current/ref/function.html From python-checkins at python.org Tue Feb 6 04:21:41 2007 From: python-checkins at python.org (kurt.kaiser) Date: Tue, 6 Feb 2007 04:21:41 +0100 (CET) Subject: [Python-checkins] r53644 - python/trunk/Lib/idlelib/PyShell.py Message-ID: <20070206032141.1852A1E400B@bag.python.org> Author: kurt.kaiser Date: Tue Feb 6 04:21:40 2007 New Revision: 53644 Modified: python/trunk/Lib/idlelib/PyShell.py Log: Clean up ModifiedInterpreter.runcode() structure Modified: python/trunk/Lib/idlelib/PyShell.py ============================================================================== --- python/trunk/Lib/idlelib/PyShell.py (original) +++ python/trunk/Lib/idlelib/PyShell.py Tue Feb 6 04:21:40 2007 @@ -706,35 +706,37 @@ debugger = self.debugger try: self.tkconsole.beginexecuting() - try: - if not debugger and self.rpcclt is not None: - self.active_seq = self.rpcclt.asyncqueue("exec", "runcode", - (code,), {}) - elif debugger: - debugger.run(code, self.locals) - else: - exec code in self.locals - except SystemExit: - if not self.tkconsole.closing: - if tkMessageBox.askyesno( - "Exit?", - "Do you want to exit altogether?", - default="yes", - master=self.tkconsole.text): - raise - else: - self.showtraceback() - else: + if not debugger and self.rpcclt is not None: + self.active_seq = self.rpcclt.asyncqueue("exec", "runcode", + (code,), {}) + elif debugger: + debugger.run(code, self.locals) + else: + exec code in self.locals + except SystemExit: + if not self.tkconsole.closing: + if tkMessageBox.askyesno( + "Exit?", + "Do you want to exit altogether?", + default="yes", + master=self.tkconsole.text): raise - except: - if use_subprocess: - # When run w/o subprocess, both user and IDLE errors - # are printed here; skip message in that case. - print >> self.tkconsole.stderr, \ - "IDLE internal error in runcode()" + else: + self.showtraceback() + else: + raise + except: + if use_subprocess: + print >>self.tkconsole.stderr, \ + "IDLE internal error in runcode()" self.showtraceback() - if use_subprocess: - self.tkconsole.endexecuting() + self.tkconsole.endexecuting() + else: + if self.tkconsole.canceled: + self.tkconsole.canceled = False + print >>self.tkconsole.stderr, "KeyboardInterrupt" + else: + self.showtraceback() finally: if not use_subprocess: try: From buildbot at python.org Tue Feb 6 04:59:20 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 06 Feb 2007 03:59:20 +0000 Subject: [Python-checkins] buildbot warnings in ppc Debian unstable trunk Message-ID: <20070206035920.BE5841E400B@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%2520Debian%2520unstable%2520trunk/builds/44 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: kurt.kaiser Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_bsddb3 Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 378, in writerThread self.doWrite(d, name, x, min(stop, x+step)) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 366, in doWrite txn.abort() DBRunRecoveryError: (-30974, 'DB_RUNRECOVERY: Fatal error, run database recovery -- PANIC: DB_NOTFOUND: No matching key/data pair found') Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 426, in readerThread rec = c.next() DBRunRecoveryError: (-30974, 'DB_RUNRECOVERY: Fatal error, run database recovery') Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 378, in writerThread self.doWrite(d, name, x, min(stop, x+step)) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 358, in doWrite d.put(key, self.makeData(key), txn) DBRunRecoveryError: (-30974, 'DB_RUNRECOVERY: Fatal error, run database recovery -- PANIC: fatal region error detected; run recovery') Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 426, in readerThread rec = c.next() DBRunRecoveryError: (-30974, 'DB_RUNRECOVERY: Fatal error, run database recovery -- PANIC: fatal region error detected; run recovery') Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 426, in readerThread rec = c.next() DBRunRecoveryError: (-30974, 'DB_RUNRECOVERY: Fatal error, run database recovery') Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 426, in readerThread rec = c.next() DBRunRecoveryError: (-30974, 'DB_RUNRECOVERY: Fatal error, run database recovery') Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 426, in readerThread rec = c.next() DBRunRecoveryError: (-30974, 'DB_RUNRECOVERY: Fatal error, run database recovery -- PANIC: fatal region error detected; run recovery') Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 378, in writerThread self.doWrite(d, name, x, min(stop, x+step)) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 358, in doWrite d.put(key, self.makeData(key), txn) DBRunRecoveryError: (-30974, 'DB_RUNRECOVERY: Fatal error, run database recovery -- PANIC: fatal region error detected; run recovery') ====================================================================== ERROR: test03_ThreadedTransactions (bsddb.test.test_thread.BTreeThreadedTransactions) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 73, in tearDown self.d.close() DBRunRecoveryError: (-30974, 'DB_RUNRECOVERY: Fatal error, run database recovery -- PANIC: fatal region error detected; run recovery') ====================================================================== ERROR: test03_ThreadedTransactions (bsddb.test.test_thread.HashThreadedTransactions) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 64, in setUp self.env.open(homeDir, self.envflags | db.DB_CREATE) DBNoSuchFileError: (2, 'No such file or directory -- /tmp/db_home/__db.001: unable to find environment') ====================================================================== ERROR: test03_ThreadedTransactions (bsddb.test.test_thread.BTreeThreadedNoWaitTransactions) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 64, in setUp self.env.open(homeDir, self.envflags | db.DB_CREATE) DBNoSuchFileError: (2, 'No such file or directory -- /tmp/db_home/__db.001: unable to find environment') ====================================================================== ERROR: test03_ThreadedTransactions (bsddb.test.test_thread.HashThreadedNoWaitTransactions) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 64, in setUp self.env.open(homeDir, self.envflags | db.DB_CREATE) DBNoSuchFileError: (2, 'No such file or directory -- /tmp/db_home/__db.001: unable to find environment') make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Tue Feb 6 05:01:00 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 06 Feb 2007 04:01:00 +0000 Subject: [Python-checkins] buildbot warnings in PPC64 Debian trunk Message-ID: <20070206040100.A997B1E400B@bag.python.org> The Buildbot has detected a new failure of PPC64 Debian trunk. Full details are available at: http://www.python.org/dev/buildbot/all/PPC64%2520Debian%2520trunk/builds/44 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: kurt.kaiser Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_bsddb3 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Tue Feb 6 13:55:27 2007 From: python-checkins at python.org (phillip.eby) Date: Tue, 6 Feb 2007 13:55:27 +0100 (CET) Subject: [Python-checkins] r53645 - sandbox/trunk/setuptools/pydoc.py Message-ID: <20070206125527.3CB601E400C@bag.python.org> Author: phillip.eby Date: Tue Feb 6 13:55:26 2007 New Revision: 53645 Modified: sandbox/trunk/setuptools/pydoc.py Log: Match Python 2.5 pydoc Modified: sandbox/trunk/setuptools/pydoc.py ============================================================================== --- sandbox/trunk/setuptools/pydoc.py (original) +++ sandbox/trunk/setuptools/pydoc.py Tue Feb 6 13:55:26 2007 @@ -321,6 +321,8 @@ # identifies something in a way that pydoc itself has issues handling; # think 'super' and how it is a descriptor (which raises the exception # by lacking a __name__ attribute) and an instance. + if inspect.isgetsetdescriptor(object): return self.docdata(*args) + if inspect.ismemberdescriptor(object): return self.docdata(*args) try: if inspect.ismodule(object): return self.docmodule(*args) if inspect.isclass(object): return self.docclass(*args) @@ -336,7 +338,7 @@ name and ' ' + repr(name), type(object).__name__) raise TypeError, message - docmodule = docclass = docroutine = docother = fail + docmodule = docclass = docroutine = docother = docproperty = docdata = fail def getdocloc(self, object): """Return the location of module docs or None""" @@ -918,6 +920,10 @@ lhs = name and '%s = ' % name or '' return lhs + self.repr(object) + def docdata(self, object, name=None, mod=None, cl=None): + """Produce html documentation for a data descriptor.""" + return self._docdescriptor(name, object, mod) + def index(self, dir, shadowed=None): """Generate an HTML index for a directory of modules.""" modpkgs = [] @@ -1271,6 +1277,10 @@ """Produce text documentation for a property.""" return self._docdescriptor(name, object, mod) + def docdata(self, object, name=None, mod=None, cl=None): + """Produce text documentation for a data descriptor.""" + return self._docdescriptor(name, object, mod) + def docother(self, object, name=None, mod=None, parent=None, maxlen=None, doc=None): """Produce text documentation for a data object.""" repr = self.repr(object) @@ -1400,6 +1410,14 @@ return 'module ' + thing.__name__ if inspect.isbuiltin(thing): return 'built-in function ' + thing.__name__ + if inspect.isgetsetdescriptor(thing): + return 'getset descriptor %s.%s.%s' % ( + thing.__objclass__.__module__, thing.__objclass__.__name__, + thing.__name__) + if inspect.ismemberdescriptor(thing): + return 'member descriptor %s.%s.%s' % ( + thing.__objclass__.__module__, thing.__objclass__.__name__, + thing.__name__) if inspect.isclass(thing): return 'class ' + thing.__name__ if inspect.isfunction(thing): @@ -1456,6 +1474,8 @@ if not (inspect.ismodule(object) or inspect.isclass(object) or inspect.isroutine(object) or + inspect.isgetsetdescriptor(object) or + inspect.ismemberdescriptor(object) or isinstance(object, property)): # If the passed object is a piece of data or an instance, # document its available methods instead of its value. From python-checkins at python.org Tue Feb 6 16:37:51 2007 From: python-checkins at python.org (peter.astrand) Date: Tue, 6 Feb 2007 16:37:51 +0100 (CET) Subject: [Python-checkins] r53646 - in python/trunk: Lib/subprocess.py Misc/NEWS Message-ID: <20070206153751.7979E1E400F@bag.python.org> Author: peter.astrand Date: Tue Feb 6 16:37:50 2007 New Revision: 53646 Modified: python/trunk/Lib/subprocess.py python/trunk/Misc/NEWS Log: Applied patch 1124861.3.patch to solve bug #1124861: Automatically create pipes on Windows, if GetStdHandle fails. Will backport. Modified: python/trunk/Lib/subprocess.py ============================================================================== --- python/trunk/Lib/subprocess.py (original) +++ python/trunk/Lib/subprocess.py Tue Feb 6 16:37:50 2007 @@ -592,6 +592,22 @@ c2pread, c2pwrite, errread, errwrite) + # On Windows, you cannot just redirect one or two handles: You + # either have to redirect all three or none. If the subprocess + # user has only redirected one or two handles, we are + # automatically creating PIPEs for the rest. We should close + # these after the process is started. See bug #1124861. + if mswindows: + if stdin is None and p2cwrite is not None: + os.close(p2cwrite) + p2cwrite = None + if stdout is None and c2pread is not None: + os.close(c2pread) + c2pread = None + if stderr is None and errread is not None: + os.close(errread) + errread = None + if p2cwrite is not None: self.stdin = os.fdopen(p2cwrite, 'wb', bufsize) if c2pread is not None: @@ -668,7 +684,9 @@ if stdin is None: p2cread = GetStdHandle(STD_INPUT_HANDLE) - elif stdin == PIPE: + if p2cread is not None: + pass + elif stdin is None or stdin == PIPE: p2cread, p2cwrite = CreatePipe(None, 0) # Detach and turn into fd p2cwrite = p2cwrite.Detach() @@ -682,7 +700,9 @@ if stdout is None: c2pwrite = GetStdHandle(STD_OUTPUT_HANDLE) - elif stdout == PIPE: + if c2pwrite is not None: + pass + elif stdout is None or stdout == PIPE: c2pread, c2pwrite = CreatePipe(None, 0) # Detach and turn into fd c2pread = c2pread.Detach() @@ -696,7 +716,9 @@ if stderr is None: errwrite = GetStdHandle(STD_ERROR_HANDLE) - elif stderr == PIPE: + if errwrite is not None: + pass + elif stderr is None or stderr == PIPE: errread, errwrite = CreatePipe(None, 0) # Detach and turn into fd errread = errread.Detach() Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Feb 6 16:37:50 2007 @@ -126,6 +126,9 @@ Library ------- +- Bug #1124861: Automatically create pipes if GetStdHandle fails in + subprocess. + - Patch #1634778: add missing encoding aliases for iso8859_15 and iso8859_16. From python-checkins at python.org Tue Feb 6 16:41:47 2007 From: python-checkins at python.org (peter.astrand) Date: Tue, 6 Feb 2007 16:41:47 +0100 (CET) Subject: [Python-checkins] r53647 - in python/branches/release25-maint: Lib/subprocess.py Misc/NEWS Message-ID: <20070206154147.E1D541E4016@bag.python.org> Author: peter.astrand Date: Tue Feb 6 16:41:46 2007 New Revision: 53647 Modified: python/branches/release25-maint/Lib/subprocess.py python/branches/release25-maint/Misc/NEWS Log: Applied patch 1124861.3.patch to solve bug #1124861: Automatically create pipes on Windows, if GetStdHandle fails. Backport from rev 53646. Modified: python/branches/release25-maint/Lib/subprocess.py ============================================================================== --- python/branches/release25-maint/Lib/subprocess.py (original) +++ python/branches/release25-maint/Lib/subprocess.py Tue Feb 6 16:41:46 2007 @@ -592,6 +592,22 @@ c2pread, c2pwrite, errread, errwrite) + # On Windows, you cannot just redirect one or two handles: You + # either have to redirect all three or none. If the subprocess + # user has only redirected one or two handles, we are + # automatically creating PIPEs for the rest. We should close + # these after the process is started. See bug #1124861. + if mswindows: + if stdin is None and p2cwrite is not None: + os.close(p2cwrite) + p2cwrite = None + if stdout is None and c2pread is not None: + os.close(c2pread) + c2pread = None + if stderr is None and errread is not None: + os.close(errread) + errread = None + if p2cwrite: self.stdin = os.fdopen(p2cwrite, 'wb', bufsize) if c2pread: @@ -668,7 +684,9 @@ if stdin is None: p2cread = GetStdHandle(STD_INPUT_HANDLE) - elif stdin == PIPE: + if p2cread is not None: + pass + elif stdin is None or stdin == PIPE: p2cread, p2cwrite = CreatePipe(None, 0) # Detach and turn into fd p2cwrite = p2cwrite.Detach() @@ -682,7 +700,9 @@ if stdout is None: c2pwrite = GetStdHandle(STD_OUTPUT_HANDLE) - elif stdout == PIPE: + if c2pwrite is not None: + pass + elif stdout is None or stdout == PIPE: c2pread, c2pwrite = CreatePipe(None, 0) # Detach and turn into fd c2pread = c2pread.Detach() @@ -696,7 +716,9 @@ if stderr is None: errwrite = GetStdHandle(STD_ERROR_HANDLE) - elif stderr == PIPE: + if errwrite is not None: + pass + elif stderr is None or stderr == PIPE: errread, errwrite = CreatePipe(None, 0) # Detach and turn into fd errread = errread.Detach() Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Tue Feb 6 16:41:46 2007 @@ -157,6 +157,9 @@ Library ------- +- Bug #1124861: Automatically create pipes if GetStdHandle fails in + subprocess. + - Patch #783050: the pty.fork() function now closes the slave fd correctly. From buildbot at python.org Tue Feb 6 18:11:02 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 06 Feb 2007 17:11:02 +0000 Subject: [Python-checkins] buildbot warnings in hppa Ubuntu dapper 2.5 Message-ID: <20070206171102.942651E400F@bag.python.org> The Buildbot has detected a new failure of hppa Ubuntu dapper 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/hppa%2520Ubuntu%2520dapper%25202.5/builds/24 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: peter.astrand Build had warnings: warnings test Excerpt from the test logfile: make: *** [buildbottest] Killed sincerely, -The Buildbot From python-checkins at python.org Tue Feb 6 19:38:15 2007 From: python-checkins at python.org (lars.gustaebel) Date: Tue, 6 Feb 2007 19:38:15 +0100 (CET) Subject: [Python-checkins] r53648 - in python/trunk: Doc/lib/libtarfile.tex Lib/tarfile.py Lib/test/test_tarfile.py Misc/NEWS Message-ID: <20070206183815.8D91D1E400F@bag.python.org> Author: lars.gustaebel Date: Tue Feb 6 19:38:13 2007 New Revision: 53648 Modified: python/trunk/Doc/lib/libtarfile.tex python/trunk/Lib/tarfile.py python/trunk/Lib/test/test_tarfile.py python/trunk/Misc/NEWS Log: Patch #1652681: create nonexistent files in append mode and allow appending to empty files. Modified: python/trunk/Doc/lib/libtarfile.tex ============================================================================== --- python/trunk/Doc/lib/libtarfile.tex (original) +++ python/trunk/Doc/lib/libtarfile.tex Tue Feb 6 19:38:13 2007 @@ -36,7 +36,8 @@ \lineii{'r:'}{Open for reading exclusively without compression.} \lineii{'r:gz'}{Open for reading with gzip compression.} \lineii{'r:bz2'}{Open for reading with bzip2 compression.} - \lineii{'a' or 'a:'}{Open for appending with no compression.} + \lineii{'a' or 'a:'}{Open for appending with no compression. The file + is created if it does not exist.} \lineii{'w' or 'w:'}{Open for uncompressed writing.} \lineii{'w:gz'}{Open for gzip compressed writing.} \lineii{'w:bz2'}{Open for bzip2 compressed writing.} Modified: python/trunk/Lib/tarfile.py ============================================================================== --- python/trunk/Lib/tarfile.py (original) +++ python/trunk/Lib/tarfile.py Tue Feb 6 19:38:13 2007 @@ -1060,6 +1060,10 @@ self.mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode] if not fileobj: + if self._mode == "a" and not os.path.exists(self.name): + # Create nonexistent files in append mode. + self._mode = "w" + self.mode = "wb" fileobj = file(self.name, self.mode) self._extfileobj = False else: @@ -1093,7 +1097,8 @@ self.fileobj.seek(0) break if tarinfo is None: - self.fileobj.seek(- BLOCKSIZE, 1) + if self.offset > 0: + self.fileobj.seek(- BLOCKSIZE, 1) break if self._mode in "aw": @@ -1120,7 +1125,7 @@ 'r:' open for reading exclusively uncompressed 'r:gz' open for reading with gzip compression 'r:bz2' open for reading with bzip2 compression - 'a' or 'a:' open for appending + 'a' or 'a:' open for appending, creating the file if necessary 'w' or 'w:' open for writing without compression 'w:gz' open for writing with gzip compression 'w:bz2' open for writing with bzip2 compression Modified: python/trunk/Lib/test/test_tarfile.py ============================================================================== --- python/trunk/Lib/test/test_tarfile.py (original) +++ python/trunk/Lib/test/test_tarfile.py Tue Feb 6 19:38:13 2007 @@ -305,6 +305,61 @@ self.assertEqual(self.dst.getnames(), [], "added the archive to itself") +class AppendTest(unittest.TestCase): + # Test append mode (cp. patch #1652681). + + def setUp(self): + self.tarname = tmpname() + if os.path.exists(self.tarname): + os.remove(self.tarname) + + def _add_testfile(self, fileobj=None): + tar = tarfile.open(self.tarname, "a", fileobj=fileobj) + tar.addfile(tarfile.TarInfo("bar")) + tar.close() + + def _create_testtar(self): + src = tarfile.open(tarname()) + t = src.getmember("0-REGTYPE") + t.name = "foo" + f = src.extractfile(t) + tar = tarfile.open(self.tarname, "w") + tar.addfile(t, f) + tar.close() + + def _test(self, names=["bar"], fileobj=None): + tar = tarfile.open(self.tarname, fileobj=fileobj) + self.assert_(tar.getnames() == names) + + def test_non_existing(self): + self._add_testfile() + self._test() + + def test_empty(self): + open(self.tarname, "w").close() + self._add_testfile() + self._test() + + def test_empty_fileobj(self): + fobj = StringIO.StringIO() + self._add_testfile(fobj) + fobj.seek(0) + self._test(fileobj=fobj) + + def test_fileobj(self): + self._create_testtar() + data = open(self.tarname).read() + fobj = StringIO.StringIO(data) + self._add_testfile(fobj) + fobj.seek(0) + self._test(names=["foo", "bar"], fileobj=fobj) + + def test_existing(self): + self._create_testtar() + self._add_testfile() + self._test(names=["foo", "bar"]) + + class Write100Test(BaseTest): # The name field in a tar header stores strings of at most 100 chars. # If a string is shorter than 100 chars it has to be padded with '\0', @@ -711,6 +766,7 @@ ReadAsteriskTest, ReadStreamAsteriskTest, WriteTest, + AppendTest, Write100Test, WriteSize0Test, WriteStreamTest, Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Feb 6 19:38:13 2007 @@ -126,6 +126,9 @@ Library ------- +- Patch #1652681: tarfile.py: create nonexistent files in append mode and + allow appending to empty files. + - Bug #1124861: Automatically create pipes if GetStdHandle fails in subprocess. From buildbot at python.org Tue Feb 6 20:06:21 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 06 Feb 2007 19:06:21 +0000 Subject: [Python-checkins] buildbot warnings in x86 W2k trunk Message-ID: <20070206190621.C83B61E400F@bag.python.org> The Buildbot has detected a new failure of x86 W2k trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520W2k%2520trunk/builds/63 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: lars.gustaebel Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_tarfile ====================================================================== ERROR: test_fileobj (test.test_tarfile.AppendTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\trentm\data\buildbot\python-slave\trunk.mick-windows\build\lib\test\test_tarfile.py", line 355, in test_fileobj self._test(names=["foo", "bar"], fileobj=fobj) File "C:\trentm\data\buildbot\python-slave\trunk.mick-windows\build\lib\test\test_tarfile.py", line 331, in _test tar = tarfile.open(self.tarname, fileobj=fileobj) File "C:\trentm\data\buildbot\python-slave\trunk.mick-windows\build\lib\tarfile.py", line 1157, in open raise ReadError("file could not be opened successfully") ReadError: file could not be opened successfully sincerely, -The Buildbot From python-checkins at python.org Tue Feb 6 20:09:44 2007 From: python-checkins at python.org (kurt.kaiser) Date: Tue, 6 Feb 2007 20:09:44 +0100 (CET) Subject: [Python-checkins] r53649 - python/trunk/Lib/idlelib/CodeContext.py Message-ID: <20070206190944.C6C6D1E4013@bag.python.org> Author: kurt.kaiser Date: Tue Feb 6 20:09:43 2007 New Revision: 53649 Modified: python/trunk/Lib/idlelib/CodeContext.py Log: Updated patch (CodeContext.061217.patch) to [ 1362975 ] CodeContext - Improved text indentation Tal Einat 16Dec06 Modified: python/trunk/Lib/idlelib/CodeContext.py ============================================================================== --- python/trunk/Lib/idlelib/CodeContext.py (original) +++ python/trunk/Lib/idlelib/CodeContext.py Tue Feb 6 20:09:43 2007 @@ -10,6 +10,7 @@ """ import Tkinter +from Tkconstants import TOP, LEFT, X, W, SUNKEN from configHandler import idleConf import re from sys import maxint as INFINITY @@ -24,7 +25,6 @@ class CodeContext: menudefs = [('options', [('!Code Conte_xt', '<>')])] - context_depth = idleConf.GetOption("extensions", "CodeContext", "numlines", type="int", default=3) bgcolor = idleConf.GetOption("extensions", "CodeContext", @@ -54,66 +54,33 @@ def toggle_code_context_event(self, event=None): if not self.label: - # The following code attempts to figure out the required border - # width and vertical padding required for the CodeContext widget - # to be perfectly aligned with the text in the main Text widget. - # This is done by retrieving the appropriate attributes from the - # editwin.text and editwin.text_frame widgets. + # Calculate the border width and horizontal padding required to + # align the context with the text in the main Text widget. # # All values are passed through int(str()), since some - # values may be pixel objects, which can't simply be added added - # to ints. - # - # This code is considered somewhat unstable since it relies on - # some of Tk's inner workings. However its effect is merely - # cosmetic; failure will only cause the CodeContext text to be - # somewhat misaligned with the text in the main Text widget. - # - # To avoid possible errors, all references to the inner workings - # of Tk are executed inside try/except blocks. - - widgets_for_width_calc = self.editwin.text, self.editwin.text_frame - - # calculate the required vertical padding + # values may be pixel objects, which can't simply be added to ints. + widgets = self.editwin.text, self.editwin.text_frame + # Calculate the required vertical padding padx = 0 - for widget in widgets_for_width_calc: - try: - # retrieve the "padx" attribte from widget's pack info - padx += int(str( widget.pack_info()['padx'] )) - except: - pass - try: - # retrieve the widget's "padx" attribte - padx += int(str( widget.cget('padx') )) - except: - pass - - # calculate the required border width - border_width = 0 - for widget in widgets_for_width_calc: - try: - # retrieve the widget's "border" attribte - border_width += int(str( widget.cget('border') )) - except: - pass - + for widget in widgets: + padx += int(str( widget.pack_info()['padx'] )) + padx += int(str( widget.cget('padx') )) + # Calculate the required border width + border = 0 + for widget in widgets: + border += int(str( widget.cget('border') )) self.label = Tkinter.Label(self.editwin.top, text="\n" * (self.context_depth - 1), - anchor="w", justify="left", + anchor=W, justify=LEFT, font=self.textfont, bg=self.bgcolor, fg=self.fgcolor, width=1, #don't request more than we get - padx=padx, #line up with text widget - border=border_width, #match border width - relief="sunken", - ) - - # CodeContext's label widget is packed before and above the - # text_frame widget, thus ensuring that it will appear directly - # above it. - self.label.pack(side="top", fill="x", expand=False, + padx=padx, border=border, + relief=SUNKEN) + # Pack the label widget before and above the text_frame widget, + # thus ensuring that it will appear directly above text_frame + self.label.pack(side=TOP, fill=X, expand=False, before=self.editwin.text_frame) - else: self.label.destroy() self.label = None @@ -190,7 +157,6 @@ stopindent) self.info.extend(lines) self.topvisible = new_topvisible - # empty lines in context pane: context_strings = [""] * max(0, self.context_depth - len(self.info)) # followed by the context hint lines: From python-checkins at python.org Tue Feb 6 20:21:19 2007 From: python-checkins at python.org (kurt.kaiser) Date: Tue, 6 Feb 2007 20:21:19 +0100 (CET) Subject: [Python-checkins] r53650 - python/trunk/Lib/idlelib/IOBinding.py Message-ID: <20070206192119.C72131E400F@bag.python.org> Author: kurt.kaiser Date: Tue Feb 6 20:21:19 2007 New Revision: 53650 Modified: python/trunk/Lib/idlelib/IOBinding.py Log: narrow exception per [ 1540849 ] except too broad Modified: python/trunk/Lib/idlelib/IOBinding.py ============================================================================== --- python/trunk/Lib/idlelib/IOBinding.py (original) +++ python/trunk/Lib/idlelib/IOBinding.py Tue Feb 6 20:21:19 2007 @@ -209,7 +209,7 @@ # gets set to "not modified" at every new prompt. try: interp = self.editwin.interp - except: + except AttributeError: interp = None if not self.filename and self.get_saved() and not interp: self.editwin.flist.open(filename, self.loadfile) From buildbot at python.org Tue Feb 6 20:42:31 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 06 Feb 2007 19:42:31 +0000 Subject: [Python-checkins] buildbot warnings in PPC64 Debian trunk Message-ID: <20070206194231.303771E400F@bag.python.org> The Buildbot has detected a new failure of PPC64 Debian trunk. Full details are available at: http://www.python.org/dev/buildbot/all/PPC64%2520Debian%2520trunk/builds/47 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: kurt.kaiser Build had warnings: warnings test Excerpt from the test logfile: make: *** [buildbottest] Segmentation fault sincerely, -The Buildbot From buildbot at python.org Tue Feb 6 20:47:34 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 06 Feb 2007 19:47:34 +0000 Subject: [Python-checkins] buildbot warnings in ppc Debian unstable trunk Message-ID: <20070206194734.C33901E4010@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%2520Debian%2520unstable%2520trunk/builds/47 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: kurt.kaiser Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_bsddb3 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Tue Feb 6 22:33:24 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 06 Feb 2007 21:33:24 +0000 Subject: [Python-checkins] buildbot warnings in hppa Ubuntu dapper trunk Message-ID: <20070206213325.014131E400F@bag.python.org> The Buildbot has detected a new failure of hppa Ubuntu dapper trunk. Full details are available at: http://www.python.org/dev/buildbot/all/hppa%2520Ubuntu%2520dapper%2520trunk/builds/60 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: kurt.kaiser Build had warnings: warnings test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Wed Feb 7 04:39:42 2007 From: python-checkins at python.org (kurt.kaiser) Date: Wed, 7 Feb 2007 04:39:42 +0100 (CET) Subject: [Python-checkins] r53653 - python/trunk/Lib/idlelib/AutoCompleteWindow.py python/trunk/Lib/idlelib/NEWS.txt Message-ID: <20070207033942.7AADD1E4010@bag.python.org> Author: kurt.kaiser Date: Wed Feb 7 04:39:41 2007 New Revision: 53653 Modified: python/trunk/Lib/idlelib/AutoCompleteWindow.py python/trunk/Lib/idlelib/NEWS.txt Log: [ 1621265 ] Auto-completion list placement Move AC window below input line unless not enough space, then put it above. Patch: Tal Einat Modified: python/trunk/Lib/idlelib/AutoCompleteWindow.py ============================================================================== --- python/trunk/Lib/idlelib/AutoCompleteWindow.py (original) +++ python/trunk/Lib/idlelib/AutoCompleteWindow.py Wed Feb 7 04:39:41 2007 @@ -215,13 +215,22 @@ if not self.is_active(): return # Position the completion list window + text = self.widget + text.see(self.startindex) + x, y, cx, cy = text.bbox(self.startindex) acw = self.autocompletewindow - self.widget.see(self.startindex) - x, y, cx, cy = self.widget.bbox(self.startindex) - acw.wm_geometry("+%d+%d" % (x + self.widget.winfo_rootx(), - y + self.widget.winfo_rooty() \ - -acw.winfo_height())) - + acw_width, acw_height = acw.winfo_width(), acw.winfo_height() + text_width, text_height = text.winfo_width(), text.winfo_height() + new_x = text.winfo_rootx() + min(x, max(0, text_width - acw_width)) + new_y = text.winfo_rooty() + y + if (text_height - (y + cy) >= acw_height # enough height below + or y < acw_height): # not enough height above + # place acw below current line + new_y += cy + else: + # place acw above current line + new_y -= acw_height + acw.wm_geometry("+%d+%d" % (new_x, new_y)) def hide_event(self, event): if not self.is_active(): Modified: python/trunk/Lib/idlelib/NEWS.txt ============================================================================== --- python/trunk/Lib/idlelib/NEWS.txt (original) +++ python/trunk/Lib/idlelib/NEWS.txt Wed Feb 7 04:39:41 2007 @@ -3,6 +3,9 @@ *Release date: XX-XXX-200X* +- AutoCompleteWindow moved below input line, will move above if there + isn't enough space. Patch 1621265 Tal Einat + - Calltips now 'handle' tuples in the argument list (display '' :) Suggested solution by Christos Georgiou, Bug 791968. From buildbot at python.org Wed Feb 7 05:32:55 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 07 Feb 2007 04:32:55 +0000 Subject: [Python-checkins] buildbot warnings in alpha Tru64 5.1 trunk Message-ID: <20070207043255.DFBD21E4010@bag.python.org> The Buildbot has detected a new failure of alpha Tru64 5.1 trunk. Full details are available at: http://www.python.org/dev/buildbot/all/alpha%2520Tru64%25205.1%2520trunk/builds/1386 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: kurt.kaiser Build had warnings: warnings test Excerpt from the test logfile: 2 tests failed: test_signal test_socket sincerely, -The Buildbot From python-checkins at python.org Wed Feb 7 09:07:13 2007 From: python-checkins at python.org (kurt.kaiser) Date: Wed, 7 Feb 2007 09:07:13 +0100 (CET) Subject: [Python-checkins] r53654 - python/trunk/Lib/idlelib/CallTips.py Message-ID: <20070207080713.D0F6C1E4010@bag.python.org> Author: kurt.kaiser Date: Wed Feb 7 09:07:13 2007 New Revision: 53654 Modified: python/trunk/Lib/idlelib/CallTips.py Log: Handle AttributeError during calltip lookup Modified: python/trunk/Lib/idlelib/CallTips.py ============================================================================== --- python/trunk/Lib/idlelib/CallTips.py (original) +++ python/trunk/Lib/idlelib/CallTips.py Wed Feb 7 09:07:13 2007 @@ -112,7 +112,7 @@ namespace.update(__main__.__dict__) try: return eval(name, namespace) - except NameError: + except (NameError, AttributeError): return None def _find_constructor(class_ob): From buildbot at python.org Wed Feb 7 09:27:08 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 07 Feb 2007 08:27:08 +0000 Subject: [Python-checkins] buildbot warnings in hppa Ubuntu dapper trunk Message-ID: <20070207082708.6FCB31E4010@bag.python.org> The Buildbot has detected a new failure of hppa Ubuntu dapper trunk. Full details are available at: http://www.python.org/dev/buildbot/all/hppa%2520Ubuntu%2520dapper%2520trunk/builds/62 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: kurt.kaiser Build had warnings: warnings test Excerpt from the test logfile: make: *** [buildbottest] Killed sincerely, -The Buildbot From buildbot at python.org Wed Feb 7 10:06:28 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 07 Feb 2007 09:06:28 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.5 Message-ID: <20070207090628.74B0C1E4006@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520gentoo%25202.5/builds/209 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Colten': Jacoby Build Source Stamp: [branch Israel] Sheldon Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Wed Feb 7 10:06:36 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 07 Feb 2007 09:06:36 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 2.5 Message-ID: <20070207090636.D5FAD1E4006@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%2520solaris10%2520gcc%25202.5/builds/202 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Darien': Dontae Build Source Stamp: [branch Anderson] Jaylen Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Wed Feb 7 10:12:46 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 07 Feb 2007 09:12:46 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 2.5 Message-ID: <20070207091246.E1A861E4006@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%2520gentoo%25202.5/builds/212 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Brant': Daren Build Source Stamp: [branch Brock] Tyshawn Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Wed Feb 7 10:17:07 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 07 Feb 2007 09:17:07 +0000 Subject: [Python-checkins] buildbot failure in x86 OpenBSD 2.5 Message-ID: <20070207091707.A79621E4006@bag.python.org> The Buildbot has detected a new failure of x86 OpenBSD 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520OpenBSD%25202.5/builds/191 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Jaylin': Maximus Build Source Stamp: [branch Stephen] Ricardo Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Wed Feb 7 12:57:25 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 07 Feb 2007 11:57:25 +0000 Subject: [Python-checkins] buildbot failure in g4 osx.4 2.5 Message-ID: <20070207115726.07DC61E4010@bag.python.org> The Buildbot has detected a new failure of g4 osx.4 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/g4%2520osx.4%25202.5/builds/199 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Elvis': Jabari Build Source Stamp: [branch Milton] Josef Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From python-checkins at python.org Wed Feb 7 21:01:29 2007 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 7 Feb 2007 21:01:29 +0100 (CET) Subject: [Python-checkins] r53655 - in python/branches/release25-maint: Lib/test/test_dict.py Objects/dictobject.c Message-ID: <20070207200129.B2D161E4013@bag.python.org> Author: raymond.hettinger Date: Wed Feb 7 21:01:28 2007 New Revision: 53655 Modified: python/branches/release25-maint/Lib/test/test_dict.py python/branches/release25-maint/Objects/dictobject.c Log: SF #1615701: make d.update(m) honor __getitem__() and keys() in dict subclasses Modified: python/branches/release25-maint/Lib/test/test_dict.py ============================================================================== --- python/branches/release25-maint/Lib/test/test_dict.py (original) +++ python/branches/release25-maint/Lib/test/test_dict.py Wed Feb 7 21:01:28 2007 @@ -189,6 +189,14 @@ self.assertRaises(ValueError, {}.update, [(1, 2, 3)]) + # SF #1615701: make d.update(m) honor __getitem__() and keys() in dict subclasses + class KeyUpperDict(dict): + def __getitem__(self, key): + return key.upper() + d.clear() + d.update(KeyUpperDict.fromkeys('abc')) + self.assertEqual(d, {'a':'A', 'b':'B', 'c':'C'}) + def test_fromkeys(self): self.assertEqual(dict.fromkeys('abc'), {'a':None, 'b':None, 'c':None}) d = {} Modified: python/branches/release25-maint/Objects/dictobject.c ============================================================================== --- python/branches/release25-maint/Objects/dictobject.c (original) +++ python/branches/release25-maint/Objects/dictobject.c Wed Feb 7 21:01:28 2007 @@ -1306,7 +1306,7 @@ return -1; } mp = (dictobject*)a; - if (PyDict_Check(b)) { + if (PyDict_CheckExact(b)) { other = (dictobject*)b; if (other == mp || other->ma_used == 0) /* a.update(a) or a.update({}); nothing to do */ From python-checkins at python.org Wed Feb 7 21:08:56 2007 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 7 Feb 2007 21:08:56 +0100 (CET) Subject: [Python-checkins] r53656 - in python/trunk: Lib/test/test_dict.py Objects/dictobject.c Message-ID: <20070207200856.B31AA1E4013@bag.python.org> Author: raymond.hettinger Date: Wed Feb 7 21:08:22 2007 New Revision: 53656 Modified: python/trunk/Lib/test/test_dict.py python/trunk/Objects/dictobject.c Log: SF #1615701: make d.update(m) honor __getitem__() and keys() in dict subclasses Modified: python/trunk/Lib/test/test_dict.py ============================================================================== --- python/trunk/Lib/test/test_dict.py (original) +++ python/trunk/Lib/test/test_dict.py Wed Feb 7 21:08:22 2007 @@ -189,6 +189,14 @@ self.assertRaises(ValueError, {}.update, [(1, 2, 3)]) + # SF #1615701: make d.update(m) honor __getitem__() and keys() in dict subclasses + class KeyUpperDict(dict): + def __getitem__(self, key): + return key.upper() + d.clear() + d.update(KeyUpperDict.fromkeys('abc')) + self.assertEqual(d, {'a':'A', 'b':'B', 'c':'C'}) + def test_fromkeys(self): self.assertEqual(dict.fromkeys('abc'), {'a':None, 'b':None, 'c':None}) d = {} Modified: python/trunk/Objects/dictobject.c ============================================================================== --- python/trunk/Objects/dictobject.c (original) +++ python/trunk/Objects/dictobject.c Wed Feb 7 21:08:22 2007 @@ -1306,7 +1306,7 @@ return -1; } mp = (dictobject*)a; - if (PyDict_Check(b)) { + if (PyDict_CheckExact(b)) { other = (dictobject*)b; if (other == mp || other->ma_used == 0) /* a.update(a) or a.update({}); nothing to do */ From buildbot at python.org Wed Feb 7 21:39:42 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 07 Feb 2007 20:39:42 +0000 Subject: [Python-checkins] buildbot warnings in x86 mvlgcc 2.5 Message-ID: <20070207203943.038E71E4005@bag.python.org> The Buildbot has detected a new failure of x86 mvlgcc 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520mvlgcc%25202.5/builds/106 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_urllib2net make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Wed Feb 7 21:48:18 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 07 Feb 2007 20:48:18 +0000 Subject: [Python-checkins] buildbot warnings in PPC64 Debian 2.5 Message-ID: <20070207204819.0E5691E4033@bag.python.org> The Buildbot has detected a new failure of PPC64 Debian 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/PPC64%2520Debian%25202.5/builds/17 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_urllib2net make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Wed Feb 7 22:03:05 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 07 Feb 2007 21:03:05 +0000 Subject: [Python-checkins] buildbot warnings in sparc solaris10 gcc 2.5 Message-ID: <20070207210306.1CD421E4016@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%2520solaris10%2520gcc%25202.5/builds/206 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: 2 tests failed: test_codecmaps_jp test_codecmaps_kr sincerely, -The Buildbot From python-checkins at python.org Wed Feb 7 22:03:25 2007 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 7 Feb 2007 22:03:25 +0100 (CET) Subject: [Python-checkins] r53657 - python/branches/release25-maint/Doc/lib/libstdtypes.tex Message-ID: <20070207210325.906A21E4013@bag.python.org> Author: raymond.hettinger Date: Wed Feb 7 22:03:24 2007 New Revision: 53657 Modified: python/branches/release25-maint/Doc/lib/libstdtypes.tex Log: SF: 1397711 Set docs conflated immutable and hashable Modified: python/branches/release25-maint/Doc/lib/libstdtypes.tex ============================================================================== --- python/branches/release25-maint/Doc/lib/libstdtypes.tex (original) +++ python/branches/release25-maint/Doc/lib/libstdtypes.tex Wed Feb 7 22:03:24 2007 @@ -1224,7 +1224,7 @@ \label{types-set}} \obindex{set} -A \dfn{set} object is an unordered collection of immutable values. +A \dfn{set} object is an unordered collection of distinct hashable objects. Common uses include membership testing, removing duplicates from a sequence, and computing mathematical operations such as intersection, union, difference, and symmetric difference. From python-checkins at python.org Wed Feb 7 22:04:21 2007 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 7 Feb 2007 22:04:21 +0100 (CET) Subject: [Python-checkins] r53658 - python/trunk/Doc/lib/libstdtypes.tex Message-ID: <20070207210421.18DEA1E401E@bag.python.org> Author: raymond.hettinger Date: Wed Feb 7 22:04:20 2007 New Revision: 53658 Modified: python/trunk/Doc/lib/libstdtypes.tex Log: SF: 1397711 Set docs conflated immutable and hashable Modified: python/trunk/Doc/lib/libstdtypes.tex ============================================================================== --- python/trunk/Doc/lib/libstdtypes.tex (original) +++ python/trunk/Doc/lib/libstdtypes.tex Wed Feb 7 22:04:20 2007 @@ -1224,7 +1224,7 @@ \label{types-set}} \obindex{set} -A \dfn{set} object is an unordered collection of immutable values. +A \dfn{set} object is an unordered collection of distinct hashable objects. Common uses include membership testing, removing duplicates from a sequence, and computing mathematical operations such as intersection, union, difference, and symmetric difference. From buildbot at python.org Wed Feb 7 22:20:51 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 07 Feb 2007 21:20:51 +0000 Subject: [Python-checkins] buildbot warnings in x86 Ubuntu edgy (icc) 2.5 Message-ID: <20070207212051.BEE431E4037@bag.python.org> The Buildbot has detected a new failure of x86 Ubuntu edgy (icc) 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520Ubuntu%2520edgy%2520%2528icc%2529%25202.5/builds/153 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_timeout ====================================================================== FAIL: testConnectTimeout (test.test_timeout.TimeoutTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/Buildbot/2.5.baxter-ubuntu/build/Lib/test/test_timeout.py", line 128, in testConnectTimeout %(_delta, self.fuzz, _timeout)) AssertionError: timeout (3.24533) is more than 2 seconds more than expected (0.001) sincerely, -The Buildbot From python-checkins at python.org Wed Feb 7 22:40:51 2007 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 7 Feb 2007 22:40:51 +0100 (CET) Subject: [Python-checkins] r53659 - in python/branches/release25-maint: Lib/test/test_defaultdict.py Misc/NEWS Modules/collectionsmodule.c Message-ID: <20070207214051.490D31E4027@bag.python.org> Author: raymond.hettinger Date: Wed Feb 7 22:40:49 2007 New Revision: 53659 Modified: python/branches/release25-maint/Lib/test/test_defaultdict.py python/branches/release25-maint/Misc/NEWS python/branches/release25-maint/Modules/collectionsmodule.c Log: Check for a common user error with defaultdict(). Modified: python/branches/release25-maint/Lib/test/test_defaultdict.py ============================================================================== --- python/branches/release25-maint/Lib/test/test_defaultdict.py (original) +++ python/branches/release25-maint/Lib/test/test_defaultdict.py Wed Feb 7 22:40:49 2007 @@ -47,6 +47,7 @@ self.assertEqual(err.args, (15,)) else: self.fail("d2[15] didn't raise KeyError") + self.assertRaises(TypeError, defaultdict, 1) def test_missing(self): d1 = defaultdict() @@ -60,10 +61,10 @@ self.assertEqual(repr(d1), "defaultdict(None, {})") d1[11] = 41 self.assertEqual(repr(d1), "defaultdict(None, {11: 41})") - d2 = defaultdict(0) - self.assertEqual(d2.default_factory, 0) + d2 = defaultdict(int) + self.assertEqual(d2.default_factory, int) d2[12] = 42 - self.assertEqual(repr(d2), "defaultdict(0, {12: 42})") + self.assertEqual(repr(d2), "defaultdict(, {12: 42})") def foo(): return 43 d3 = defaultdict(foo) self.assert_(d3.default_factory is foo) Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Wed Feb 7 22:40:49 2007 @@ -103,6 +103,8 @@ Extension Modules ----------------- +- collections.defaultdict() now verifies that the factory function is callable. + - Bug #1486663: don't reject keyword arguments for subclasses of builtin types. Modified: python/branches/release25-maint/Modules/collectionsmodule.c ============================================================================== --- python/branches/release25-maint/Modules/collectionsmodule.c (original) +++ python/branches/release25-maint/Modules/collectionsmodule.c Wed Feb 7 22:40:49 2007 @@ -1252,8 +1252,14 @@ newargs = PyTuple_New(0); else { Py_ssize_t n = PyTuple_GET_SIZE(args); - if (n > 0) + if (n > 0) { newdefault = PyTuple_GET_ITEM(args, 0); + if (!PyCallable_Check(newdefault)) { + PyErr_SetString(PyExc_TypeError, + "first argument must be callable"); + return -1; + } + } newargs = PySequence_GetSlice(args, 1, n); } if (newargs == NULL) From python-checkins at python.org Wed Feb 7 22:42:17 2007 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 7 Feb 2007 22:42:17 +0100 (CET) Subject: [Python-checkins] r53660 - in python/trunk: Lib/test/test_defaultdict.py Modules/collectionsmodule.c Message-ID: <20070207214217.7E2911E4010@bag.python.org> Author: raymond.hettinger Date: Wed Feb 7 22:42:17 2007 New Revision: 53660 Modified: python/trunk/Lib/test/test_defaultdict.py python/trunk/Modules/collectionsmodule.c Log: Check for a common user error with defaultdict(). Modified: python/trunk/Lib/test/test_defaultdict.py ============================================================================== --- python/trunk/Lib/test/test_defaultdict.py (original) +++ python/trunk/Lib/test/test_defaultdict.py Wed Feb 7 22:42:17 2007 @@ -47,6 +47,7 @@ self.assertEqual(err.args, (15,)) else: self.fail("d2[15] didn't raise KeyError") + self.assertRaises(TypeError, defaultdict, 1) def test_missing(self): d1 = defaultdict() @@ -60,10 +61,10 @@ self.assertEqual(repr(d1), "defaultdict(None, {})") d1[11] = 41 self.assertEqual(repr(d1), "defaultdict(None, {11: 41})") - d2 = defaultdict(0) - self.assertEqual(d2.default_factory, 0) + d2 = defaultdict(int) + self.assertEqual(d2.default_factory, int) d2[12] = 42 - self.assertEqual(repr(d2), "defaultdict(0, {12: 42})") + self.assertEqual(repr(d2), "defaultdict(, {12: 42})") def foo(): return 43 d3 = defaultdict(foo) self.assert_(d3.default_factory is foo) Modified: python/trunk/Modules/collectionsmodule.c ============================================================================== --- python/trunk/Modules/collectionsmodule.c (original) +++ python/trunk/Modules/collectionsmodule.c Wed Feb 7 22:42:17 2007 @@ -1252,8 +1252,14 @@ newargs = PyTuple_New(0); else { Py_ssize_t n = PyTuple_GET_SIZE(args); - if (n > 0) + if (n > 0) { newdefault = PyTuple_GET_ITEM(args, 0); + if (!PyCallable_Check(newdefault)) { + PyErr_SetString(PyExc_TypeError, + "first argument must be callable"); + return -1; + } + } newargs = PySequence_GetSlice(args, 1, n); } if (newargs == NULL) From python-checkins at python.org Wed Feb 7 23:12:02 2007 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 7 Feb 2007 23:12:02 +0100 (CET) Subject: [Python-checkins] r53661 - in python/branches/release25-maint: Lib/test/test_operator.py Misc/NEWS Objects/abstract.c Message-ID: <20070207221202.554041E4013@bag.python.org> Author: raymond.hettinger Date: Wed Feb 7 23:12:01 2007 New Revision: 53661 Modified: python/branches/release25-maint/Lib/test/test_operator.py python/branches/release25-maint/Misc/NEWS python/branches/release25-maint/Objects/abstract.c Log: Bug #1575169: operator.isSequenceType() now returns False for subclasses of dict. Modified: python/branches/release25-maint/Lib/test/test_operator.py ============================================================================== --- python/branches/release25-maint/Lib/test/test_operator.py (original) +++ python/branches/release25-maint/Lib/test/test_operator.py Wed Feb 7 23:12:01 2007 @@ -215,6 +215,8 @@ self.failUnless(operator.isSequenceType(xrange(10))) self.failUnless(operator.isSequenceType('yeahbuddy')) self.failIf(operator.isSequenceType(3)) + class Dict(dict): pass + self.failIf(operator.isSequenceType(Dict())) def test_lshift(self): self.failUnlessRaises(TypeError, operator.lshift) Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Wed Feb 7 23:12:01 2007 @@ -103,6 +103,8 @@ Extension Modules ----------------- +- Bug #1575169: operator.isSequenceType() now returns False for subclasses of dict. + - collections.defaultdict() now verifies that the factory function is callable. - Bug #1486663: don't reject keyword arguments for subclasses of builtin Modified: python/branches/release25-maint/Objects/abstract.c ============================================================================== --- python/branches/release25-maint/Objects/abstract.c (original) +++ python/branches/release25-maint/Objects/abstract.c Wed Feb 7 23:12:01 2007 @@ -1157,6 +1157,8 @@ { if (s && PyInstance_Check(s)) return PyObject_HasAttrString(s, "__getitem__"); + if (PyObject_IsInstance(s, &PyDict_Type)) + return 0; return s != NULL && s->ob_type->tp_as_sequence && s->ob_type->tp_as_sequence->sq_item != NULL; } From python-checkins at python.org Wed Feb 7 23:24:08 2007 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 7 Feb 2007 23:24:08 +0100 (CET) Subject: [Python-checkins] r53662 - in python/trunk: Lib/test/test_operator.py Objects/abstract.c Message-ID: <20070207222408.84C0D1E4005@bag.python.org> Author: raymond.hettinger Date: Wed Feb 7 23:24:07 2007 New Revision: 53662 Modified: python/trunk/Lib/test/test_operator.py python/trunk/Objects/abstract.c Log: Bug #1575169: operator.isSequenceType() now returns False for subclasses of dict. Modified: python/trunk/Lib/test/test_operator.py ============================================================================== --- python/trunk/Lib/test/test_operator.py (original) +++ python/trunk/Lib/test/test_operator.py Wed Feb 7 23:24:07 2007 @@ -215,6 +215,8 @@ self.failUnless(operator.isSequenceType(xrange(10))) self.failUnless(operator.isSequenceType('yeahbuddy')) self.failIf(operator.isSequenceType(3)) + class Dict(dict): pass + self.failIf(operator.isSequenceType(Dict())) def test_lshift(self): self.failUnlessRaises(TypeError, operator.lshift) Modified: python/trunk/Objects/abstract.c ============================================================================== --- python/trunk/Objects/abstract.c (original) +++ python/trunk/Objects/abstract.c Wed Feb 7 23:24:07 2007 @@ -1157,6 +1157,8 @@ { if (s && PyInstance_Check(s)) return PyObject_HasAttrString(s, "__getitem__"); + if (PyObject_IsInstance(s, &PyDict_Type)) + return 0; return s != NULL && s->ob_type->tp_as_sequence && s->ob_type->tp_as_sequence->sq_item != NULL; } From python-checkins at python.org Thu Feb 8 00:48:15 2007 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 8 Feb 2007 00:48:15 +0100 (CET) Subject: [Python-checkins] r53663 - python/branches/release25-maint/Objects/abstract.c Message-ID: <20070207234815.B3B1B1E4005@bag.python.org> Author: raymond.hettinger Date: Thu Feb 8 00:48:15 2007 New Revision: 53663 Modified: python/branches/release25-maint/Objects/abstract.c Log: Silence compiler warning Modified: python/branches/release25-maint/Objects/abstract.c ============================================================================== --- python/branches/release25-maint/Objects/abstract.c (original) +++ python/branches/release25-maint/Objects/abstract.c Thu Feb 8 00:48:15 2007 @@ -1157,7 +1157,7 @@ { if (s && PyInstance_Check(s)) return PyObject_HasAttrString(s, "__getitem__"); - if (PyObject_IsInstance(s, &PyDict_Type)) + if (PyObject_IsInstance(s, (PyObject *)&PyDict_Type)) return 0; return s != NULL && s->ob_type->tp_as_sequence && s->ob_type->tp_as_sequence->sq_item != NULL; From python-checkins at python.org Thu Feb 8 00:49:04 2007 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 8 Feb 2007 00:49:04 +0100 (CET) Subject: [Python-checkins] r53664 - python/trunk/Objects/abstract.c Message-ID: <20070207234904.2EC6D1E4005@bag.python.org> Author: raymond.hettinger Date: Thu Feb 8 00:49:03 2007 New Revision: 53664 Modified: python/trunk/Objects/abstract.c Log: Silence compiler warning Modified: python/trunk/Objects/abstract.c ============================================================================== --- python/trunk/Objects/abstract.c (original) +++ python/trunk/Objects/abstract.c Thu Feb 8 00:49:03 2007 @@ -1157,7 +1157,7 @@ { if (s && PyInstance_Check(s)) return PyObject_HasAttrString(s, "__getitem__"); - if (PyObject_IsInstance(s, &PyDict_Type)) + if (PyObject_IsInstance(s, (PyObject *)&PyDict_Type)) return 0; return s != NULL && s->ob_type->tp_as_sequence && s->ob_type->tp_as_sequence->sq_item != NULL; From buildbot at python.org Thu Feb 8 00:54:02 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 07 Feb 2007 23:54:02 +0000 Subject: [Python-checkins] buildbot warnings in x86 Ubuntu edgy (icc) trunk Message-ID: <20070207235402.D0D631E4005@bag.python.org> The Buildbot has detected a new failure of x86 Ubuntu edgy (icc) trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520Ubuntu%2520edgy%2520%2528icc%2529%2520trunk/builds/1169 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: raymond.hettinger Build had warnings: warnings failed slave lost sincerely, -The Buildbot From python-checkins at python.org Thu Feb 8 00:57:06 2007 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 8 Feb 2007 00:57:06 +0100 (CET) Subject: [Python-checkins] r53665 - in python/branches/release25-maint: Lib/test/test_itertools.py Misc/NEWS Modules/itertoolsmodule.c Objects/enumobject.c Message-ID: <20070207235706.806DD1E4005@bag.python.org> Author: raymond.hettinger Date: Thu Feb 8 00:57:05 2007 New Revision: 53665 Modified: python/branches/release25-maint/Lib/test/test_itertools.py python/branches/release25-maint/Misc/NEWS python/branches/release25-maint/Modules/itertoolsmodule.c python/branches/release25-maint/Objects/enumobject.c Log: Do not let overflows in enumerate() and count() pass silently. Modified: python/branches/release25-maint/Lib/test/test_itertools.py ============================================================================== --- python/branches/release25-maint/Lib/test/test_itertools.py (original) +++ python/branches/release25-maint/Lib/test/test_itertools.py Thu Feb 8 00:57:05 2007 @@ -52,8 +52,7 @@ self.assertEqual(take(2, zip('abc',count(3))), [('a', 3), ('b', 4)]) self.assertRaises(TypeError, count, 2, 3) self.assertRaises(TypeError, count, 'a') - c = count(sys.maxint-2) # verify that rollover doesn't crash - c.next(); c.next(); c.next(); c.next(); c.next() + self.assertRaises(OverflowError, list, islice(count(sys.maxint-5), 10)) c = count(3) self.assertEqual(repr(c), 'count(3)') c.next() Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Thu Feb 8 00:57:05 2007 @@ -12,6 +12,8 @@ Core and builtins ----------------- +- SF #151204: enumerate() now raises an Overflow error at sys.maxint items. + - Bug #1377858: Fix the segfaulting of the interpreter when an object created a weakref on itself during a __del__ call for new-style classes (classic classes still have the bug). @@ -103,6 +105,8 @@ Extension Modules ----------------- +- operator.count() now raises an OverflowError when the count reaches sys.maxint. + - Bug #1575169: operator.isSequenceType() now returns False for subclasses of dict. - collections.defaultdict() now verifies that the factory function is callable. Modified: python/branches/release25-maint/Modules/itertoolsmodule.c ============================================================================== --- python/branches/release25-maint/Modules/itertoolsmodule.c (original) +++ python/branches/release25-maint/Modules/itertoolsmodule.c Thu Feb 8 00:57:05 2007 @@ -2073,6 +2073,11 @@ static PyObject * count_next(countobject *lz) { + if (lz->cnt == LONG_MAX) { + PyErr_SetString(PyExc_OverflowError, + "cannot count beyond LONG_MAX"); + return NULL; + } return PyInt_FromSsize_t(lz->cnt++); } Modified: python/branches/release25-maint/Objects/enumobject.c ============================================================================== --- python/branches/release25-maint/Objects/enumobject.c (original) +++ python/branches/release25-maint/Objects/enumobject.c Thu Feb 8 00:57:05 2007 @@ -62,6 +62,12 @@ PyObject *result = en->en_result; PyObject *it = en->en_sit; + if (en->en_index == LONG_MAX) { + PyErr_SetString(PyExc_OverflowError, + "enumerate() is limited to LONG_MAX items"); + return NULL; + } + next_item = (*it->ob_type->tp_iternext)(it); if (next_item == NULL) return NULL; From python-checkins at python.org Thu Feb 8 01:07:33 2007 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 8 Feb 2007 01:07:33 +0100 (CET) Subject: [Python-checkins] r53666 - in python/trunk: Lib/test/test_itertools.py Modules/itertoolsmodule.c Objects/enumobject.c Message-ID: <20070208000733.C0CDD1E4005@bag.python.org> Author: raymond.hettinger Date: Thu Feb 8 01:07:32 2007 New Revision: 53666 Modified: python/trunk/Lib/test/test_itertools.py python/trunk/Modules/itertoolsmodule.c python/trunk/Objects/enumobject.c Log: Do not let overflows in enumerate() and count() pass silently. Modified: python/trunk/Lib/test/test_itertools.py ============================================================================== --- python/trunk/Lib/test/test_itertools.py (original) +++ python/trunk/Lib/test/test_itertools.py Thu Feb 8 01:07:32 2007 @@ -52,8 +52,7 @@ self.assertEqual(take(2, zip('abc',count(3))), [('a', 3), ('b', 4)]) self.assertRaises(TypeError, count, 2, 3) self.assertRaises(TypeError, count, 'a') - c = count(sys.maxint-2) # verify that rollover doesn't crash - c.next(); c.next(); c.next(); c.next(); c.next() + self.assertRaises(OverflowError, list, islice(count(sys.maxint-5), 10)) c = count(3) self.assertEqual(repr(c), 'count(3)') c.next() Modified: python/trunk/Modules/itertoolsmodule.c ============================================================================== --- python/trunk/Modules/itertoolsmodule.c (original) +++ python/trunk/Modules/itertoolsmodule.c Thu Feb 8 01:07:32 2007 @@ -2073,6 +2073,11 @@ static PyObject * count_next(countobject *lz) { + if (lz->cnt == LONG_MAX) { + PyErr_SetString(PyExc_OverflowError, + "cannot count beyond LONG_MAX"); + return NULL; + } return PyInt_FromSsize_t(lz->cnt++); } Modified: python/trunk/Objects/enumobject.c ============================================================================== --- python/trunk/Objects/enumobject.c (original) +++ python/trunk/Objects/enumobject.c Thu Feb 8 01:07:32 2007 @@ -62,6 +62,12 @@ PyObject *result = en->en_result; PyObject *it = en->en_sit; + if (en->en_index == LONG_MAX) { + PyErr_SetString(PyExc_OverflowError, + "enumerate() is limited to LONG_MAX items"); + return NULL; + } + next_item = (*it->ob_type->tp_iternext)(it); if (next_item == NULL) return NULL; From python-checkins at python.org Thu Feb 8 01:49:52 2007 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 8 Feb 2007 01:49:52 +0100 (CET) Subject: [Python-checkins] r53667 - python/branches/release25-maint/Objects/setobject.c Message-ID: <20070208004952.7D2AE1E4005@bag.python.org> Author: raymond.hettinger Date: Thu Feb 8 01:49:51 2007 New Revision: 53667 Modified: python/branches/release25-maint/Objects/setobject.c Log: Bypass set specific optimizations for set and frozenset subclasses. Modified: python/branches/release25-maint/Objects/setobject.c ============================================================================== --- python/branches/release25-maint/Objects/setobject.c (original) +++ python/branches/release25-maint/Objects/setobject.c Thu Feb 8 01:49:51 2007 @@ -912,7 +912,7 @@ { PyObject *key, *it; - if (PyAnySet_Check(other)) + if (PyAnySet_CheckExact(other)) return set_merge(so, other); if (PyDict_CheckExact(other)) { @@ -1190,7 +1190,7 @@ if (result == NULL) return NULL; - if (PyAnySet_Check(other)) { + if (PyAnySet_CheckExact(other)) { Py_ssize_t pos = 0; setentry *entry; @@ -1314,7 +1314,7 @@ if ((PyObject *)so == other) return set_clear_internal(so); - if (PyAnySet_Check(other)) { + if (PyAnySet_CheckExact(other)) { setentry *entry; Py_ssize_t pos = 0; @@ -1363,7 +1363,7 @@ setentry *entry; Py_ssize_t pos = 0; - if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) { + if (!PyAnySet_CheckExact(other) && !PyDict_CheckExact(other)) { result = set_copy(so); if (result == NULL) return NULL; @@ -1472,7 +1472,7 @@ Py_RETURN_NONE; } - if (PyAnySet_Check(other)) { + if (PyAnySet_CheckExact(other)) { Py_INCREF(other); otherset = (PySetObject *)other; } else { @@ -1555,7 +1555,7 @@ setentry *entry; Py_ssize_t pos = 0; - if (!PyAnySet_Check(other)) { + if (!PyAnySet_CheckExact(other)) { PyObject *tmp, *result; tmp = make_new_set(&PySet_Type, other); if (tmp == NULL) @@ -1584,7 +1584,7 @@ { PyObject *tmp, *result; - if (!PyAnySet_Check(other)) { + if (!PyAnySet_CheckExact(other)) { tmp = make_new_set(&PySet_Type, other); if (tmp == NULL) return NULL; From python-checkins at python.org Thu Feb 8 01:50:40 2007 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 8 Feb 2007 01:50:40 +0100 (CET) Subject: [Python-checkins] r53668 - python/trunk/Objects/setobject.c Message-ID: <20070208005040.257761E4032@bag.python.org> Author: raymond.hettinger Date: Thu Feb 8 01:50:39 2007 New Revision: 53668 Modified: python/trunk/Objects/setobject.c Log: Bypass set specific optimizations for set and frozenset subclasses. Modified: python/trunk/Objects/setobject.c ============================================================================== --- python/trunk/Objects/setobject.c (original) +++ python/trunk/Objects/setobject.c Thu Feb 8 01:50:39 2007 @@ -912,7 +912,7 @@ { PyObject *key, *it; - if (PyAnySet_Check(other)) + if (PyAnySet_CheckExact(other)) return set_merge(so, other); if (PyDict_CheckExact(other)) { @@ -1190,7 +1190,7 @@ if (result == NULL) return NULL; - if (PyAnySet_Check(other)) { + if (PyAnySet_CheckExact(other)) { Py_ssize_t pos = 0; setentry *entry; @@ -1314,7 +1314,7 @@ if ((PyObject *)so == other) return set_clear_internal(so); - if (PyAnySet_Check(other)) { + if (PyAnySet_CheckExact(other)) { setentry *entry; Py_ssize_t pos = 0; @@ -1363,7 +1363,7 @@ setentry *entry; Py_ssize_t pos = 0; - if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) { + if (!PyAnySet_CheckExact(other) && !PyDict_CheckExact(other)) { result = set_copy(so); if (result == NULL) return NULL; @@ -1472,7 +1472,7 @@ Py_RETURN_NONE; } - if (PyAnySet_Check(other)) { + if (PyAnySet_CheckExact(other)) { Py_INCREF(other); otherset = (PySetObject *)other; } else { @@ -1555,7 +1555,7 @@ setentry *entry; Py_ssize_t pos = 0; - if (!PyAnySet_Check(other)) { + if (!PyAnySet_CheckExact(other)) { PyObject *tmp, *result; tmp = make_new_set(&PySet_Type, other); if (tmp == NULL) @@ -1584,7 +1584,7 @@ { PyObject *tmp, *result; - if (!PyAnySet_Check(other)) { + if (!PyAnySet_CheckExact(other)) { tmp = make_new_set(&PySet_Type, other); if (tmp == NULL) return NULL; From buildbot at python.org Thu Feb 8 02:10:12 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 08 Feb 2007 01:10:12 +0000 Subject: [Python-checkins] buildbot warnings in x86 Ubuntu edgy (icc) 2.5 Message-ID: <20070208011012.3A8331E4005@bag.python.org> The Buildbot has detected a new failure of x86 Ubuntu edgy (icc) 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520Ubuntu%2520edgy%2520%2528icc%2529%25202.5/builds/155 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_timeout ====================================================================== FAIL: testConnectTimeout (test.test_timeout.TimeoutTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/Buildbot/2.5.baxter-ubuntu/build/Lib/test/test_timeout.py", line 128, in testConnectTimeout %(_delta, self.fuzz, _timeout)) AssertionError: timeout (3.73337) is more than 2 seconds more than expected (0.001) sincerely, -The Buildbot From python-checkins at python.org Thu Feb 8 02:37:18 2007 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 8 Feb 2007 02:37:18 +0100 (CET) Subject: [Python-checkins] r53669 - python/branches/release25-maint/Lib/decimal.py Message-ID: <20070208013718.D11141E4005@bag.python.org> Author: raymond.hettinger Date: Thu Feb 8 02:37:18 2007 New Revision: 53669 Modified: python/branches/release25-maint/Lib/decimal.py Log: Fix docstring bug Modified: python/branches/release25-maint/Lib/decimal.py ============================================================================== --- python/branches/release25-maint/Lib/decimal.py (original) +++ python/branches/release25-maint/Lib/decimal.py Thu Feb 8 02:37:18 2007 @@ -487,7 +487,7 @@ 28 >>> with localcontext(): ... ctx = getcontext() - ... ctx.prec() += 2 + ... ctx.prec += 2 ... print ctx.prec ... 30 From python-checkins at python.org Thu Feb 8 02:42:36 2007 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 8 Feb 2007 02:42:36 +0100 (CET) Subject: [Python-checkins] r53670 - python/trunk/Lib/decimal.py Message-ID: <20070208014236.7E7F61E4005@bag.python.org> Author: raymond.hettinger Date: Thu Feb 8 02:42:35 2007 New Revision: 53670 Modified: python/trunk/Lib/decimal.py Log: Fix docstring bug Modified: python/trunk/Lib/decimal.py ============================================================================== --- python/trunk/Lib/decimal.py (original) +++ python/trunk/Lib/decimal.py Thu Feb 8 02:42:35 2007 @@ -487,7 +487,7 @@ 28 >>> with localcontext(): ... ctx = getcontext() - ... ctx.prec() += 2 + ... ctx.prec += 2 ... print ctx.prec ... 30 From buildbot at python.org Thu Feb 8 04:03:51 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 08 Feb 2007 03:03:51 +0000 Subject: [Python-checkins] buildbot warnings in alpha Tru64 5.1 2.5 Message-ID: <20070208030352.044DA1E4005@bag.python.org> The Buildbot has detected a new failure of alpha Tru64 5.1 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/alpha%2520Tru64%25205.1%25202.5/builds/163 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_socket ====================================================================== FAIL: testInterruptedTimeout (test.test_socket.TCPTimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/net/ringneck/scratch1/nnorwitz/python/2.5.norwitz-tru64/build/Lib/test/test_socket.py", line 872, in testInterruptedTimeout self.fail("got Alarm in wrong place") AssertionError: got Alarm in wrong place sincerely, -The Buildbot From buildbot at python.org Thu Feb 8 04:10:05 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 08 Feb 2007 03:10:05 +0000 Subject: [Python-checkins] buildbot warnings in S-390 Debian trunk Message-ID: <20070208031005.99D771E4005@bag.python.org> The Buildbot has detected a new failure of S-390 Debian trunk. Full details are available at: http://www.python.org/dev/buildbot/all/S-390%2520Debian%2520trunk/builds/655 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_urllibnet make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Thu Feb 8 04:12:26 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 08 Feb 2007 03:12:26 +0000 Subject: [Python-checkins] buildbot warnings in hppa Ubuntu dapper trunk Message-ID: <20070208031226.96E151E4005@bag.python.org> The Buildbot has detected a new failure of hppa Ubuntu dapper trunk. Full details are available at: http://www.python.org/dev/buildbot/all/hppa%2520Ubuntu%2520dapper%2520trunk/builds/65 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: sincerely, -The Buildbot From buildbot at python.org Thu Feb 8 05:08:43 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 08 Feb 2007 04:08:43 +0000 Subject: [Python-checkins] buildbot warnings in sparc solaris10 gcc trunk Message-ID: <20070208040843.7C54B1E4005@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc trunk. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%2520solaris10%2520gcc%2520trunk/builds/1745 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_socketserver Traceback (most recent call last): File "/opt/users/buildbot/slave/trunk.loewis-sun/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/opt/users/buildbot/slave/trunk.loewis-sun/build/Lib/test/test_socketserver.py", line 81, in run svr = svrcls(self.__addr, self.__hdlrcls) File "/opt/users/buildbot/slave/trunk.loewis-sun/build/Lib/SocketServer.py", line 330, in __init__ self.server_bind() File "/opt/users/buildbot/slave/trunk.loewis-sun/build/Lib/SocketServer.py", line 341, in server_bind self.socket.bind(self.server_address) File "", line 1, in bind error: (125, 'Address already in use') Traceback (most recent call last): File "/opt/users/buildbot/slave/trunk.loewis-sun/build/Lib/threading.py", line 473, in __bootstrap (self.getName(), _format_exc())) File "/opt/users/buildbot/slave/trunk.loewis-sun/build/Lib/traceback.py", line 236, in format_exc return ''.join(format_exception(etype, value, tb, limit)) File "/opt/users/buildbot/slave/trunk.loewis-sun/build/Lib/traceback.py", line 142, in format_exception list = list + format_tb(tb, limit) File "/opt/users/buildbot/slave/trunk.loewis-sun/build/Lib/traceback.py", line 76, in format_tb return format_list(extract_tb(tb, limit)) File "/opt/users/buildbot/slave/trunk.loewis-sun/build/Lib/traceback.py", line 101, in extract_tb line = linecache.getline(filename, lineno, f.f_globals) AttributeError: 'NoneType' object has no attribute 'getline' sincerely, -The Buildbot From python-checkins at python.org Thu Feb 8 10:13:38 2007 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 8 Feb 2007 10:13:38 +0100 (CET) Subject: [Python-checkins] r53671 - in python/trunk: Lib/test/test_datetime.py Misc/NEWS Modules/datetimemodule.c Message-ID: <20070208091338.0B8EB1E4005@bag.python.org> Author: martin.v.loewis Date: Thu Feb 8 10:13:36 2007 New Revision: 53671 Modified: python/trunk/Lib/test/test_datetime.py python/trunk/Misc/NEWS python/trunk/Modules/datetimemodule.c Log: Bug #1653736: Complain about keyword arguments to time.isoformat. Will backport to 2.5. Modified: python/trunk/Lib/test/test_datetime.py ============================================================================== --- python/trunk/Lib/test/test_datetime.py (original) +++ python/trunk/Lib/test/test_datetime.py Thu Feb 8 10:13:36 2007 @@ -1740,6 +1740,11 @@ self.assertEqual(t.isoformat(), "00:00:00.100000") self.assertEqual(t.isoformat(), str(t)) + def test_1653736(self): + # verify it doesn't accept extra keyword arguments + t = self.theclass(second=1) + self.assertRaises(TypeError, t.isoformat, foo=3) + def test_strftime(self): t = self.theclass(1, 2, 3, 4) self.assertEqual(t.strftime('%H %M %S'), "01 02 03") Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Feb 8 10:13:36 2007 @@ -347,6 +347,8 @@ Extension Modules ----------------- +- Bug #1653736: Complain about keyword arguments to time.isoformat. + - Bug #1486663: don't reject keyword arguments for subclasses of builtin types. Modified: python/trunk/Modules/datetimemodule.c ============================================================================== --- python/trunk/Modules/datetimemodule.c (original) +++ python/trunk/Modules/datetimemodule.c Thu Feb 8 10:13:36 2007 @@ -3167,7 +3167,7 @@ } static PyObject * -time_isoformat(PyDateTime_Time *self) +time_isoformat(PyDateTime_Time *self, PyObject *unused) { char buf[100]; PyObject *result; @@ -3411,7 +3411,7 @@ static PyMethodDef time_methods[] = { - {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS, + {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS, PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]" "[+HH:MM].")}, From python-checkins at python.org Thu Feb 8 10:13:52 2007 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 8 Feb 2007 10:13:52 +0100 (CET) Subject: [Python-checkins] r53672 - in python/branches/release25-maint: Lib/test/test_datetime.py Misc/NEWS Modules/datetimemodule.c Message-ID: <20070208091352.8FC4B1E4005@bag.python.org> Author: martin.v.loewis Date: Thu Feb 8 10:13:51 2007 New Revision: 53672 Modified: python/branches/release25-maint/Lib/test/test_datetime.py python/branches/release25-maint/Misc/NEWS python/branches/release25-maint/Modules/datetimemodule.c Log: Bug #1653736: Complain about keyword arguments to time.isoformat. Modified: python/branches/release25-maint/Lib/test/test_datetime.py ============================================================================== --- python/branches/release25-maint/Lib/test/test_datetime.py (original) +++ python/branches/release25-maint/Lib/test/test_datetime.py Thu Feb 8 10:13:51 2007 @@ -1740,6 +1740,11 @@ self.assertEqual(t.isoformat(), "00:00:00.100000") self.assertEqual(t.isoformat(), str(t)) + def test_1653736(self): + # verify it doesn't accept extra keyword arguments + t = self.theclass(second=1) + self.assertRaises(TypeError, t.isoformat, foo=3) + def test_strftime(self): t = self.theclass(1, 2, 3, 4) self.assertEqual(t.strftime('%H %M %S'), "01 02 03") Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Thu Feb 8 10:13:51 2007 @@ -105,6 +105,8 @@ Extension Modules ----------------- +- Bug #1653736: Complain about keyword arguments to time.isoformat. + - operator.count() now raises an OverflowError when the count reaches sys.maxint. - Bug #1575169: operator.isSequenceType() now returns False for subclasses of dict. Modified: python/branches/release25-maint/Modules/datetimemodule.c ============================================================================== --- python/branches/release25-maint/Modules/datetimemodule.c (original) +++ python/branches/release25-maint/Modules/datetimemodule.c Thu Feb 8 10:13:51 2007 @@ -3167,7 +3167,7 @@ } static PyObject * -time_isoformat(PyDateTime_Time *self) +time_isoformat(PyDateTime_Time *self, PyObject *unused) { char buf[100]; PyObject *result; @@ -3411,7 +3411,7 @@ static PyMethodDef time_methods[] = { - {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS, + {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS, PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]" "[+HH:MM].")}, From nnorwitz at gmail.com Thu Feb 8 11:23:05 2007 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 8 Feb 2007 05:23:05 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20070208102305.GA8084@python.psfb.org> test_cmd_line leaked [17, 0, -17] references test_softspace leaked [0, 90, 0] references From buildbot at python.org Thu Feb 8 11:36:05 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 08 Feb 2007 10:36:05 +0000 Subject: [Python-checkins] buildbot warnings in x86 Ubuntu edgy (icc) trunk Message-ID: <20070208103605.5FF841E401A@bag.python.org> The Buildbot has detected a new failure of x86 Ubuntu edgy (icc) trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520Ubuntu%2520edgy%2520%2528icc%2529%2520trunk/builds/1172 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 2 tests failed: test_timeout test_urllibnet ====================================================================== FAIL: testConnectTimeout (test.test_timeout.TimeoutTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/test/test_timeout.py", line 128, in testConnectTimeout %(_delta, self.fuzz, _timeout)) AssertionError: timeout (3.20527) is more than 2 seconds more than expected (0.001) sincerely, -The Buildbot From buildbot at python.org Thu Feb 8 12:18:54 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 08 Feb 2007 11:18:54 +0000 Subject: [Python-checkins] buildbot warnings in alpha Tru64 5.1 2.5 Message-ID: <20070208111854.6B9811E4005@bag.python.org> The Buildbot has detected a new failure of alpha Tru64 5.1 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/alpha%2520Tru64%25205.1%25202.5/builds/165 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 2 tests failed: test_signal test_socket sincerely, -The Buildbot From buildbot at python.org Thu Feb 8 13:52:47 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 08 Feb 2007 12:52:47 +0000 Subject: [Python-checkins] buildbot warnings in x86 Ubuntu edgy (icc) 2.5 Message-ID: <20070208125247.512501E4007@bag.python.org> The Buildbot has detected a new failure of x86 Ubuntu edgy (icc) 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520Ubuntu%2520edgy%2520%2528icc%2529%25202.5/builds/157 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_timeout ====================================================================== FAIL: testConnectTimeout (test.test_timeout.TimeoutTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/Buildbot/2.5.baxter-ubuntu/build/Lib/test/test_timeout.py", line 128, in testConnectTimeout %(_delta, self.fuzz, _timeout)) AssertionError: timeout (3.5533) is more than 2 seconds more than expected (0.001) sincerely, -The Buildbot From python-checkins at python.org Thu Feb 8 21:08:16 2007 From: python-checkins at python.org (phillip.eby) Date: Thu, 8 Feb 2007 21:08:16 +0100 (CET) Subject: [Python-checkins] r53673 - sandbox/trunk/setuptools/pkg_resources.py Message-ID: <20070208200816.D88EB1E4007@bag.python.org> Author: phillip.eby Date: Thu Feb 8 21:08:16 2007 New Revision: 53673 Modified: sandbox/trunk/setuptools/pkg_resources.py Log: Ensure extracted libraries have correct permissions on Posix systems (e.g. Cygwin, which is where I found the problem.) Modified: sandbox/trunk/setuptools/pkg_resources.py ============================================================================== --- sandbox/trunk/setuptools/pkg_resources.py (original) +++ sandbox/trunk/setuptools/pkg_resources.py Thu Feb 8 21:08:16 2007 @@ -883,6 +883,23 @@ return target_path + + + + + + + + + + + + + + + + + def postprocess(self, tempname, filename): """Perform any platform-specific postprocessing of `tempname` @@ -897,7 +914,31 @@ is the name it will be renamed to by the caller after this routine returns. """ - # XXX + + if os.name == 'posix': + # Make the resource executable + mode = ((os.stat(tempname).st_mode) | 0555) & 07777 + os.chmod(tempname, mode) + + + + + + + + + + + + + + + + + + + + def set_extraction_path(self, path): From python-checkins at python.org Thu Feb 8 21:11:22 2007 From: python-checkins at python.org (phillip.eby) Date: Thu, 8 Feb 2007 21:11:22 +0100 (CET) Subject: [Python-checkins] r53674 - sandbox/branches/setuptools-0.6/pkg_resources.py sandbox/branches/setuptools-0.6/pkg_resources.txt Message-ID: <20070208201122.BF4791E4007@bag.python.org> Author: phillip.eby Date: Thu Feb 8 21:11:22 2007 New Revision: 53674 Modified: sandbox/branches/setuptools-0.6/pkg_resources.py sandbox/branches/setuptools-0.6/pkg_resources.txt Log: Fix extracted C extensions not having executable permissions under Cygwin. (backport from trunk) Modified: sandbox/branches/setuptools-0.6/pkg_resources.py ============================================================================== --- sandbox/branches/setuptools-0.6/pkg_resources.py (original) +++ sandbox/branches/setuptools-0.6/pkg_resources.py Thu Feb 8 21:11:22 2007 @@ -883,6 +883,23 @@ return target_path + + + + + + + + + + + + + + + + + def postprocess(self, tempname, filename): """Perform any platform-specific postprocessing of `tempname` @@ -897,7 +914,31 @@ is the name it will be renamed to by the caller after this routine returns. """ - # XXX + + if os.name == 'posix': + # Make the resource executable + mode = ((os.stat(tempname).st_mode) | 0555) & 07777 + os.chmod(tempname, mode) + + + + + + + + + + + + + + + + + + + + def set_extraction_path(self, path): Modified: sandbox/branches/setuptools-0.6/pkg_resources.txt ============================================================================== --- sandbox/branches/setuptools-0.6/pkg_resources.txt (original) +++ sandbox/branches/setuptools-0.6/pkg_resources.txt Thu Feb 8 21:11:22 2007 @@ -1692,6 +1692,9 @@ Release Notes/Change History ---------------------------- +0.6c6 + * Fix extracted C extensions not having executable permissions under Cygwin. + 0.6c4 * Fix "dev" versions being considered newer than release candidates. From python-checkins at python.org Thu Feb 8 23:32:36 2007 From: python-checkins at python.org (guido.van.rossum) Date: Thu, 8 Feb 2007 23:32:36 +0100 (CET) Subject: [Python-checkins] r53675 - sandbox/trunk/2to3/fixes/find_pattern.py Message-ID: <20070208223236.290561E4012@bag.python.org> Author: guido.van.rossum Date: Thu Feb 8 23:32:35 2007 New Revision: 53675 Added: sandbox/trunk/2to3/fixes/find_pattern.py (contents, props changed) Log: Helper script by Collin Winter. Added: sandbox/trunk/2to3/fixes/find_pattern.py ============================================================================== --- (empty file) +++ sandbox/trunk/2to3/fixes/find_pattern.py Thu Feb 8 23:32:35 2007 @@ -0,0 +1,98 @@ +#!/usr/bin/env python2.5 + +"""A script that makes determining PATTERN for a new fixer much, much easier. + +Figuring out exactly what PATTERN I want for a given fixer class is +getting tedious. This script will step through each possible subtree +for a given string, allowing you to select which one you want. It will +then try to figure out an appropriate pattern to match that tree. This +pattern will require some editing (it will be overly restrictive) but +should provide a solid base to work with and handle the tricky parts. + +Usage: + + python find_pattern.py "g.throw(E, V, T)" + +This will step through each subtree in the parse. To reject a +candidate subtree, hit enter; to accept a candidate, hit "y" and +enter. The pattern will be spit out to stdout. + +For example, the above will yield a succession of possible snippets, +skipping all leaf-only trees. I accept + +'g.throw(E, V, T)' + +This causes find_pattern to spit out + +power< 'g' trailer< '.' 'throw' > + trailer< '(' arglist< 'E' ',' 'V' ',' 'T' > ')' > > + + +Some minor tweaks later, I'm left with + +power< any trailer< '.' 'throw' > + trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' > > + + +which is exactly what I was after. + +Larger snippets can be placed in a file (as opposed to a command-line +arg) and processed with the -f option. +""" + +__author__ = "Collin Winter " + +# Python imports +import optparse +import sys +from StringIO import StringIO + +# Local imports +import pytree +from pgen2 import driver +from pygram import python_symbols, python_grammar + +driver = driver.Driver(python_grammar, convert=pytree.convert) + +def main(args): + parser = optparse.OptionParser(usage="find_pattern.py [options] [string]") + parser.add_option("-f", "--file", action="store", + help="Read a code snippet from the specified file") + + # Parse command line arguments + options, args = parser.parse_args(args) + if options.file: + tree = driver.parse_file(options.file) + elif len(args) > 1: + tree = driver.parse_stream(StringIO(args[1] + "\n")) + else: + print >>sys.stderr, "You must specify an input file or an input string" + return 1 + + examine_tree(tree) + return 0 + +def examine_tree(tree): + for node in tree.post_order(): + if isinstance(node, pytree.Leaf): + continue + print repr(str(node)) + verdict = raw_input() + if verdict.strip(): + print find_pattern(node) + return + +def find_pattern(node): + if isinstance(node, pytree.Leaf): + return repr(node.value) + + return find_symbol(node.type) + \ + "< " + " ".join(find_pattern(n) for n in node.children) + " >" + +def find_symbol(sym): + for n, v in python_symbols.__dict__.items(): + if v == sym: + return n + +if __name__ == "__main__": + sys.exit(main(sys.argv)) From python-checkins at python.org Thu Feb 8 23:35:32 2007 From: python-checkins at python.org (guido.van.rossum) Date: Thu, 8 Feb 2007 23:35:32 +0100 (CET) Subject: [Python-checkins] r53676 - in sandbox/trunk/2to3: find_pattern.py fixes/find_pattern.py Message-ID: <20070208223532.2720F1E401A@bag.python.org> Author: guido.van.rossum Date: Thu Feb 8 23:35:31 2007 New Revision: 53676 Added: sandbox/trunk/2to3/find_pattern.py (contents, props changed) Removed: sandbox/trunk/2to3/fixes/find_pattern.py Log: Move find_pattern.py to where it belongs. [Blush.] Added: sandbox/trunk/2to3/find_pattern.py ============================================================================== --- (empty file) +++ sandbox/trunk/2to3/find_pattern.py Thu Feb 8 23:35:31 2007 @@ -0,0 +1,97 @@ +#!/usr/bin/env python2.5 + +"""Script that makes determining PATTERN for a new fix much easier. + +Figuring out exactly what PATTERN I want for a given fixer class is +getting tedious. This script will step through each possible subtree +for a given string, allowing you to select which one you want. It will +then try to figure out an appropriate pattern to match that tree. This +pattern will require some editing (it will be overly restrictive) but +should provide a solid base to work with and handle the tricky parts. + +Usage: + + python find_pattern.py "g.throw(E, V, T)" + +This will step through each subtree in the parse. To reject a +candidate subtree, hit enter; to accept a candidate, hit "y" and +enter. The pattern will be spit out to stdout. + +For example, the above will yield a succession of possible snippets, +skipping all leaf-only trees. I accept + +'g.throw(E, V, T)' + +This causes find_pattern to spit out + +power< 'g' trailer< '.' 'throw' > + trailer< '(' arglist< 'E' ',' 'V' ',' 'T' > ')' > > + + +Some minor tweaks later, I'm left with + +power< any trailer< '.' 'throw' > + trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' > > + +which is exactly what I was after. + +Larger snippets can be placed in a file (as opposed to a command-line +arg) and processed with the -f option. +""" + +__author__ = "Collin Winter " + +# Python imports +import optparse +import sys +from StringIO import StringIO + +# Local imports +import pytree +from pgen2 import driver +from pygram import python_symbols, python_grammar + +driver = driver.Driver(python_grammar, convert=pytree.convert) + +def main(args): + parser = optparse.OptionParser(usage="find_pattern.py [options] [string]") + parser.add_option("-f", "--file", action="store", + help="Read a code snippet from the specified file") + + # Parse command line arguments + options, args = parser.parse_args(args) + if options.file: + tree = driver.parse_file(options.file) + elif len(args) > 1: + tree = driver.parse_stream(StringIO(args[1] + "\n")) + else: + print >>sys.stderr, "You must specify an input file or an input string" + return 1 + + examine_tree(tree) + return 0 + +def examine_tree(tree): + for node in tree.post_order(): + if isinstance(node, pytree.Leaf): + continue + print repr(str(node)) + verdict = raw_input() + if verdict.strip(): + print find_pattern(node) + return + +def find_pattern(node): + if isinstance(node, pytree.Leaf): + return repr(node.value) + + return find_symbol(node.type) + \ + "< " + " ".join(find_pattern(n) for n in node.children) + " >" + +def find_symbol(sym): + for n, v in python_symbols.__dict__.items(): + if v == sym: + return n + +if __name__ == "__main__": + sys.exit(main(sys.argv)) Deleted: /sandbox/trunk/2to3/fixes/find_pattern.py ============================================================================== --- /sandbox/trunk/2to3/fixes/find_pattern.py Thu Feb 8 23:35:31 2007 +++ (empty file) @@ -1,98 +0,0 @@ -#!/usr/bin/env python2.5 - -"""A script that makes determining PATTERN for a new fixer much, much easier. - -Figuring out exactly what PATTERN I want for a given fixer class is -getting tedious. This script will step through each possible subtree -for a given string, allowing you to select which one you want. It will -then try to figure out an appropriate pattern to match that tree. This -pattern will require some editing (it will be overly restrictive) but -should provide a solid base to work with and handle the tricky parts. - -Usage: - - python find_pattern.py "g.throw(E, V, T)" - -This will step through each subtree in the parse. To reject a -candidate subtree, hit enter; to accept a candidate, hit "y" and -enter. The pattern will be spit out to stdout. - -For example, the above will yield a succession of possible snippets, -skipping all leaf-only trees. I accept - -'g.throw(E, V, T)' - -This causes find_pattern to spit out - -power< 'g' trailer< '.' 'throw' > - trailer< '(' arglist< 'E' ',' 'V' ',' 'T' > ')' > > - - -Some minor tweaks later, I'm left with - -power< any trailer< '.' 'throw' > - trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' > > - - -which is exactly what I was after. - -Larger snippets can be placed in a file (as opposed to a command-line -arg) and processed with the -f option. -""" - -__author__ = "Collin Winter " - -# Python imports -import optparse -import sys -from StringIO import StringIO - -# Local imports -import pytree -from pgen2 import driver -from pygram import python_symbols, python_grammar - -driver = driver.Driver(python_grammar, convert=pytree.convert) - -def main(args): - parser = optparse.OptionParser(usage="find_pattern.py [options] [string]") - parser.add_option("-f", "--file", action="store", - help="Read a code snippet from the specified file") - - # Parse command line arguments - options, args = parser.parse_args(args) - if options.file: - tree = driver.parse_file(options.file) - elif len(args) > 1: - tree = driver.parse_stream(StringIO(args[1] + "\n")) - else: - print >>sys.stderr, "You must specify an input file or an input string" - return 1 - - examine_tree(tree) - return 0 - -def examine_tree(tree): - for node in tree.post_order(): - if isinstance(node, pytree.Leaf): - continue - print repr(str(node)) - verdict = raw_input() - if verdict.strip(): - print find_pattern(node) - return - -def find_pattern(node): - if isinstance(node, pytree.Leaf): - return repr(node.value) - - return find_symbol(node.type) + \ - "< " + " ".join(find_pattern(n) for n in node.children) + " >" - -def find_symbol(sym): - for n, v in python_symbols.__dict__.items(): - if v == sym: - return n - -if __name__ == "__main__": - sys.exit(main(sys.argv)) From python-checkins at python.org Thu Feb 8 23:42:36 2007 From: python-checkins at python.org (guido.van.rossum) Date: Thu, 8 Feb 2007 23:42:36 +0100 (CET) Subject: [Python-checkins] r53677 - in sandbox/trunk/2to3: example.py fixer_tests.py fixes/basefix.py fixes/fix_apply.py fixes/fix_except.py fixes/fix_exec.py fixes/fix_has_key.py fixes/fix_intern.py fixes/fix_long.py fixes/fix_print.py fixes/fix_raise.py fixes/fix_repr.py fixes/fix_sysexcinfo.py fixes/fix_throw.py fixes/macros.py pytree.py refactor.py Message-ID: <20070208224236.B638D1E4008@bag.python.org> Author: guido.van.rossum Date: Thu Feb 8 23:42:35 2007 New Revision: 53677 Added: sandbox/trunk/2to3/fixes/fix_sysexcinfo.py (contents, props changed) sandbox/trunk/2to3/fixes/fix_throw.py (contents, props changed) sandbox/trunk/2to3/fixes/macros.py (contents, props changed) Modified: sandbox/trunk/2to3/example.py sandbox/trunk/2to3/fixer_tests.py sandbox/trunk/2to3/fixes/basefix.py sandbox/trunk/2to3/fixes/fix_apply.py sandbox/trunk/2to3/fixes/fix_except.py sandbox/trunk/2to3/fixes/fix_exec.py sandbox/trunk/2to3/fixes/fix_has_key.py sandbox/trunk/2to3/fixes/fix_intern.py sandbox/trunk/2to3/fixes/fix_long.py sandbox/trunk/2to3/fixes/fix_print.py sandbox/trunk/2to3/fixes/fix_raise.py sandbox/trunk/2to3/fixes/fix_repr.py sandbox/trunk/2to3/pytree.py sandbox/trunk/2to3/refactor.py Log: Lots of new stuff by Collin Winter: - macros.patch is a new version of the earlier macros.patch. - better_raise.patch allows 2to3 to convert three-argument raise statements. This depends on macros.patch. - fix_throw.patch converts two- and three-argument generator.throw() calls much like fix_raise does. - fix_sysexcinfo.patch adds a fixer that warns on usage of sys.exc_{info,type,value,traceback}. Right now I see some test failures; I'll ask Collin to address these. Modified: sandbox/trunk/2to3/example.py ============================================================================== --- sandbox/trunk/2to3/example.py (original) +++ sandbox/trunk/2to3/example.py Thu Feb 8 23:42:35 2007 @@ -165,7 +165,7 @@ except Exception, (f, e): pass except ImportError, e: - pass + print e.args # try: pass @@ -208,7 +208,7 @@ pass except (Exception, SystemExit): pass - + def raise_examples(): raise Exception, 5 # @@ -223,10 +223,14 @@ raise Exception(5, 6) # # These should produce a warning + # TODO: convert "raise E, V, T" to + # "e = E(V); e.__traceback__ = T; raise e;" # raise Exception, 5, 6 # raise Exception,5,6 + # + raise Exception, (5, 6, 7), 6 def long_examples(): x = long(x) @@ -238,6 +242,6 @@ a = 12 b = 0x12 c = 3.14 - - + + # This is the last line. Modified: sandbox/trunk/2to3/fixer_tests.py ============================================================================== --- sandbox/trunk/2to3/fixer_tests.py (original) +++ sandbox/trunk/2to3/fixer_tests.py Thu Feb 8 23:42:35 2007 @@ -11,14 +11,18 @@ import refactor +# We wrap the RefactoringTool's fixer objects so we can intercept +# the call to set_filename() and so modify the fixers' logging objects. +# This allows us to make sure that certain code chunks produce certain +# warnings. class Fixer(object): def __init__(self, fixer, handler): self.fixer = fixer self.handler = handler - + def __getattr__(self, attr): return getattr(self.fixer, attr) - + def set_filename(self, filename): self.fixer.set_filename(filename) self.fixer.logger.addHandler(self.handler) @@ -27,30 +31,29 @@ def __init__(self, **kwargs): for k, v in kwargs.items(): setattr(self, k, v) - + self.verbose = False class FixerTestCase(unittest.TestCase): def setUp(self): options = Options(fix=[self.fixer]) self.refactor = refactor.RefactoringTool(options) - + self.logging_stream = StringIO() sh = logging.StreamHandler(self.logging_stream) sh.setFormatter(logging.Formatter("%(message)s")) self.refactor.fixers = [Fixer(f, sh) for f in self.refactor.fixers] - + def check(self, before, after): before += "\n" after += "\n" refactored = self.refactor_stream("", StringIO(before)) self.failUnlessEqual(after, refactored) - + def warns(self, before, after, message): self.check(before, after) - - self.logging_stream.seek(0) - self.failUnless(message in '\n'.join(self.logging_stream)) + + self.failUnless(message in self.logging_stream.getvalue()) def refactor_stream(self, stream_name, stream): try: @@ -70,158 +73,158 @@ def test_1(self): b = """if x <> y: pass""" - + a = """if x != y: pass""" self.check(b, a) - + def test_2(self): b = """if x<>y: pass""" - + a = """if x!=y: pass""" self.check(b, a) - + def test_3(self): b = """if x<>y<>z: pass""" - + a = """if x!=y!=z: pass""" self.check(b, a) - + class Test_has_key(FixerTestCase): fixer = "has_key" - + def test_1(self): b = """x = d.has_key("x") or d.has_key("y")""" a = """x = "x" in d or "y" in d""" self.check(b, a) - + def test_2(self): b = """x = a.b.c.d.has_key("x") ** 3""" a = """x = ("x" in a.b.c.d) ** 3""" self.check(b, a) - + def test_3(self): b = """x = a.b.has_key(1 + 2).__repr__()""" a = """x = (1 + 2 in a.b).__repr__()""" self.check(b, a) - + def test_4(self): b = """x = a.b.has_key(1 + 2).__repr__() ** -3 ** 4""" a = """x = (1 + 2 in a.b).__repr__() ** -3 ** 4""" self.check(b, a) - + def test_5(self): b = """x = a.has_key(f or g)""" a = """x = (f or g) in a""" self.check(b, a) - + def test_6(self): b = """x = a + b.has_key(c)""" a = """x = a + (c in b)""" self.check(b, a) - + def test_7(self): b = """x = a.has_key(lambda: 12)""" a = """x = (lambda: 12) in a""" self.check(b, a) - + def test_8(self): b = """x = a.has_key(a for a in b)""" a = """x = (a for a in b) in a""" self.check(b, a) - + def test_9(self): b = """if not a.has_key(b): pass""" a = """if b not in a: pass""" self.check(b, a) - + def test_10(self): b = """if not a.has_key(b).__repr__(): pass""" a = """if not (b in a).__repr__(): pass""" self.check(b, a) - + def test_11(self): b = """if not a.has_key(b) ** 2: pass""" a = """if not (b in a) ** 2: pass""" self.check(b, a) - + class Test_apply(FixerTestCase): fixer = "apply" - + def test_1(self): b = """x = apply(f, g + h)""" a = """x = f(*g + h)""" self.check(b, a) - + def test_2(self): b = """y = apply(f, g, h)""" a = """y = f(*g, **h)""" self.check(b, a) - + def test_3(self): b = """z = apply(fs[0], g or h, h or g)""" a = """z = fs[0](*g or h, **h or g)""" self.check(b, a) - + def test_4(self): b = """apply(f, (x, y) + t)""" a = """f(*(x, y) + t)""" self.check(b, a) - + def test_5(self): b = """apply(f, args,)""" a = """f(*args)""" self.check(b, a) - + def test_6(self): b = """apply(f, args, kwds,)""" a = """f(*args, **kwds)""" self.check(b, a) - + # Test that complex functions are parenthesized - + def test_7(self): b = """x = apply(f+g, args)""" a = """x = (f+g)(*args)""" self.check(b, a) - + def test_8(self): b = """x = apply(f*g, args)""" a = """x = (f*g)(*args)""" self.check(b, a) - + def test_9(self): b = """x = apply(f**g, args)""" a = """x = (f**g)(*args)""" self.check(b, a) - + # But dotted names etc. not - + def test_10(self): b = """x = apply(f.g, args)""" a = """x = f.g(*args)""" self.check(b, a) - + def test_11(self): b = """x = apply(f[x], args)""" a = """x = f[x](*args)""" self.check(b, a) - + def test_12(self): b = """x = apply(f(), args)""" a = """x = f()(*args)""" self.check(b, a) - + # Extreme case def test_13(self): b = """x = apply(a.b.c.d.e.f, args, kwds)""" a = """x = a.b.c.d.e.f(*args, **kwds)""" self.check(b, a) - + # XXX Comments in weird places still get lost def test_14(self): b = """apply( # foo @@ -229,49 +232,49 @@ args)""" a = """f(*args)""" self.check(b, a) - + # These should *not* be touched - + def test_15(self): b = """apply()""" a = """apply()""" self.check(b, a) - + def test_16(self): b = """apply(f)""" a = """apply(f)""" self.check(b, a) - + def test_17(self): b = """apply(f,)""" a = """apply(f,)""" self.check(b, a) - + def test_18(self): b = """apply(f, args, kwds, extras)""" a = """apply(f, args, kwds, extras)""" self.check(b, a) - + def test_19(self): b = """apply(f, *args, **kwds)""" a = """apply(f, *args, **kwds)""" self.check(b, a) - + def test_20(self): b = """apply(f, *args)""" a = """apply(f, *args)""" self.check(b, a) - + def test_21(self): b = """apply(func=f, args=args, kwds=kwds)""" a = """apply(func=f, args=args, kwds=kwds)""" self.check(b, a) - + def test_22(self): b = """apply(f, args=args, kwds=kwds)""" a = """apply(f, args=args, kwds=kwds)""" self.check(b, a) - + def test_23(self): b = """apply(f, args, kwds=kwds)""" a = """apply(f, args, kwds=kwds)""" @@ -280,106 +283,106 @@ class Test_intern(FixerTestCase): fixer = "intern" - + def test_1(self): b = """x = intern(a)""" a = """x = sys.intern(a)""" self.check(b, a) - + def test_2(self): b = """y = intern("b" # test )""" a = """y = sys.intern("b" # test )""" self.check(b, a) - + def test_3(self): b = """z = intern(a+b+c.d,)""" a = """z = sys.intern(a+b+c.d,)""" self.check(b, a) - + def test_4(self): b = """intern("y%s" % 5).replace("y", "")""" a = """sys.intern("y%s" % 5).replace("y", "")""" self.check(b, a) - + # These should not be refactored - + def test_5(self): b = """intern(a=1)""" a = """intern(a=1)""" self.check(b, a) - + def test_6(self): b = """intern(f, g)""" a = """intern(f, g)""" self.check(b, a) - + def test_7(self): b = """intern(*h)""" a = """intern(*h)""" self.check(b, a) - + def test_8(self): b = """intern(**i)""" a = """intern(**i)""" self.check(b, a) - + class Test_print(FixerTestCase): fixer = "print" - + def test_1(self): b = """print 1, 1+1, 1+1+1""" a = """Print(1, 1+1, 1+1+1)""" self.check(b, a) - + def test_2(self): b = """print 1, 2""" a = """Print(1, 2)""" self.check(b, a) - + def test_3(self): b = """print""" a = """Print()""" self.check(b, a) - + # trailing commas - + def test_4(self): b = """print 1, 2, 3,""" a = """Print(1, 2, 3, end=' ')""" self.check(b, a) - + def test_5(self): b = """print 1, 2,""" a = """Print(1, 2, end=' ')""" self.check(b, a) - + def test_6(self): b = """print 1,""" a = """Print(1, end=' ')""" self.check(b, a) - + # >> stuff - + # no trailing comma def test_7(self): b = """print >>sys.stderr, 1, 2, 3""" a = """Print(1, 2, 3, file=sys.stderr)""" self.check(b, a) - + # trailing comma def test_8(self): b = """print >>sys.stderr, 1, 2,""" a = """Print(1, 2, end=' ', file=sys.stderr)""" self.check(b, a) - + # no trailing comma def test_9(self): b = """print >>sys.stderr, 1+1""" a = """Print(1+1, file=sys.stderr)""" self.check(b, a) - + # spaces before sys.stderr def test_10(self): b = """print >> sys.stderr""" @@ -389,49 +392,49 @@ class Test_exec(FixerTestCase): fixer = "exec" - + def test_1(self): b = """exec code""" a = """exec(code)""" self.check(b, a) - + def test_2(self): b = """exec code in ns""" a = """exec(code, ns)""" self.check(b, a) - + def test_3(self): b = """exec code in ns1, ns2""" a = """exec(code, ns1, ns2)""" self.check(b, a) - + def test_4(self): b = """exec (a.b()) in ns""" a = """exec((a.b()), ns)""" self.check(b, a) - + def test_5(self): b = """exec a.b() + c in ns""" a = """exec(a.b() + c, ns)""" self.check(b, a) - + # These should not be touched - + def test_6(self): b = """exec(code)""" a = """exec(code)""" self.check(b, a) - + def test_7(self): b = """exec (code)""" a = """exec (code)""" self.check(b, a) - + def test_8(self): b = """exec(code, ns)""" a = """exec(code, ns)""" self.check(b, a) - + def test_9(self): b = """exec(code, ns1, ns2)""" a = """exec(code, ns1, ns2)""" @@ -440,40 +443,40 @@ class Test_repr(FixerTestCase): fixer = "repr" - + def test_1(self): b = """x = `1 + 2`""" a = """x = repr(1 + 2)""" self.check(b, a) - + def test_2(self): b = """y = `x`""" a = """y = repr(x)""" self.check(b, a) - + def test_3(self): b = """z = `y`.__repr__()""" a = """z = repr(y).__repr__()""" self.check(b, a) - + def test_4(self): b = """x = `1, 2, 3`""" a = """x = repr((1, 2, 3))""" self.check(b, a) - + def test_5(self): b = """x = `1 + `2``""" a = """x = repr(1 + repr(2))""" self.check(b, a) - + def test_6(self): b = """x = `1, 2 + `3, 4``""" a = """x = repr((1, 2 + repr((3, 4))))""" self.check(b, a) - + class Test_except(): fixer = "except" - + def test_1(self): b = """ try: @@ -482,7 +485,7 @@ pass except ImportError, e: pass""" - + a = """ try: pass @@ -491,42 +494,42 @@ except ImportError as e: pass""" self.check(b, a) - + def test_2(self): b = """ try: pass except (RuntimeError, ImportError), e: pass""" - + a = """ try: pass except (RuntimeError, ImportError) as e: pass""" self.check(b, a) - + def test_3(self): b = """ try: pass except Exception, (a, b): pass""" - + a = """ try: pass except Exception as (a, b): pass""" self.check(b, a) - + def test_4(self): b = """ try: pass except Exception, d[5]: pass""" - + a = """ try: pass @@ -534,14 +537,14 @@ d[5] = xxx_todo_changeme pass""" self.check(b, a) - + def test_5(self): b = """ try: pass except Exception, a.foo: pass""" - + a = """ try: pass @@ -549,14 +552,14 @@ a.foo = xxx_todo_changeme1 pass""" self.check(b, a) - + def test_6(self): b = """ try: pass except Exception, a().foo: pass""" - + a = """ try: pass @@ -564,9 +567,9 @@ a().foo = xxx_todo_changeme2 pass""" self.check(b, a) - + # These should not be touched: - + def test_7(self): b = """ try: @@ -580,7 +583,7 @@ except: pass""" self.check(b, a) - + def test_8(self): b = """ try: @@ -594,7 +597,7 @@ except Exception: pass""" self.check(b, a) - + def test_9(self): b = """ try: @@ -609,94 +612,303 @@ pass""" self.check(b, a) - + class Test_raise(FixerTestCase): fixer = "raise" - + def test_1(self): b = """raise Exception, 5""" a = """raise Exception(5)""" self.check(b, a) - + def test_2(self): b = """raise Exception,5""" a = """raise Exception(5)""" self.check(b, a) - + def test_3(self): b = """raise Exception, (5, 6, 7)""" a = """raise Exception((5, 6, 7))""" self.check(b, a) - + # These should not be touched - + def test_4(self): b = """raise Exception""" a = """raise Exception""" self.check(b, a) - + def test_5(self): b = """raise Exception(5, 6)""" a = """raise Exception(5, 6)""" self.check(b, a) - - # These should produce a warning - + + # These should result in traceback-assignment + + def test_tb_1(self): + b = """def foo(): + raise Exception, 5, 6""" + a = """def foo(): + xxx_todo_changeme = Exception(5) + xxx_todo_changeme.__traceback__ = 6 + raise xxx_todo_changeme""" + self.check(b, a) + + def test_tb_2(self): + b = """def foo(): + a = 5 + raise Exception, 5, 6 + b = 6""" + a = """def foo(): + a = 5 + xxx_todo_changeme1 = Exception(5) + xxx_todo_changeme1.__traceback__ = 6 + raise xxx_todo_changeme1 + b = 6""" + self.check(b, a) + + def test_tb_3(self): + b = """def foo(): + raise Exception,5,6""" + a = """def foo(): + xxx_todo_changeme2 = Exception(5) + xxx_todo_changeme2.__traceback__ = 6 + raise xxx_todo_changeme2""" + self.check(b, a) + + def test_tb_4(self): + b = """def foo(): + a = 5 + raise Exception,5,6 + b = 6""" + a = """def foo(): + a = 5 + xxx_todo_changeme3 = Exception(5) + xxx_todo_changeme3.__traceback__ = 6 + raise xxx_todo_changeme3 + b = 6""" + self.check(b, a) + + def test_tb_5(self): + b = """def foo(): + raise Exception, (5, 6, 7), 6""" + a = """def foo(): + xxx_todo_changeme4 = Exception((5, 6, 7)) + xxx_todo_changeme4.__traceback__ = 6 + raise xxx_todo_changeme4""" + self.check(b, a) + + def test_tb_6(self): + b = """def foo(): + a = 5 + raise Exception, (5, 6, 7), 6 + b = 6""" + a = """def foo(): + a = 5 + xxx_todo_changeme5 = Exception((5, 6, 7)) + xxx_todo_changeme5.__traceback__ = 6 + raise xxx_todo_changeme5 + b = 6""" + self.check(b, a) + + +class Test_throw(FixerTestCase): + fixer = "throw" + + def test_1(self): + b = """g.throw(Exception, 5)""" + a = """g.throw(Exception(5))""" + self.check(b, a) + + def test_2(self): + b = """g.throw(Exception,5)""" + a = """g.throw(Exception(5))""" + self.check(b, a) + + def test_3(self): + b = """g.throw(Exception, (5, 6, 7))""" + a = """g.throw(Exception((5, 6, 7)))""" + self.check(b, a) + + def test_4(self): + b = """5 + g.throw(Exception, 5)""" + a = """5 + g.throw(Exception(5))""" + self.check(b, a) + + # These should not be touched + + def test_5(self): + b = """g.throw(Exception)""" + a = """g.throw(Exception)""" + self.check(b, a) + def test_6(self): - b = """raise Exception, 5, 6""" - a = """raise Exception, 5, 6""" - self.warns(b, a, "raise will not support providing a traceback") - + b = """g.throw(Exception(5, 6))""" + a = """g.throw(Exception(5, 6))""" + self.check(b, a) + def test_7(self): - b = """raise Exception,5,6""" - a = """raise Exception,5,6""" - self.warns(b, a, "raise will not support providing a traceback") - + b = """5 + g.throw(Exception(5, 6))""" + a = """5 + g.throw(Exception(5, 6))""" + self.check(b, a) + + # These should result in traceback-assignment + + def test_tb_1(self): + b = """def foo(): + g.throw(Exception, 5, 6)""" + a = """def foo(): + xxx_todo_changeme6 = Exception(5) + xxx_todo_changeme6.__traceback__ = 6 + g.throw(xxx_todo_changeme6)""" + self.check(b, a) + + def test_tb_2(self): + b = """def foo(): + a = 5 + g.throw(Exception, 5, 6) + b = 6""" + a = """def foo(): + a = 5 + xxx_todo_changeme7 = Exception(5) + xxx_todo_changeme7.__traceback__ = 6 + g.throw(xxx_todo_changeme7) + b = 6""" + self.check(b, a) + + def test_tb_3(self): + b = """def foo(): + g.throw(Exception,5,6)""" + a = """def foo(): + xxx_todo_changeme8 = Exception(5) + xxx_todo_changeme8.__traceback__ = 6 + g.throw(xxx_todo_changeme8)""" + self.check(b, a) + + def test_tb_4(self): + b = """def foo(): + a = 5 + g.throw(Exception,5,6) + b = 6""" + a = """def foo(): + a = 5 + xxx_todo_changeme9 = Exception(5) + xxx_todo_changeme9.__traceback__ = 6 + g.throw(xxx_todo_changeme9) + b = 6""" + self.check(b, a) + + def test_tb_5(self): + b = """def foo(): + g.throw(Exception, (5, 6, 7), 6)""" + a = """def foo(): + xxx_todo_changeme10 = Exception((5, 6, 7)) + xxx_todo_changeme10.__traceback__ = 6 + g.throw(xxx_todo_changeme10)""" + self.check(b, a) + + def test_tb_6(self): + b = """def foo(): + a = 5 + g.throw(Exception, (5, 6, 7), 6) + b = 6""" + a = """def foo(): + a = 5 + xxx_todo_changeme11 = Exception((5, 6, 7)) + xxx_todo_changeme11.__traceback__ = 6 + g.throw(xxx_todo_changeme11) + b = 6""" + self.check(b, a) + + def test_tb_7(self): + b = """def foo(): + a + g.throw(Exception, 5, 6)""" + a = """def foo(): + xxx_todo_changeme12 = Exception(5) + xxx_todo_changeme12.__traceback__ = 6 + a + g.throw(xxx_todo_changeme12)""" + self.check(b, a) + + def test_tb_8(self): + b = """def foo(): + a = 5 + a + g.throw(Exception, 5, 6) + b = 6""" + a = """def foo(): + a = 5 + xxx_todo_changeme13 = Exception(5) + xxx_todo_changeme13.__traceback__ = 6 + a + g.throw(xxx_todo_changeme13) + b = 6""" + self.check(b, a) + + class Test_long(FixerTestCase): fixer = "long" - + def test_1(self): b = """x = long(x)""" a = """x = int(x)""" self.check(b, a) - + def test_2(self): b = """y = isinstance(x, long)""" a = """y = isinstance(x, int)""" self.check(b, a) - + def test_3(self): b = """z = type(x) in (int, long)""" a = """z = type(x) in (int, int)""" self.check(b, a) - + def test_4(self): b = """a = 12L""" a = """a = 12""" self.check(b, a) - + def test_5(self): b = """b = 0x12l""" a = """b = 0x12""" self.check(b, a) - + # These should not be touched - + def test_6(self): b = """a = 12""" a = """a = 12""" self.check(b, a) - + def test_7(self): b = """b = 0x12""" a = """b = 0x12""" self.check(b, a) - + def test_8(self): b = """c = 3.14""" a = """c = 3.14""" self.check(b, a) - + + +class Test_sysexcinfo(FixerTestCase): + fixer = "sysexcinfo" + + def test_1(self): + s = """sys.exc_info()""" + self.warns(s, s, "This function is going away") + + def test_2(self): + s = """if sys.exc_info()[1] == 1: + pass""" + + self.warns(s, s, "This function is going away") + + def test_3(self): + s = """f = sys.exc_info""" + self.warns(s, s, "This function is going away") + + def test_4(self): + s = """f = sys.exc_type + ":" + sys.exc_value""" + self.warns(s, s, "This attribute is going away") if __name__ == "__main__": import sys Modified: sandbox/trunk/2to3/fixes/basefix.py ============================================================================== --- sandbox/trunk/2to3/fixes/basefix.py (original) +++ sandbox/trunk/2to3/fixes/basefix.py Thu Feb 8 23:42:35 2007 @@ -86,6 +86,10 @@ return pygram.parenthesize(node) def new_name(self, template="xxx_todo_changeme"): + """Return a string suitable for use as an identifier + + The new name is guaranteed not to conflict with other identifiers. + """ name = template while name in self.used_names: name = template + str(numbers.next()) @@ -93,6 +97,12 @@ return name def cannot_convert(self, node, reason=None): + """Warn the user that a given chunk of code is not valid Python 3, + but that it cannot be converted automatically. + + First argument is the top-level node for the code in question. + Optional second argument is why it can't be converted. + """ lineno = node.get_lineno() for_output = node.clone() for_output.set_prefix("") Modified: sandbox/trunk/2to3/fixes/fix_apply.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_apply.py (original) +++ sandbox/trunk/2to3/fixes/fix_apply.py Thu Feb 8 23:42:35 2007 @@ -9,7 +9,7 @@ # Local imports import pytree from fixes import basefix - +from fixes.macros import Call, Comma class FixApply(basefix.BaseFix): @@ -49,17 +49,13 @@ kwds.set_prefix("") l_newargs = [pytree.Leaf(token.STAR, "*"), args] if kwds is not None: - l_newargs.extend([pytree.Leaf(token.COMMA, ","), + l_newargs.extend([Comma(), pytree.Leaf(token.DOUBLESTAR, "**"), kwds]) l_newargs[-2].set_prefix(" ") # that's the ** token # XXX Sometimes we could be cleverer, e.g. apply(f, (x, y) + t) # can be translated into f(x, y, *t) instead of f(*(x, y) + t) - new = pytree.Node(syms.power, - (func, - pytree.Node(syms.trailer, - (pytree.Leaf(token.LPAR, "("), - pytree.Node(syms.arglist, l_newargs), - pytree.Leaf(token.RPAR, ")"))))) + #new = pytree.Node(syms.power, (func, ArgList(l_newargs))) + new = Call(func, l_newargs) new.set_prefix(prefix) return new Modified: sandbox/trunk/2to3/fixes/fix_except.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_except.py (original) +++ sandbox/trunk/2to3/fixes/fix_except.py Thu Feb 8 23:42:35 2007 @@ -7,6 +7,7 @@ # Local imports import pytree from fixes import basefix +from fixes.macros import Assign, Attr, Name def find_excepts(nodes): for i in range(len(nodes)): @@ -19,9 +20,6 @@ as_leaf = pytree.Leaf(token.NAME, "as") as_leaf.set_prefix(" ") -ass_leaf = pytree.Leaf(token.EQUAL, "=") -ass_leaf.set_prefix(" ") - tuple_reason = "exception unpacking is going away" class FixExcept(basefix.BaseFix): @@ -32,42 +30,44 @@ ['finally' ':' suite] | 'finally' ':' suite) > """ - + def transform(self, node): syms = self.syms results = self.match(node) assert results - + try_cleanup = [ch.clone() for ch in results['cleanup']] for except_clause, e_suite in find_excepts(try_cleanup): if len(except_clause.children) == 4: (E, comma, N) = except_clause.children[1:4] comma.replace(as_leaf.clone()) - if str(N).strip()[0] == '(': - # We're dealing with a tuple - self.cannot_convert(N, tuple_reason) - elif N.type != token.NAME: + if N.type != token.NAME: # Generate a new N for the except clause - new_N = pytree.Leaf(token.NAME, self.new_name()) + new_N = Name(self.new_name()) new_N.set_prefix(" ") target = N.clone() target.set_prefix("") N.replace(new_N) - + new_N = new_N.clone() + # Insert "old_N = new_N" as the first statement in - # the except body + # the except body. This loop skips leading whitespace + # and indents suite_stmts = list(e_suite.children) for i, stmt in enumerate(suite_stmts): if isinstance(stmt, pytree.Node): break - assign = pytree.Node(syms.atom, - [target, - ass_leaf.clone(), - new_N.clone()]) - - assign.parent = e_suite + + # The assignment is different if old_N is a tuple + # In that case, the assignment is old_N = new_N.message + if str(N).strip()[0] == '(': + assign = Assign(target, Attr(new_N, Name('message'))) + else: + assign = Assign(target, new_N) + + assign.parent = e_suite suite_stmts = suite_stmts[:i] + [assign] + suite_stmts e_suite.children = tuple(suite_stmts) - + children = [c.clone() for c in node.children[:3]] + try_cleanup return pytree.Node(node.type, children) Modified: sandbox/trunk/2to3/fixes/fix_exec.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_exec.py (original) +++ sandbox/trunk/2to3/fixes/fix_exec.py Thu Feb 8 23:42:35 2007 @@ -9,6 +9,7 @@ # Local imports import pytree from fixes import basefix +from fixes.macros import Comma, Name, Call class FixExec(basefix.BaseFix): @@ -29,14 +30,10 @@ args = [a.clone()] args[0].set_prefix("") if b is not None: - args.extend([pytree.Leaf(token.COMMA, ","), b.clone()]) + args.extend([Comma(), b.clone()]) if c is not None: - args.extend([pytree.Leaf(token.COMMA, ","), c.clone()]) - new = pytree.Node(syms.factor, - [pytree.Leaf(token.NAME, "exec"), - pytree.Node(syms.trailer, - [pytree.Leaf(token.LPAR, "("), - pytree.Node(syms.arglist, args), - pytree.Leaf(token.RPAR, ")")])]) + args.extend([Comma(), c.clone()]) + + new = Call(Name("exec"), args) new.set_prefix(node.get_prefix()) return new Modified: sandbox/trunk/2to3/fixes/fix_has_key.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_has_key.py (original) +++ sandbox/trunk/2to3/fixes/fix_has_key.py Thu Feb 8 23:42:35 2007 @@ -9,6 +9,7 @@ # Local imports import pytree from fixes import basefix +from fixes.macros import Name class FixHasKey(basefix.BaseFix): @@ -68,10 +69,10 @@ else: before = pytree.Node(syms.power, before) before.set_prefix(" ") - n_op = pytree.Leaf(token.NAME, "in") + n_op = Name("in") n_op.set_prefix(" ") if negation: - n_not = pytree.Leaf(token.NAME, "not") + n_not = Name("not") n_not.set_prefix(" ") n_op = pytree.Node(syms.comp_op, (n_not, n_op)) new = pytree.Node(syms.comparison, (arg, n_op, before)) Modified: sandbox/trunk/2to3/fixes/fix_intern.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_intern.py (original) +++ sandbox/trunk/2to3/fixes/fix_intern.py Thu Feb 8 23:42:35 2007 @@ -9,6 +9,7 @@ # Local imports import pytree from fixes import basefix +from fixes.macros import Name, Attr class FixIntern(basefix.BaseFix): @@ -36,14 +37,11 @@ if after: after = tuple(n.clone() for n in after) new = pytree.Node(syms.power, - (pytree.Leaf(token.NAME, "sys"), - pytree.Node(syms.trailer, - [pytree.Leaf(token.DOT, "."), - pytree.Leaf(token.NAME, "intern")]), - pytree.Node(syms.trailer, + Attr(Name("sys"), Name("intern")) + + (pytree.Node(syms.trailer, [results["lpar"].clone(), newarglist, - results["rpar"].clone()])) + results["rpar"].clone()]),) + after) new.set_prefix(node.get_prefix()) return new Modified: sandbox/trunk/2to3/fixes/fix_long.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_long.py (original) +++ sandbox/trunk/2to3/fixes/fix_long.py Thu Feb 8 23:42:35 2007 @@ -12,6 +12,7 @@ # Local imports import pytree from fixes import basefix +from fixes.macros import Name class FixLong(basefix.BaseFix): @@ -20,8 +21,8 @@ (long_type = 'long' | number = NUMBER) """ - static_long = pytree.Leaf(token.NAME, "long") - static_int = pytree.Leaf(token.NAME, "int") + static_long = Name("long") + static_int = Name("int") def transform(self, node): results = self.match(node) Modified: sandbox/trunk/2to3/fixes/fix_print.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_print.py (original) +++ sandbox/trunk/2to3/fixes/fix_print.py Thu Feb 8 23:42:35 2007 @@ -16,6 +16,7 @@ # Local imports import pytree from fixes import basefix +from fixes.macros import Name, Call, Comma class FixPrint(basefix.BaseFix): @@ -36,19 +37,15 @@ results = self.match(node) assert results - if node == pytree.Leaf(token.NAME, "print"): + if node == Name("print"): # Special-case print all by itself - new = pytree.Node(syms.power, - (pytree.Leaf(token.NAME, "Print"), - pytree.Node(syms.trailer, - (pytree.Leaf(token.LPAR, "("), - pytree.Leaf(token.RPAR, ")"))))) + new = Call(Name("Print"), []) new.set_prefix(node.get_prefix()) return new - assert node.children[0] == pytree.Leaf(token.NAME, "print") + assert node.children[0] == Name("print") args = node.children[1:] sep = end = file = None - if args and args[-1] == pytree.Leaf(token.COMMA, ","): + if args and args[-1] == Comma(): args = args[:-1] end = " " if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, ">>"): @@ -56,7 +53,6 @@ file = args[1].clone() args = args[3:] # Strip a possible comma after the file expression # Now synthesize a Print(args, sep=..., end=..., file=...) node. - n_print = pytree.Leaf(token.NAME, "Print") # XXX -> "print" l_args = [arg.clone() for arg in args] if l_args: l_args[0].set_prefix("") @@ -69,15 +65,7 @@ pytree.Leaf(token.STRING, repr(end))) if file is not None: self.add_kwarg(l_args, "file", file) - if l_args: - n_arglist = pytree.Node(syms.arglist, l_args) - else: - n_arglist = None - l_args = [pytree.Leaf(token.LPAR, "("), pytree.Leaf(token.RPAR, ")")] - if n_arglist: - l_args.insert(1, n_arglist) - n_trailer = pytree.Node(syms.trailer, l_args) - n_stmt = pytree.Node(syms.power, (n_print, n_trailer)) + n_stmt = Call(Name("Print"), l_args) n_stmt.set_prefix(node.get_prefix()) return n_stmt @@ -85,10 +73,10 @@ # XXX All this prefix-setting may lose comments (though rarely) n_expr.set_prefix("") n_argument = pytree.Node(self.syms.argument, - (pytree.Leaf(token.NAME, s_kwd), + (Name(s_kwd), pytree.Leaf(token.EQUAL, "="), n_expr)) if l_nodes: - l_nodes.append(pytree.Leaf(token.COMMA, ",")) + l_nodes.append(Comma()) n_argument.set_prefix(" ") l_nodes.append(n_argument) Modified: sandbox/trunk/2to3/fixes/fix_raise.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_raise.py (original) +++ sandbox/trunk/2to3/fixes/fix_raise.py Thu Feb 8 23:42:35 2007 @@ -1,4 +1,4 @@ -"""Fixer for 'raise E, a1, a2, ...'""" +"""Fixer for 'raise E, V, T'""" # Author: Collin Winter # Python imports @@ -7,35 +7,57 @@ # Local imports import pytree from fixes import basefix - -reason = "Python 3's raise will not support providing a traceback" +from fixes.macros import Name, Call, Assign, Newline, Attr class FixRaise(basefix.BaseFix): PATTERN = """ - raise_stmt< 'raise' exc=any ',' a1=any [',' a2=any] > + raise_stmt< 'raise' exc=any ',' val=any [',' tb=any] > """ def transform(self, node): syms = self.syms results = self.match(node) assert results - + exc = results["exc"].clone() - args = [results["a1"].clone()] + args = [results["val"].clone()] args[0].set_prefix("") - - arg2 = results.get("a2") - if arg2 is not None: - self.cannot_convert(node, reason) - return node - - new = pytree.Node(syms.raise_stmt, - [pytree.Leaf(token.NAME, "raise"), - exc, - pytree.Node(syms.trailer, - [pytree.Leaf(token.LPAR, "("), - pytree.Node(syms.arglist, args), - pytree.Leaf(token.RPAR, ")")])]) - new.set_prefix(node.get_prefix()) - return new + + if "tb" in results: + tb = results["tb"].clone() + name = Name(self.new_name()) + children = list(node.parent.parent.children) + i = children.index(node.parent) + indent = children[1].value + + # Instance the exception + build_e = pytree.Node(syms.simple_stmt, + [Assign(name.clone(), Call(exc, args)), + Newline()]) + build_e.parent = node.parent.parent + if node.get_prefix(): + # Over-indents otherwise + build_e.set_prefix(indent) + + # Assign the traceback + set_tb = pytree.Node(syms.simple_stmt, + [Assign(Attr(name.clone(), + Name("__traceback__")), tb), + Newline()]) + set_tb.set_prefix(indent) + set_tb.parent = node.parent.parent + + # Insert into the suite + children[i:i] = [build_e, set_tb] + node.parent.parent.children = tuple(children) + + name.set_prefix(" ") + new = pytree.Node(syms.simple_stmt, [Name("raise"), name]) + new.set_prefix(indent) + return new + else: + new = pytree.Node(syms.raise_stmt, + [Name("raise"), Call(exc, args)]) + new.set_prefix(node.get_prefix()) + return new Modified: sandbox/trunk/2to3/fixes/fix_repr.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_repr.py (original) +++ sandbox/trunk/2to3/fixes/fix_repr.py Thu Feb 8 23:42:35 2007 @@ -9,6 +9,7 @@ # Local imports import pytree from fixes import basefix +from fixes.macros import Call, Name class FixRepr(basefix.BaseFix): @@ -23,11 +24,6 @@ expr = results["expr"].clone() if expr.type == self.syms.testlist1: expr = self.parenthesize(expr) - new = pytree.Node(self.syms.power, - (pytree.Leaf(token.NAME, "repr"), - pytree.Node(self.syms.trailer, - (pytree.Leaf(token.LPAR, "("), - expr, - pytree.Leaf(token.RPAR, ")"))))) + new = Call(Name("repr"), [expr]) new.set_prefix(node.get_prefix()) return new Added: sandbox/trunk/2to3/fixes/fix_sysexcinfo.py ============================================================================== --- (empty file) +++ sandbox/trunk/2to3/fixes/fix_sysexcinfo.py Thu Feb 8 23:42:35 2007 @@ -0,0 +1,32 @@ +"""Fixer/warner for sys.exc_{info,value,type,traceback}""" +# Author: Collin Winter + +# Python imports +import token + +# Local imports +from pytree import Leaf +from fixes import basefix + + +class FixSysexcinfo(basefix.BaseFix): + + PATTERN = """ + power< 'sys' trailer< '.' attr='exc_info'> any* > + | + power< 'sys' + trailer< '.' attr=('exc_value' | 'exc_traceback' | 'exc_type')> + any* > + """ + + def transform(self, node): + results = self.match(node) + assert results + attr = results['attr'] + + if isinstance(attr, Leaf) and attr.value == 'exc_info': + self.cannot_convert(node, + "This function is going away in Python 3") + else: + self.cannot_convert(node, + "This attribute is going away in Python 3") Added: sandbox/trunk/2to3/fixes/fix_throw.py ============================================================================== --- (empty file) +++ sandbox/trunk/2to3/fixes/fix_throw.py Thu Feb 8 23:42:35 2007 @@ -0,0 +1,80 @@ +"""Fixer for generator.throw(E, V, T)""" +# Author: Collin Winter + +# Python imports +import token + +# Local imports +import pytree +from fixes import basefix +from fixes.macros import Name, Call, Assign, Newline, Attr + +class FixThrow(basefix.BaseFix): + + PATTERN = """ + power< any trailer< '.' 'throw' > + trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' > + > + """ + + def transform(self, node): + syms = self.syms + results = self.match(node) + assert results + + throw_args = results["args"] + exc = results["exc"].clone() + args = [results["val"].clone()] + args[0].set_prefix("") + + if "tb" in results: + tb = results["tb"].clone() + name = Name(self.new_name()) + suite = find_parent_suite(node) + stmts = list(suite.children) + node_stmt = find_stmt(stmts, node) + i = stmts.index(node_stmt) + indent = stmts[1].value + + # Instance the exception + build_e = pytree.Node(syms.simple_stmt, + [Assign(name.clone(), Call(exc, args)), + Newline()]) + build_e.parent = node.parent.parent + if node_stmt.get_prefix(): + # Over-indents otherwise + build_e.set_prefix(indent) + + # Assign the traceback + tb.set_prefix(" ") + set_tb = pytree.Node(syms.simple_stmt, + [Assign(Attr(name.clone(), + Name("__traceback__")), tb), + Newline()]) + set_tb.set_prefix(indent) + set_tb.parent = node.parent.parent + + # Insert into the suite + stmts[i:i] = [build_e, set_tb] + suite.children = tuple(stmts) + + throw_args.replace(name) + if not node_stmt.get_prefix(): + node_stmt.set_prefix(indent) + # No return + else: + throw_args.replace(Call(exc, args)) + # No return + + +def find_parent_suite(node): + parent = node.parent + while parent: + if len(parent.children) > 2 and parent.children[0].value == "\n": + return parent + parent = parent.parent + +def find_stmt(stmts, node): + while node not in stmts: + node = node.parent + return node Added: sandbox/trunk/2to3/fixes/macros.py ============================================================================== --- (empty file) +++ sandbox/trunk/2to3/fixes/macros.py Thu Feb 8 23:42:35 2007 @@ -0,0 +1,57 @@ +"""Abstract away often-used node construction routines.""" +# Author: Collin Winter + +# Python imports +import token + +# Local imports +from pytree import Leaf, Node +from pygram import python_symbols as syms + + +### Constant nodes +ass_leaf = Leaf(token.EQUAL, "=") +ass_leaf.set_prefix(" ") + +comma_leaf = Leaf(token.COMMA, ",") +lparen_leaf = Leaf(token.LPAR, "(") +rparen_leaf = Leaf(token.RPAR, ")") + +def Assign(target, source): + """Build an assignment statement""" + if not isinstance(target, tuple): + target = (target,) + if not isinstance(source, tuple): + source.set_prefix(" ") + source = (source,) + + return Node(syms.atom, target + (ass_leaf.clone(),) + source) + +def Name(name): + """Return a NAME leaf""" + return Leaf(token.NAME, name) + +def Attr(obj, attr): + """A node tuple for obj.attr""" + return (obj, + Node(syms.trailer, [Leaf(token.DOT, '.'), + attr])) + +def Comma(): + """A comma leaf""" + return comma_leaf.clone() + +def ArgList(args, lparen=lparen_leaf, rparen=rparen_leaf): + """A parenthesised argument list, used by Call()""" + return Node(syms.trailer, + [lparen.clone(), + Node(syms.arglist, args), + rparen.clone()]) + +def Call(func_name, args): + """A function call""" + return Node(syms.power, [func_name, ArgList(args)]) + +def Newline(): + """A newline literal""" + return Leaf(token.NEWLINE, "\n") Modified: sandbox/trunk/2to3/pytree.py ============================================================================== --- sandbox/trunk/2to3/pytree.py (original) +++ sandbox/trunk/2to3/pytree.py Thu Feb 8 23:42:35 2007 @@ -115,8 +115,9 @@ if new is not None: new.parent = self.parent self.parent = None - + def get_lineno(self): + """Returns the line number which generated the invocant node.""" node = self while not isinstance(node, Leaf): if not node.children: Modified: sandbox/trunk/2to3/refactor.py ============================================================================== --- sandbox/trunk/2to3/refactor.py (original) +++ sandbox/trunk/2to3/refactor.py Thu Feb 8 23:42:35 2007 @@ -24,6 +24,7 @@ import patcomp from pgen2 import driver import fixes +import fixes.macros import pygram logging.basicConfig(format='%(name)s: %(message)s', level=logging.INFO) From python-checkins at python.org Thu Feb 8 23:46:51 2007 From: python-checkins at python.org (guido.van.rossum) Date: Thu, 8 Feb 2007 23:46:51 +0100 (CET) Subject: [Python-checkins] r53678 - sandbox/trunk/2to3/fixes/fix_throw.py Message-ID: <20070208224651.2317F1E4008@bag.python.org> Author: guido.van.rossum Date: Thu Feb 8 23:46:50 2007 New Revision: 53678 Modified: sandbox/trunk/2to3/fixes/fix_throw.py Log: Fix unit test failure caused by improper indentation in PATTERN (introduced by my folding a long line). Modified: sandbox/trunk/2to3/fixes/fix_throw.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_throw.py (original) +++ sandbox/trunk/2to3/fixes/fix_throw.py Thu Feb 8 23:46:50 2007 @@ -14,7 +14,7 @@ PATTERN = """ power< any trailer< '.' 'throw' > trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' > - > + > """ def transform(self, node): From python-checkins at python.org Thu Feb 8 23:58:19 2007 From: python-checkins at python.org (kurt.kaiser) Date: Thu, 8 Feb 2007 23:58:19 +0100 (CET) Subject: [Python-checkins] r53679 - python/trunk/Lib/idlelib/AutoCompleteWindow.py python/trunk/Lib/idlelib/NEWS.txt python/trunk/Lib/idlelib/help.txt Message-ID: <20070208225819.546331E4009@bag.python.org> Author: kurt.kaiser Date: Thu Feb 8 23:58:18 2007 New Revision: 53679 Modified: python/trunk/Lib/idlelib/AutoCompleteWindow.py python/trunk/Lib/idlelib/NEWS.txt python/trunk/Lib/idlelib/help.txt Log: Corrected some bugs in AutoComplete. Also, Page Up/Down in ACW implemented; mouse and cursor selection in ACWindow implemented; double Tab inserts current selection and closes ACW (similar to double-click and Return); scroll wheel now works in ACW. Added AutoComplete instructions to IDLE Help. Modified: python/trunk/Lib/idlelib/AutoCompleteWindow.py ============================================================================== --- python/trunk/Lib/idlelib/AutoCompleteWindow.py (original) +++ python/trunk/Lib/idlelib/AutoCompleteWindow.py Thu Feb 8 23:58:18 2007 @@ -10,13 +10,14 @@ KEYPRESS_VIRTUAL_EVENT_NAME = "<>" # We need to bind event beyond so that the function will be called # before the default specific IDLE function -KEYPRESS_SEQUENCES = ("", "", "", - "", "", "", "") +KEYPRESS_SEQUENCES = ("", "", "", "", + "", "", "", "", + "", "") KEYRELEASE_VIRTUAL_EVENT_NAME = "<>" KEYRELEASE_SEQUENCE = "" -LISTUPDATE_SEQUENCE = "" +LISTUPDATE_SEQUENCE = "" WINCONFIG_SEQUENCE = "" -DOUBLECLICK_SEQUENCE = "" +DOUBLECLICK_SEQUENCE = "" class AutoCompleteWindow: @@ -49,6 +50,8 @@ # event ids self.hideid = self.keypressid = self.listupdateid = self.winconfigid \ = self.keyreleaseid = self.doubleclickid = None + # Flag set if last keypress was a tab + self.lastkey_was_tab = False def _change_start(self, newstart): i = 0 @@ -118,11 +121,6 @@ i = 0 while i < len(lts) and i < len(selstart) and lts[i] == selstart[i]: i += 1 - previous_completion = self.completions[cursel - 1] - while cursel > 0 and selstart[:i] <= previous_completion: - i += 1 - if selstart == previous_completion: - break # maybe we have a duplicate? newstart = selstart[:i] self._change_start(newstart) @@ -206,7 +204,7 @@ self.keyrelease_event) self.widget.event_add(KEYRELEASE_VIRTUAL_EVENT_NAME,KEYRELEASE_SEQUENCE) self.listupdateid = listbox.bind(LISTUPDATE_SEQUENCE, - self.listupdate_event) + self.listselect_event) self.winconfigid = acw.bind(WINCONFIG_SEQUENCE, self.winconfig_event) self.doubleclickid = listbox.bind(DOUBLECLICK_SEQUENCE, self.doubleclick_event) @@ -237,11 +235,12 @@ return self.hide_window() - def listupdate_event(self, event): + def listselect_event(self, event): if not self.is_active(): return self.userwantswindow = True - self._selection_changed() + cursel = int(self.listbox.curselection()[0]) + self._change_start(self.completions[cursel]) def doubleclick_event(self, event): # Put the selected completion in the text, and close the list @@ -257,7 +256,8 @@ state = event.mc_state else: state = 0 - + if keysym != "Tab": + self.lastkey_was_tab = False if (len(keysym) == 1 or keysym in ("underscore", "BackSpace") or (self.mode==AutoComplete.COMPLETE_FILES and keysym in ("period", "minus"))) \ @@ -339,13 +339,21 @@ self.listbox.select_clear(cursel) self.listbox.select_set(newsel) self._selection_changed() + self._change_start(self.completions[newsel]) return "break" elif (keysym == "Tab" and not state): - # The user wants a completion, but it is handled by AutoComplete - # (not AutoCompleteWindow), so ignore. - self.userwantswindow = True - return + if self.lastkey_was_tab: + # two tabs in a row; insert current selection and close acw + cursel = int(self.listbox.curselection()[0]) + self._change_start(self.completions[cursel]) + self.hide_window() + return "break" + else: + # first tab; let AutoComplete handle the completion + self.userwantswindow = True + self.lastkey_was_tab = True + return elif reduce(lambda x, y: x or y, [keysym.find(s) != -1 for s in ("Shift", "Control", "Alt", Modified: python/trunk/Lib/idlelib/NEWS.txt ============================================================================== --- python/trunk/Lib/idlelib/NEWS.txt (original) +++ python/trunk/Lib/idlelib/NEWS.txt Thu Feb 8 23:58:18 2007 @@ -3,6 +3,11 @@ *Release date: XX-XXX-200X* +- Corrected some bugs in AutoComplete. Also, Page Up/Down in ACW implemented; + mouse and cursor selection in ACWindow implemented; double Tab inserts + current selection and closes ACW (similar to double-click and Return); scroll + wheel now works in ACW. Added AutoComplete instructions to IDLE Help. + - AutoCompleteWindow moved below input line, will move above if there isn't enough space. Patch 1621265 Tal Einat Modified: python/trunk/Lib/idlelib/help.txt ============================================================================== --- python/trunk/Lib/idlelib/help.txt (original) +++ python/trunk/Lib/idlelib/help.txt Thu Feb 8 23:58:18 2007 @@ -44,6 +44,10 @@ Find in Files... -- Open a search dialog box for searching files Replace... -- Open a search-and-replace dialog box Go to Line -- Ask for a line number and show that line + Show Calltip -- Open a small window with function param hints + Show Completions -- Open a scroll window allowing selection keywords + and attributes. (see '*TIPS*', below) + Show Parens -- Highlight the surrounding parenthesis Expand Word -- Expand the word you have typed to match another word in the same buffer; repeat to get a different expansion @@ -91,6 +95,7 @@ Code Context -- Open a pane at the top of the edit window which shows the block context of the section of code which is scrolling off the top or the window. + (Not present in Shell window.) Windows Menu: @@ -138,8 +143,11 @@ Control-left/right Arrow moves by words in a strange but useful way. Home/End go to begin/end of line. Control-Home/End go to begin/end of file. - Some useful Emacs bindings (Control-a, Control-e, Control-k, etc.) - are inherited from Tcl/Tk. + Some useful Emacs bindings are inherited from Tcl/Tk: + Control-a beginning of line + Control-e end of line + Control-k kill line (but doesn't put it in clipboard) + Control-l center window around the insertion point Standard Windows bindings may work on that platform. Keybindings are selected in the Settings Dialog, look there. @@ -155,6 +163,52 @@ See also the indent/dedent region commands in the edit menu. +Completions: + + Completions are supplied for functions, classes, and attributes of + classes, both built-in and user-defined. Completions are also provided + for filenames. + + The AutoCompleteWindow (ACW) will open after a predefined delay + (default is two seconds) after a '.' or (in a string) an os.sep is + typed. If after one of those characters (plus zero or more other + characters) you type a Tab the ACW will open immediately if a possible + continuation is found. + + If there is only one possible completion for the characters entered, a + Tab will supply that completion without opening the ACW. + + 'Show Completions' will force open a completions window. In an empty + string, this will contain the files in the current directory. On a + blank line, it will contain the built-in and user-defined functions and + classes in the current name spaces, plus any modules imported. If some + characters have been entered, the ACW will attempt to be more specific. + + If string of characters is typed, the ACW selection will jump to the + entry most closely matching those characters. Entering a Tab will cause + the longest non-ambiguous match to be entered in the Edit window or + Shell. Two Tabs in a row will supply the current ACW selection, as + will Return or a double click. Cursor keys, Page Up/Down, mouse + selection, and the scrollwheel all operate on the ACW. + + 'Hidden' attributes can be accessed by typing the beginning of hidden + name after a '.'. e.g. '_'. This allows access to modules with + '__all__' set, or to class-private attributes. + + Completions and the 'Expand Word' facility can save a lot of typing! + + Completions are currently limited to those in the namespaces. Names in + an Edit window which are not via __main__ or sys.modules will not be + found. Run the module once with your imports to correct this + situation. Note that IDLE itself places quite a few modules in + sys.modules, so much can be found by default, e.g. the re module. + + If you don't like the ACW popping up unbidden, simply make the delay + longer or disable the extension. OTOH, you could make the delay zero. + + You could also switch off the CallTips extension. (We will be adding + a delay to the call tip window.) + Python Shell window: Control-c interrupts executing command. @@ -165,7 +219,7 @@ Alt-p retrieves previous command matching what you have typed. Alt-n retrieves next. - (These are Control-p, Control-n on the Mac) + (These are Control-p, Control-n on the Mac) Return while cursor is on a previous command retrieves that command. Expand word is also useful to reduce typing. @@ -196,7 +250,7 @@ be changed using the Settings dialog. Command line usage: - + Enter idle -h at the command prompt to get a usage message. Running without a subprocess: @@ -211,3 +265,18 @@ re-import any specific items (e.g. from foo import baz) if the changes are to take effect. For these reasons, it is preferable to run IDLE with the default subprocess if at all possible. + +Extensions: + + IDLE contains an extension facility. See the beginning of + config-extensions.def in the idlelib directory for further information. + The default extensions are currently: + + FormatParagraph + AutoExpand + ZoomHeight + ScriptBinding + CallTips + ParenMatch + AutoComplete + CodeContext From buildbot at python.org Fri Feb 9 00:22:28 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 08 Feb 2007 23:22:28 +0000 Subject: [Python-checkins] buildbot warnings in amd64 gentoo trunk Message-ID: <20070208232228.E3BA71E4009@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%2520gentoo%2520trunk/builds/1824 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: kurt.kaiser Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_timeout make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Fri Feb 9 00:54:16 2007 From: python-checkins at python.org (guido.van.rossum) Date: Fri, 9 Feb 2007 00:54:16 +0100 (CET) Subject: [Python-checkins] r53680 - sandbox/trunk/2to3/fixer_tests.py Message-ID: <20070208235416.5CF951E4009@bag.python.org> Author: guido.van.rossum Date: Fri Feb 9 00:54:15 2007 New Revision: 53680 Modified: sandbox/trunk/2to3/fixer_tests.py (contents, props changed) Log: Make fixer_tests.py executable, adding a #! line. Modified: sandbox/trunk/2to3/fixer_tests.py ============================================================================== --- sandbox/trunk/2to3/fixer_tests.py (original) +++ sandbox/trunk/2to3/fixer_tests.py Fri Feb 9 00:54:15 2007 @@ -1,3 +1,4 @@ +#!/usr/bin/env python2.5 """ Test suite for the fixer modules """ # Author: Collin Winter From buildbot at python.org Fri Feb 9 01:20:07 2007 From: buildbot at python.org (buildbot at python.org) Date: Fri, 09 Feb 2007 00:20:07 +0000 Subject: [Python-checkins] buildbot warnings in hppa Ubuntu dapper trunk Message-ID: <20070209002008.0C2CB1E4021@bag.python.org> The Buildbot has detected a new failure of hppa Ubuntu dapper trunk. Full details are available at: http://www.python.org/dev/buildbot/all/hppa%2520Ubuntu%2520dapper%2520trunk/builds/68 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: kurt.kaiser Build had warnings: warnings test Excerpt from the test logfile: make: *** [buildbottest] Killed sincerely, -The Buildbot From python-checkins at python.org Fri Feb 9 02:27:50 2007 From: python-checkins at python.org (guido.van.rossum) Date: Fri, 9 Feb 2007 02:27:50 +0100 (CET) Subject: [Python-checkins] r53681 - in sandbox/trunk/2to3: example.py fixes/fix_dict.py Message-ID: <20070209012750.2F6C11E4009@bag.python.org> Author: guido.van.rossum Date: Fri Feb 9 02:27:49 2007 New Revision: 53681 Added: sandbox/trunk/2to3/fixes/fix_dict.py (contents, props changed) Modified: sandbox/trunk/2to3/example.py Log: Work checkpoint: convert d.keys(), d.iterkeys() etc. Modified: sandbox/trunk/2to3/example.py ============================================================================== --- sandbox/trunk/2to3/example.py (original) +++ sandbox/trunk/2to3/example.py Fri Feb 9 02:27:49 2007 @@ -243,5 +243,36 @@ b = 0x12 c = 3.14 +def dict_examples(): + # + # Plain method calls + # + print d.keys() + print d.items() + print d.values() + # + # Plain method calls in special contexts + # + print list(e.keys()) + print sorted(e.keys()) + print iter(e.keys()) + for i in e.keys(): print i + # + # Iterator method calls + # + print d.iterkeys() + print d.iteritems() + print d.itervalues() + # + # Iterator method calls in special contexts + # + print list(e.iterkeys()) + print sorted(e.iterkeys()) + print iter(e.iterkeys()) + for i in e.iterkeys(): print i + # + # This should be left unchanged but trigger a warning: + # + print d.keys()[0] # This is the last line. Added: sandbox/trunk/2to3/fixes/fix_dict.py ============================================================================== --- (empty file) +++ sandbox/trunk/2to3/fixes/fix_dict.py Fri Feb 9 02:27:49 2007 @@ -0,0 +1,90 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. + +"""Fixer for dict methods. + +d.keys() -> list(d.keys()) +d.items() -> list(d.items()) +d.values() -> list(d.values()) + +d.iterkeys() -> iter(d.keys()) +d.iteritems() -> iter(d.items()) +d.itervalues() -> iter(d.values()) + +Except in certain very specific contexts: the iter() can be dropped +when the context is list(), sorted(), iter() or for...in; the list() +can be dropped when the context is list() or sorted() (but not iter() +or for...in!). + +Note: iter(d.keys()) could be written as iter(d) but since the +original d.iterkeys() was also redundant we don't fix this. And there +are (rare) contexts where it makes a difference (e.g. when passing it +as an argument to a function that introspects the argument). +""" + +# Python imports +import token + +# Local imports +import pytree +import patcomp +from fixes import basefix +from fixes import macros + +class FixDict(basefix.BaseFix): + + PATTERN = """ + power< prefix=any+ + trailer< '.' method=('keys'|'items'|'values'| + 'iterkeys'|'iteritems'|'itervalues') > + trailer< '(' ')' > + tail=any* + > + """ + + def transform(self, node): + results = self.match(node) + prefix = results["prefix"] + method = results["method"][0].value # Extract method name + tail = results["tail"] + if tail: + return self.cannot_convert(node, + "stuff after .[iter]keys() etc. unsupported") + syms = self.syms + isiter = method.startswith("iter") + if isiter: + method = method[4:] + assert method in ("keys", "items", "values"), repr(method) + prefix = [n.clone() for n in prefix] + new = pytree.Node(syms.power, + prefix + [pytree.Node(syms.trailer, + [pytree.Leaf(token.DOT, '.'), + macros.Name(method)]), + pytree.Node(syms.trailer, + [macros.lparen_leaf.clone(), + macros.rparen_leaf.clone()])]) + if not self.in_special_context(node, isiter): + new.set_prefix("") + new = macros.Call(macros.Name(isiter and "iter" or "list"), [new]) + new.set_prefix(node.get_prefix()) + return new + + P1 = "trailer< '(' node=any ')' >" + p1 = patcomp.PatternCompiler().compile_pattern(P1) + + P2 = "power< func=NAME trailer< '(' node=any ')' > any* >" + p2 = patcomp.PatternCompiler().compile_pattern(P2) + + def in_special_context(self, node, isiter): + results = {} + if not (self.p1.match(node.parent, results) and + results["node"] is node): + return False + results = {} + if not (self.p2.match(node.parent.parent, results) and + results["node"] is node): + return False + if isiter: + return results["func"].value == ("iter", "list", "sorted") + else: + return results["func"].value in ("list", "sorted") + # XXX TODO: for...in context. From python-checkins at python.org Fri Feb 9 05:10:51 2007 From: python-checkins at python.org (guido.van.rossum) Date: Fri, 9 Feb 2007 05:10:51 +0100 (CET) Subject: [Python-checkins] r53682 - in sandbox/trunk/2to3: example.py fixes/fix_dict.py Message-ID: <20070209041051.1D9F71E4009@bag.python.org> Author: guido.van.rossum Date: Fri Feb 9 05:10:50 2007 New Revision: 53682 Modified: sandbox/trunk/2to3/example.py sandbox/trunk/2to3/fixes/fix_dict.py Log: Refactor the context checking a bit. Add support for special contexts 'for...in'. Modified: sandbox/trunk/2to3/example.py ============================================================================== --- sandbox/trunk/2to3/example.py (original) +++ sandbox/trunk/2to3/example.py Fri Feb 9 05:10:50 2007 @@ -253,26 +253,35 @@ # # Plain method calls in special contexts # - print list(e.keys()) - print sorted(e.keys()) print iter(e.keys()) for i in e.keys(): print i + [i for i in e.keys()] + (i for i in e.keys()) # # Iterator method calls # - print d.iterkeys() - print d.iteritems() - print d.itervalues() + print f.iterkeys() + print f.iteritems() + print f.itervalues() # # Iterator method calls in special contexts # - print list(e.iterkeys()) - print sorted(e.iterkeys()) - print iter(e.iterkeys()) - for i in e.iterkeys(): print i + print list(g.iterkeys()) + print sorted(g.iterkeys()) + print iter(g.iterkeys()) + for i in g.iterkeys(): print i + [i for i in g.iterkeys()] + (i for i in g.iterkeys()) + +def dict_negative_examples(): + # + # These should all remain unchanged: + # + print list(h.keys()) + print sorted(h.keys()) # - # This should be left unchanged but trigger a warning: + # This should be left unchanged and trigger a warning: # - print d.keys()[0] + print h.keys()[0] # This is the last line. Modified: sandbox/trunk/2to3/fixes/fix_dict.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_dict.py (original) +++ sandbox/trunk/2to3/fixes/fix_dict.py Fri Feb 9 05:10:50 2007 @@ -68,23 +68,29 @@ new.set_prefix(node.get_prefix()) return new - P1 = "trailer< '(' node=any ')' >" + P1 = "power< func=NAME trailer< '(' node=any ')' > any* >" p1 = patcomp.PatternCompiler().compile_pattern(P1) - P2 = "power< func=NAME trailer< '(' node=any ')' > any* >" + P2 = """for_stmt< 'for' any 'in' node=any ':' any* > + | list_for< 'for' any 'in' node=any any* > + | gen_for< 'for' any 'in' node=any any* > + """ p2 = patcomp.PatternCompiler().compile_pattern(P2) def in_special_context(self, node, isiter): - results = {} - if not (self.p1.match(node.parent, results) and - results["node"] is node): + if node.parent is None: return False results = {} - if not (self.p2.match(node.parent.parent, results) and - results["node"] is node): + if (node.parent.parent is not None and + self.p1.match(node.parent.parent, results) and + results["node"] is node): + if isiter: + # iter(d.iterkeys()) -> iter(d.keys()), etc. + return results["func"].value in ("iter", "list", "sorted") + else: + # list(d.keys()) -> list(d.keys()), etc. + return results["func"].value in ("list", "sorted") + if not isiter: return False - if isiter: - return results["func"].value == ("iter", "list", "sorted") - else: - return results["func"].value in ("list", "sorted") - # XXX TODO: for...in context. + # for ... in d.iterkeys() -> for ... in d.keys(), etc. + return self.p2.match(node.parent, results) and results["node"] is node From python-checkins at python.org Fri Feb 9 05:41:13 2007 From: python-checkins at python.org (guido.van.rossum) Date: Fri, 9 Feb 2007 05:41:13 +0100 (CET) Subject: [Python-checkins] r53683 - sandbox/trunk/2to3/fixer_tests.py Message-ID: <20070209044113.0549F1E4009@bag.python.org> Author: guido.van.rossum Date: Fri Feb 9 05:41:12 2007 New Revision: 53683 Modified: sandbox/trunk/2to3/fixer_tests.py Log: Unit tests for dict fixer. Modified: sandbox/trunk/2to3/fixer_tests.py ============================================================================== --- sandbox/trunk/2to3/fixer_tests.py (original) +++ sandbox/trunk/2to3/fixer_tests.py Fri Feb 9 05:41:12 2007 @@ -911,6 +911,116 @@ s = """f = sys.exc_type + ":" + sys.exc_value""" self.warns(s, s, "This attribute is going away") + +class Test_dict(FixerTestCase): + fixer = "dict" + + def test_01(self): + b = "d.keys()" + a = "list(d.keys())" + self.check(b, a) + + def test_01a(self): + b = "a[0].foo().keys()" + a = "list(a[0].foo().keys())" + self.check(b, a) + + def test_02(self): + b = "d.items()" + a = "list(d.items())" + self.check(b, a) + + def test_03(self): + b = "d.values()" + a = "list(d.values())" + self.check(b, a) + + def test_04(self): + b = "d.iterkeys()" + a = "iter(d.keys())" + self.check(b, a) + + def test_05(self): + b = "d.iteritems()" + a = "iter(d.items())" + self.check(b, a) + + def test_06(self): + b = "d.itervalues()" + a = "iter(d.values())" + self.check(b, a) + + def test_07(self): + b = "list(d.keys())" + a = b + self.check(b, a) + + def test_08(self): + b = "sorted(d.keys())" + a = b + self.check(b, a) + + def test_09(self): + b = "iter(d.keys())" + a = "iter(list(d.keys()))" + self.check(b, a) + + def test_10(self): + b = "foo(d.keys())" + a = "foo(list(d.keys()))" + self.check(b, a) + + def test_11(self): + b = "for i in d.keys(): print i" + a = "for i in list(d.keys()): print i" + self.check(b, a) + + def test_12(self): + b = "for i in d.iterkeys(): print i" + a = "for i in d.keys(): print i" + self.check(b, a) + + def test_13(self): + b = "[i for i in d.keys()]" + a = "[i for i in list(d.keys())]" + self.check(b, a) + + def test_14(self): + b = "[i for i in d.iterkeys()]" + a = "[i for i in d.keys()]" + self.check(b, a) + + def test_15(self): + b = "(i for i in d.keys())" + a = "(i for i in list(d.keys()))" + self.check(b, a) + + def test_16(self): + b = "(i for i in d.iterkeys())" + a = "(i for i in d.keys())" + self.check(b, a) + + def test_17(self): + b = "iter(d.iterkeys())" + a = "iter(d.keys())" + self.check(b, a) + + def test_18(self): + b = "list(d.iterkeys())" + a = "list(d.keys())" + self.check(b, a) + + def test_19(self): + b = "sorted(d.iterkeys())" + a = "sorted(d.keys())" + self.check(b, a) + + def test_20(self): + b = "foo(d.iterkeys())" + a = "foo(iter(d.keys()))" + self.check(b, a) + + if __name__ == "__main__": import sys if not sys.argv[1:]: From python-checkins at python.org Fri Feb 9 05:55:42 2007 From: python-checkins at python.org (guido.van.rossum) Date: Fri, 9 Feb 2007 05:55:42 +0100 (CET) Subject: [Python-checkins] r53684 - sandbox/trunk/2to3/fixes/fix_print.py Message-ID: <20070209045542.428E51E4009@bag.python.org> Author: guido.van.rossum Date: Fri Feb 9 05:55:41 2007 New Revision: 53684 Modified: sandbox/trunk/2to3/fixes/fix_print.py Log: Use print() instead of Print(). Modified: sandbox/trunk/2to3/fixes/fix_print.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_print.py (original) +++ sandbox/trunk/2to3/fixes/fix_print.py Fri Feb 9 05:55:41 2007 @@ -4,10 +4,10 @@ """Fixer for print. Change: - 'print' into 'Print()' - 'print ...' into 'Print(...)' - 'print ... ,' into 'Print(..., end=" ")' - 'print >>x, ...' into 'Print(..., file=x)' + 'print' into 'print()' + 'print ...' into 'print(...)' + 'print ... ,' into 'print(..., end=" ")' + 'print >>x, ...' into 'print(..., file=x)' """ # Python imports @@ -39,7 +39,7 @@ if node == Name("print"): # Special-case print all by itself - new = Call(Name("Print"), []) + new = Call(Name("print"), []) new.set_prefix(node.get_prefix()) return new assert node.children[0] == Name("print") @@ -52,7 +52,7 @@ assert len(args) >= 2 file = args[1].clone() args = args[3:] # Strip a possible comma after the file expression - # Now synthesize a Print(args, sep=..., end=..., file=...) node. + # Now synthesize a print(args, sep=..., end=..., file=...) node. l_args = [arg.clone() for arg in args] if l_args: l_args[0].set_prefix("") @@ -65,7 +65,7 @@ pytree.Leaf(token.STRING, repr(end))) if file is not None: self.add_kwarg(l_args, "file", file) - n_stmt = Call(Name("Print"), l_args) + n_stmt = Call(Name("print"), l_args) n_stmt.set_prefix(node.get_prefix()) return n_stmt From python-checkins at python.org Fri Feb 9 06:41:38 2007 From: python-checkins at python.org (guido.van.rossum) Date: Fri, 9 Feb 2007 06:41:38 +0100 (CET) Subject: [Python-checkins] r53687 - peps/trunk/pep-3100.txt Message-ID: <20070209054138.164711E4014@bag.python.org> Author: guido.van.rossum Date: Fri Feb 9 06:41:37 2007 New Revision: 53687 Modified: peps/trunk/pep-3100.txt Log: Mark print conversion as mostly done. Modified: peps/trunk/pep-3100.txt ============================================================================== --- peps/trunk/pep-3100.txt (original) +++ peps/trunk/pep-3100.txt Fri Feb 9 06:41:37 2007 @@ -67,7 +67,7 @@ * ``exec`` as a statement is not worth it -- make it a function [done] * (Maybe) add optional declarations for static typing [#pep3107]_ [10]_ * Support only new-style classes; classic classes will be gone [1]_ [done] -* Replace ``print`` by a function [14]_ [#pep3105]_ +* Replace ``print`` by a function [14]_ [#pep3105]_ [mostly done] * Use ``except E1, E2, E3 as err:`` if you want the error variable. [3]_ * ``None`` becomes a keyword [4]_ (What about ``True``, ``False``?) * ``...`` to become a general expression element [16]_ [done] From python-checkins at python.org Fri Feb 9 13:19:33 2007 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 9 Feb 2007 13:19:33 +0100 (CET) Subject: [Python-checkins] r53689 - in python/trunk: Misc/NEWS Objects/typeobject.c Message-ID: <20070209121933.AB1DF1E400A@bag.python.org> Author: martin.v.loewis Date: Fri Feb 9 13:19:32 2007 New Revision: 53689 Modified: python/trunk/Misc/NEWS python/trunk/Objects/typeobject.c Log: Bug #1653736: Properly discard third argument to slot_nb_inplace_power. Will backport. Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Feb 9 13:19:32 2007 @@ -12,6 +12,8 @@ Core and builtins ----------------- +- Bug #1653736: Properly discard third argument to slot_nb_inplace_power. + - PEP 352: Raising a string exception now triggers a TypeError. Attempting to catch a string exception raises DeprecationWarning. Modified: python/trunk/Objects/typeobject.c ============================================================================== --- python/trunk/Objects/typeobject.c (original) +++ python/trunk/Objects/typeobject.c Fri Feb 9 13:19:32 2007 @@ -4427,7 +4427,13 @@ SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *, "O") SLOT1(slot_nb_inplace_divide, "__idiv__", PyObject *, "O") SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *, "O") -SLOT1(slot_nb_inplace_power, "__ipow__", PyObject *, "O") +/* Can't use SLOT1 here, because nb_inplace_power is ternary */ +static PyObject * +slot_nb_inplace_power(PyObject *self, PyObject * arg1, PyObject *arg2) +{ + static PyObject *cache_str; + return call_method(self, "__ipow__", &cache_str, "(" "O" ")", arg1); +} SLOT1(slot_nb_inplace_lshift, "__ilshift__", PyObject *, "O") SLOT1(slot_nb_inplace_rshift, "__irshift__", PyObject *, "O") SLOT1(slot_nb_inplace_and, "__iand__", PyObject *, "O") From python-checkins at python.org Fri Feb 9 13:19:47 2007 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 9 Feb 2007 13:19:47 +0100 (CET) Subject: [Python-checkins] r53690 - in python/branches/release25-maint: Misc/NEWS Objects/typeobject.c Message-ID: <20070209121947.22E2D1E400A@bag.python.org> Author: martin.v.loewis Date: Fri Feb 9 13:19:46 2007 New Revision: 53690 Modified: python/branches/release25-maint/Misc/NEWS python/branches/release25-maint/Objects/typeobject.c Log: Bug #1653736: Properly discard third argument to slot_nb_inplace_power. Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Fri Feb 9 13:19:46 2007 @@ -12,6 +12,8 @@ Core and builtins ----------------- +- Bug #1653736: Properly discard third argument to slot_nb_inplace_power. + - SF #151204: enumerate() now raises an Overflow error at sys.maxint items. - Bug #1377858: Fix the segfaulting of the interpreter when an object created Modified: python/branches/release25-maint/Objects/typeobject.c ============================================================================== --- python/branches/release25-maint/Objects/typeobject.c (original) +++ python/branches/release25-maint/Objects/typeobject.c Fri Feb 9 13:19:46 2007 @@ -4427,7 +4427,13 @@ SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *, "O") SLOT1(slot_nb_inplace_divide, "__idiv__", PyObject *, "O") SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *, "O") -SLOT1(slot_nb_inplace_power, "__ipow__", PyObject *, "O") +/* Can't use SLOT1 here, because nb_inplace_power is ternary */ +static PyObject * +slot_nb_inplace_power(PyObject *self, PyObject * arg1, PyObject *arg2) +{ + static PyObject *cache_str; + return call_method(self, "__ipow__", &cache_str, "(" "O" ")", arg1); +} SLOT1(slot_nb_inplace_lshift, "__ilshift__", PyObject *, "O") SLOT1(slot_nb_inplace_rshift, "__irshift__", PyObject *, "O") SLOT1(slot_nb_inplace_and, "__iand__", PyObject *, "O") From python-checkins at python.org Fri Feb 9 13:36:49 2007 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 9 Feb 2007 13:36:49 +0100 (CET) Subject: [Python-checkins] r53691 - in python/trunk: Lib/distutils/command/build_ext.py Misc/NEWS Message-ID: <20070209123649.E28321E400A@bag.python.org> Author: martin.v.loewis Date: Fri Feb 9 13:36:48 2007 New Revision: 53691 Modified: python/trunk/Lib/distutils/command/build_ext.py python/trunk/Misc/NEWS Log: Bug #1600860: Search for shared python library in LIBDIR, not lib/python/config, on "linux" and "gnu" systems. Will backport. Modified: python/trunk/Lib/distutils/command/build_ext.py ============================================================================== --- python/trunk/Lib/distutils/command/build_ext.py (original) +++ python/trunk/Lib/distutils/command/build_ext.py Fri Feb 9 13:36:48 2007 @@ -185,9 +185,7 @@ # for extensions under Cygwin and AtheOS Python's library directory must be # appended to library_dirs - if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos' or \ - ((sys.platform.startswith('linux') or sys.platform.startswith('gnu')) and - sysconfig.get_config_var('Py_ENABLE_SHARED')): + if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos': if string.find(sys.executable, sys.exec_prefix) != -1: # building third party extensions self.library_dirs.append(os.path.join(sys.prefix, "lib", @@ -197,6 +195,17 @@ # building python standard extensions self.library_dirs.append('.') + # for extensions under Linux with a shared Python library, + # Python's library directory must be appended to library_dirs + if (sys.platform.startswith('linux') or sys.platform.startswith('gnu')) \ + and sysconfig.get_config_var('Py_ENABLE_SHARED'): + if string.find(sys.executable, sys.exec_prefix) != -1: + # building third party extensions + self.library_dirs.append(sysconfig.get_config_var('LIBDIR')) + else: + # building python standard extensions + self.library_dirs.append('.') + # The argument parsing will result in self.define being a string, but # it has to be a list of 2-tuples. All the preprocessor symbols # specified by the 'define' option will be set to '1'. Multiple Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Feb 9 13:36:48 2007 @@ -128,6 +128,9 @@ Library ------- +- Bug #1600860: Search for shared python library in LIBDIR, not lib/python/config, + on "linux" and "gnu" systems. + - Patch #1652681: tarfile.py: create nonexistent files in append mode and allow appending to empty files. From python-checkins at python.org Fri Feb 9 13:37:13 2007 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 9 Feb 2007 13:37:13 +0100 (CET) Subject: [Python-checkins] r53692 - in python/branches/release25-maint: Lib/distutils/command/build_ext.py Misc/NEWS Message-ID: <20070209123713.A0A1E1E400A@bag.python.org> Author: martin.v.loewis Date: Fri Feb 9 13:37:12 2007 New Revision: 53692 Modified: python/branches/release25-maint/Lib/distutils/command/build_ext.py python/branches/release25-maint/Misc/NEWS Log: Bug #1600860: Search for shared python library in LIBDIR, not lib/python/config, on "linux" and "gnu" systems. Modified: python/branches/release25-maint/Lib/distutils/command/build_ext.py ============================================================================== --- python/branches/release25-maint/Lib/distutils/command/build_ext.py (original) +++ python/branches/release25-maint/Lib/distutils/command/build_ext.py Fri Feb 9 13:37:12 2007 @@ -185,9 +185,7 @@ # for extensions under Cygwin and AtheOS Python's library directory must be # appended to library_dirs - if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos' or \ - ((sys.platform.startswith('linux') or sys.platform.startswith('gnu')) and - sysconfig.get_config_var('Py_ENABLE_SHARED')): + if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos': if string.find(sys.executable, sys.exec_prefix) != -1: # building third party extensions self.library_dirs.append(os.path.join(sys.prefix, "lib", @@ -197,6 +195,17 @@ # building python standard extensions self.library_dirs.append('.') + # for extensions under Linux with a shared Python library, + # Python's library directory must be appended to library_dirs + if (sys.platform.startswith('linux') or sys.platform.startswith('gnu')) \ + and sysconfig.get_config_var('Py_ENABLE_SHARED'): + if string.find(sys.executable, sys.exec_prefix) != -1: + # building third party extensions + self.library_dirs.append(sysconfig.get_config_var('LIBDIR')) + else: + # building python standard extensions + self.library_dirs.append('.') + # The argument parsing will result in self.define being a string, but # it has to be a list of 2-tuples. All the preprocessor symbols # specified by the 'define' option will be set to '1'. Multiple Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Fri Feb 9 13:37:12 2007 @@ -169,6 +169,9 @@ Library ------- +- Bug #1600860: Search for shared python library in LIBDIR, not lib/python/config, + on "linux" and "gnu" systems. + - Bug #1124861: Automatically create pipes if GetStdHandle fails in subprocess. From python-checkins at python.org Fri Feb 9 13:58:50 2007 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 9 Feb 2007 13:58:50 +0100 (CET) Subject: [Python-checkins] r53693 - python/trunk/Doc/lib/emailgenerator.tex Message-ID: <20070209125850.B26F21E400A@bag.python.org> Author: martin.v.loewis Date: Fri Feb 9 13:58:49 2007 New Revision: 53693 Modified: python/trunk/Doc/lib/emailgenerator.tex Log: Update broken link. Will backport to 2.5. Modified: python/trunk/Doc/lib/emailgenerator.tex ============================================================================== --- python/trunk/Doc/lib/emailgenerator.tex (original) +++ python/trunk/Doc/lib/emailgenerator.tex Fri Feb 9 13:58:49 2007 @@ -33,7 +33,7 @@ line. This is the only guaranteed portable way to avoid having such lines be mistaken for a \UNIX{} mailbox format envelope header separator (see \ulink{WHY THE CONTENT-LENGTH FORMAT IS BAD} -{http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html} +{http://www.jwz.org/doc/content-length.html} for details). \var{mangle_from_} defaults to \code{True}, but you might want to set this to \code{False} if you are not writing \UNIX{} mailbox format files. From python-checkins at python.org Fri Feb 9 13:59:28 2007 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 9 Feb 2007 13:59:28 +0100 (CET) Subject: [Python-checkins] r53694 - python/branches/release25-maint/Doc/lib/emailgenerator.tex Message-ID: <20070209125928.3F0CF1E400A@bag.python.org> Author: martin.v.loewis Date: Fri Feb 9 13:59:27 2007 New Revision: 53694 Modified: python/branches/release25-maint/Doc/lib/emailgenerator.tex Log: Update broken link. Modified: python/branches/release25-maint/Doc/lib/emailgenerator.tex ============================================================================== --- python/branches/release25-maint/Doc/lib/emailgenerator.tex (original) +++ python/branches/release25-maint/Doc/lib/emailgenerator.tex Fri Feb 9 13:59:27 2007 @@ -33,7 +33,7 @@ line. This is the only guaranteed portable way to avoid having such lines be mistaken for a \UNIX{} mailbox format envelope header separator (see \ulink{WHY THE CONTENT-LENGTH FORMAT IS BAD} -{http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html} +{http://www.jwz.org/doc/content-length.html} for details). \var{mangle_from_} defaults to \code{True}, but you might want to set this to \code{False} if you are not writing \UNIX{} mailbox format files. From buildbot at python.org Fri Feb 9 14:12:03 2007 From: buildbot at python.org (buildbot at python.org) Date: Fri, 09 Feb 2007 13:12:03 +0000 Subject: [Python-checkins] buildbot warnings in alpha Tru64 5.1 trunk Message-ID: <20070209131203.E514A1E400A@bag.python.org> The Buildbot has detected a new failure of alpha Tru64 5.1 trunk. Full details are available at: http://www.python.org/dev/buildbot/all/alpha%2520Tru64%25205.1%2520trunk/builds/1394 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_socket ====================================================================== FAIL: testInterruptedTimeout (test.test_socket.TCPTimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/net/ringneck/scratch1/nnorwitz/python/trunk.norwitz-tru64/build/Lib/test/test_socket.py", line 886, in testInterruptedTimeout self.fail("got Alarm in wrong place") AssertionError: got Alarm in wrong place sincerely, -The Buildbot From buildbot at python.org Fri Feb 9 14:38:46 2007 From: buildbot at python.org (buildbot at python.org) Date: Fri, 09 Feb 2007 13:38:46 +0000 Subject: [Python-checkins] buildbot warnings in x86 gentoo 2.5 Message-ID: <20070209133846.65E191E400A@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520gentoo%25202.5/builds/221 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: Traceback (most recent call last): File "/home/buildslave/python-trunk/2.5.norwitz-x86/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/buildslave/python-trunk/2.5.norwitz-x86/build/Lib/test/test_socketserver.py", line 81, in run svr = svrcls(self.__addr, self.__hdlrcls) File "/home/buildslave/python-trunk/2.5.norwitz-x86/build/Lib/SocketServer.py", line 330, in __init__ self.server_bind() File "/home/buildslave/python-trunk/2.5.norwitz-x86/build/Lib/SocketServer.py", line 341, in server_bind self.socket.bind(self.server_address) File "", line 1, in bind error: (98, 'Address already in use') 1 test failed: test_socketserver make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Fri Feb 9 15:04:16 2007 From: buildbot at python.org (buildbot at python.org) Date: Fri, 09 Feb 2007 14:04:16 +0000 Subject: [Python-checkins] buildbot warnings in PPC64 Debian trunk Message-ID: <20070209140416.7CCFE1E4010@bag.python.org> The Buildbot has detected a new failure of PPC64 Debian trunk. Full details are available at: http://www.python.org/dev/buildbot/all/PPC64%2520Debian%2520trunk/builds/59 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_ctypes make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Fri Feb 9 15:50:40 2007 From: python-checkins at python.org (collin.winter) Date: Fri, 9 Feb 2007 15:50:40 +0100 (CET) Subject: [Python-checkins] r53695 - peps/trunk/pep-3109.txt Message-ID: <20070209145040.DC1CF1E4010@bag.python.org> Author: collin.winter Date: Fri Feb 9 15:50:40 2007 New Revision: 53695 Modified: peps/trunk/pep-3109.txt Log: Fix off-by-one indentation error Modified: peps/trunk/pep-3109.txt ============================================================================== --- peps/trunk/pep-3109.txt (original) +++ peps/trunk/pep-3109.txt Fri Feb 9 15:50:40 2007 @@ -215,24 +215,24 @@ except E as V: handle(V) - 2. ``raise E, V`` as a way of "casting" an exception to another - class. Taking an example from - distutils.compiler.unixcompiler :: - - try: - self.spawn(pp_args) - except DistutilsExecError as msg: - raise CompileError(msg) - - This would be better expressed as :: - - try: - self.spawn(pp_args) - except DistutilsExecError as msg: - raise CompileError from msg - - Using the ``raise ... from ...`` syntax introduced in - PEP 344. + 2. ``raise E, V`` as a way of "casting" an exception to another + class. Taking an example from + distutils.compiler.unixcompiler :: + + try: + self.spawn(pp_args) + except DistutilsExecError as msg: + raise CompileError(msg) + + This would be better expressed as :: + + try: + self.spawn(pp_args) + except DistutilsExecError as msg: + raise CompileError from msg + + Using the ``raise ... from ...`` syntax introduced in + PEP 344. References From buildbot at python.org Fri Feb 9 17:10:24 2007 From: buildbot at python.org (buildbot at python.org) Date: Fri, 09 Feb 2007 16:10:24 +0000 Subject: [Python-checkins] buildbot warnings in x86 cygwin 2.5 Message-ID: <20070209161024.D87AD1E4010@bag.python.org> The Buildbot has detected a new failure of x86 cygwin 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520cygwin%25202.5/builds/8 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: andrew.kuchling,brett.cannon,fred.drake,georg.brandl,martin.v.loewis,peter.astrand,raymond.hettinger,thomas.heller Build had warnings: warnings failed slave lost sincerely, -The Buildbot From python-checkins at python.org Fri Feb 9 17:25:05 2007 From: python-checkins at python.org (guido.van.rossum) Date: Fri, 9 Feb 2007 17:25:05 +0100 (CET) Subject: [Python-checkins] r53696 - sandbox/trunk/2to3/refactor.py Message-ID: <20070209162505.8CFD01E4010@bag.python.org> Author: guido.van.rossum Date: Fri Feb 9 17:25:05 2007 New Revision: 53696 Modified: sandbox/trunk/2to3/refactor.py Log: Make a log message about modified files unambiguous. Modified: sandbox/trunk/2to3/refactor.py ============================================================================== --- sandbox/trunk/2to3/refactor.py (original) +++ sandbox/trunk/2to3/refactor.py Fri Feb 9 17:25:05 2007 @@ -262,10 +262,14 @@ self.log_message("Wrote changes to %s", filename) def summarize(self): + if self.options.write: + were = "were" + else: + were = "should be" if not self.files: - self.log_message("No files were (or should be) modified.") + self.log_message("No files %s modified.", were) else: - self.log_message("Files that were (or should be) modified:") + self.log_message("Files that %s modified:", were) for file in self.files: self.log_message(file) if self.errors: From buildbot at python.org Fri Feb 9 18:19:52 2007 From: buildbot at python.org (buildbot at python.org) Date: Fri, 09 Feb 2007 17:19:52 +0000 Subject: [Python-checkins] buildbot warnings in hppa Ubuntu dapper 2.5 Message-ID: <20070209171952.3E06D1E4010@bag.python.org> The Buildbot has detected a new failure of hppa Ubuntu dapper 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/hppa%2520Ubuntu%2520dapper%25202.5/builds/31 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: make: *** [buildbottest] Killed sincerely, -The Buildbot From python-checkins at python.org Fri Feb 9 19:48:42 2007 From: python-checkins at python.org (georg.brandl) Date: Fri, 9 Feb 2007 19:48:42 +0100 (CET) Subject: [Python-checkins] r53697 - python/trunk/Doc/lib/libprofile.tex Message-ID: <20070209184842.1BAEF1E4012@bag.python.org> Author: georg.brandl Date: Fri Feb 9 19:48:41 2007 New Revision: 53697 Modified: python/trunk/Doc/lib/libprofile.tex Log: Bug #1656078: typo in in profile docs. Modified: python/trunk/Doc/lib/libprofile.tex ============================================================================== --- python/trunk/Doc/lib/libprofile.tex (original) +++ python/trunk/Doc/lib/libprofile.tex Fri Feb 9 19:48:41 2007 @@ -319,7 +319,7 @@ \begin{funcdesc}{run}{command\optional{, filename}} -This function takes a single argument that has can be passed to the +This function takes a single argument that can be passed to the \keyword{exec} statement, and an optional file name. In all cases this routine attempts to \keyword{exec} its first argument, and gather profiling statistics from the execution. If no file name is present, then this From python-checkins at python.org Fri Feb 9 19:48:45 2007 From: python-checkins at python.org (georg.brandl) Date: Fri, 9 Feb 2007 19:48:45 +0100 (CET) Subject: [Python-checkins] r53698 - python/branches/release25-maint/Doc/lib/libprofile.tex Message-ID: <20070209184845.1ACFD1E4012@bag.python.org> Author: georg.brandl Date: Fri Feb 9 19:48:44 2007 New Revision: 53698 Modified: python/branches/release25-maint/Doc/lib/libprofile.tex Log: Bug #1656078: typo in in profile docs. (backport from rev. 53697) Modified: python/branches/release25-maint/Doc/lib/libprofile.tex ============================================================================== --- python/branches/release25-maint/Doc/lib/libprofile.tex (original) +++ python/branches/release25-maint/Doc/lib/libprofile.tex Fri Feb 9 19:48:44 2007 @@ -319,7 +319,7 @@ \begin{funcdesc}{run}{command\optional{, filename}} -This function takes a single argument that has can be passed to the +This function takes a single argument that can be passed to the \keyword{exec} statement, and an optional file name. In all cases this routine attempts to \keyword{exec} its first argument, and gather profiling statistics from the execution. If no file name is present, then this From python-checkins at python.org Fri Feb 9 21:00:13 2007 From: python-checkins at python.org (guido.van.rossum) Date: Fri, 9 Feb 2007 21:00:13 +0100 (CET) Subject: [Python-checkins] r53699 - sandbox/trunk/2to3/example.py sandbox/trunk/2to3/refactor.py Message-ID: <20070209200013.D5C801E401C@bag.python.org> Author: guido.van.rossum Date: Fri Feb 9 21:00:11 2007 New Revision: 53699 Modified: sandbox/trunk/2to3/example.py sandbox/trunk/2to3/refactor.py Log: Add a new option to fix doctests. For now, you must choose to either fix doctests or the regular source code; you can't fix both at once. Also, it doesn't really parse docstrings; it just looks for lines starting with >>> anywhere in the input file(s). Modified: sandbox/trunk/2to3/example.py ============================================================================== --- sandbox/trunk/2to3/example.py (original) +++ sandbox/trunk/2to3/example.py Fri Feb 9 21:00:11 2007 @@ -1,6 +1,33 @@ #!/usr/bin/python # comment indented by tab -"""Docstring.""" + +"""Docstring. + +Here are some doctest exampes: + +>>> print 42 +42 + + >>> d = {1: 1, 2: 2, 2: 2} + >>> d.keys().sort() + >>> print d + {1: 1, 2: 2} + + >>> for i in d.keys(): + ... print i, d[i] + +And a tricky one: + +>>> class X(Structure): +... _fields_ = [("x", c_int), ("y", c_int), ("array", c_char_p * 5)] +... +>>> x = X() +>>> print x._objects +None +>>> + +""" + import sys def ne_examples(): Modified: sandbox/trunk/2to3/refactor.py ============================================================================== --- sandbox/trunk/2to3/refactor.py (original) +++ sandbox/trunk/2to3/refactor.py Fri Feb 9 21:00:11 2007 @@ -26,9 +26,11 @@ import fixes import fixes.macros import pygram +import tokenize logging.basicConfig(format='%(name)s: %(message)s', level=logging.INFO) + def main(args=None): """Main program. @@ -39,13 +41,16 @@ """ # Set up option parser parser = optparse.OptionParser(usage="refactor.py [options] file|dir ...") + parser.add_option("-d", "--doctests_only", action="store_true", + help="Fix up doctests only") parser.add_option("-f", "--fix", action="append", default=[], help="Each FIX specifies a transformation; default all") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations (fixes/fix_*.py)") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") - parser.add_option("-w", "--write", action="store_true") + parser.add_option("-w", "--write", action="store_true", + help="Write back modified files") # Parse command line arguments options, args = parser.parse_args(args) @@ -92,7 +97,7 @@ The argument is an optparse.Values instance. """ self.options = options - self.errors = 0 + self.errors = [] self.logger = logging.getLogger("RefactoringTool") self.driver = driver.Driver(pygram.python_grammar, convert=pytree.convert, @@ -133,7 +138,7 @@ def log_error(self, msg, *args, **kwds): """Increments error count and log a message.""" - self.errors += 1 + self.errors.append((msg, args, kwds)) self.logger.error(msg, *args, **kwds) def log_message(self, msg, *args): @@ -177,23 +182,35 @@ self.log_error("Can't open %s: %s", filename, err) return try: - try: - tree = self.driver.parse_file(filename) - except Exception, err: - self.log_error("Can't parse %s: %s: %s", - filename, err.__class__.__name__, err) - return + if self.options.doctests_only: + input = f.read() + else: + try: + tree = self.driver.parse_file(filename) + except Exception, err: + self.log_error("Can't parse %s: %s: %s", + filename, err.__class__.__name__, err) + return + finally: + f.close() + if self.options.doctests_only: + if self.options.verbose: + self.log_message("Refactoring doctests in %s", filename) + output = self.refactor_docstring(input, filename) + if output != input: + self.write_file(output, filename, input) + elif self.options.verbose: + self.log_message("No doctest changes in %s", filename) + else: if self.options.verbose: self.log_message("Refactoring %s", filename) if self.refactor_tree(tree, filename): - self.write_tree(tree, filename) + self.write_file(str(tree), filename) elif self.options.verbose: self.log_message("No changes in %s", filename) - finally: - f.close() def refactor_tree(self, tree, filename): - """Refactors a parse tree.""" + """Refactors a parse tree (modifying the tree in place).""" for fixer in self.fixers: fixer.set_filename(filename) fixer.used_names = tree.used_names @@ -207,26 +224,26 @@ changes += 1 return changes - def write_tree(self, tree, filename): - """Writes a (presumably modified) tree to a file. + def write_file(self, new_text, filename, old_text=None): + """Writes a string to a file. If there are no changes, this is a no-op. - Otherwise, it first shows a unified diff between the old file - and the tree, and then rewrites the file, but the latter is + Otherwise, it first shows a unified diff between the old text + and the new text, and then rewrites the file; the latter is only done if the write option is set. """ self.files.append(filename) - try: - f = open(filename, "r") - except IOError, err: - self.log_error("Can't read %s: %s", filename, err) - return - try: - old_text = f.read() - finally: - f.close() - new_text = str(tree) + if old_text is None: + try: + f = open(filename, "r") + except IOError, err: + self.log_error("Can't read %s: %s", filename, err) + return + try: + old_text = f.read() + finally: + f.close() if old_text == new_text: if self.options.verbose: self.log_message("No changes to %s", filename) @@ -261,11 +278,86 @@ if self.options.verbose: self.log_message("Wrote changes to %s", filename) + PS1 = ">>> " + PS2 = "... " + + def refactor_docstring(self, input, filename): + """Refactors a docstring, looking for doctests. + + This returns a modified version of the input string. It looks + for doctests, which start with a ">>>" prompt, and may be + continued with "..." prompts, as long as the "..." is indented + the same as the ">>>". + + (Unfortunately we can't use the doctest module's parser, + since, like most parsers, it is not geared towards preserving + the original source.) + """ + result = [] + block = None + block_lineno = None + indent = None + lineno = 0 + for line in input.splitlines(True): + lineno += 1 + if line.lstrip().startswith(self.PS1): + if block is not None: + result.extend(self.refactor_doctest(block, block_lineno, + indent, filename)) + block_lineno = lineno + block = [line] + i = line.find(self.PS1) + indent = line[:i] + elif (indent is not None and + (line.startswith(indent + self.PS2) or + line == indent + self.PS2.rstrip() + "\n")): + block.append(line) + else: + if block is not None: + result.extend(self.refactor_doctest(block, block_lineno, + indent, filename)) + block = None + indent = None + result.append(line) + if block is not None: + result.extend(self.refactor_doctest(block, block_lineno, + indent, filename)) + return "".join(result) + + def refactor_doctest(self, block, lineno, indent, filename): + """Refactors one doctest. + + A doctest is given as a block of lines, the first of which starts + with ">>>" (possibly indented), while the remaining lines start + with "..." (identically indented). + + """ + try: + tree = self.parse_block(block, lineno, indent) + except Exception, err: + if self.options.verbose: + for line in block: + self.log_message("Source: %s", line.rstrip("\n")) + self.log_error("Can't parse docstring in %s line %s: %s: %s", + filename, lineno, err.__class__.__name__, err) + return block + if self.refactor_tree(tree, filename): + new = str(tree).splitlines(True) + # Undo the adjustment of the line numbers in wrap_toks() below. + clipped, new = new[:lineno-1], new[lineno-1:] + assert clipped == ["\n"] * (lineno-1), clipped + if not new[-1].endswith("\n"): + new[-1] += "\n" + block = [indent + self.PS1 + new.pop(0)] + if new: + block += [indent + self.PS2 + line for line in new] + return block + def summarize(self): if self.options.write: were = "were" else: - were = "should be" + were = "need to be" if not self.files: self.log_message("No files %s modified.", were) else: @@ -273,13 +365,57 @@ for file in self.files: self.log_message(file) if self.errors: - if self.errors == 1: - self.log_message("There was 1 error") + if len(self.errors) == 1: + self.log_message("There was 1 error:") + else: + self.log_message("There were %d errors:", len(self.errors)) + for msg, args, kwds in self.errors: + self.log_message(msg, *args, **kwds) + + def parse_block(self, block, lineno, indent): + """Parses a block into a tree. + + This is necessary to get correct line number / offset information + in the parser diagnostics and embedded into the parse tree. + """ + return self.driver.parse_tokens(self.wrap_toks(block, lineno, indent)) + + def wrap_toks(self, block, lineno, indent): + """Wraps a tokenize stream to systematically modify start/end.""" + tokens = tokenize.generate_tokens(self.gen_lines(block, indent).next) + for type, value, (line0, col0), (line1, col1), line_text in tokens: + line0 += lineno - 1 + line1 += lineno - 1 + # Don't bother updating the columns; this is too complicated + # since line_text would also have to be updated and it would + # still break for tokens spanning lines. Let the user guess + # that the column numbers for doctests are relative to the + # end of the prompt string (PS1 or PS2). + yield type, value, (line0, col0), (line1, col1), line_text + + + def gen_lines(self, block, indent): + """Generates lines as expected by tokenize from a list of lines. + + This strips the first len(indent + self.PS1) characters off each line. + """ + prefix1 = indent + self.PS1 + prefix2 = indent + self.PS2 + prefix = prefix1 + for line in block: + if line.startswith(prefix): + yield line[len(prefix):] + elif line == prefix.rstrip() + "\n": + yield "\n" else: - self.log_message("There were %d errors", self.errors) + raise AssertionError("line=%r, prefix=%r" % (line, prefix)) + prefix = prefix2 + while True: + yield "" def diff_texts(a, b, filename): + """Prints a unified diff of two strings.""" a = a.splitlines() b = b.splitlines() for line in difflib.unified_diff(a, b, filename, filename, From python-checkins at python.org Fri Feb 9 21:02:27 2007 From: python-checkins at python.org (guido.van.rossum) Date: Fri, 9 Feb 2007 21:02:27 +0100 (CET) Subject: [Python-checkins] r53700 - sandbox/trunk/2to3/fixer_tests.py Message-ID: <20070209200227.0AC4D1E4028@bag.python.org> Author: guido.van.rossum Date: Fri Feb 9 21:02:26 2007 New Revision: 53700 Modified: sandbox/trunk/2to3/fixer_tests.py Log: Fix unit tests that broke when I changed print() to Print(). Modified: sandbox/trunk/2to3/fixer_tests.py ============================================================================== --- sandbox/trunk/2to3/fixer_tests.py (original) +++ sandbox/trunk/2to3/fixer_tests.py Fri Feb 9 21:02:26 2007 @@ -334,34 +334,34 @@ def test_1(self): b = """print 1, 1+1, 1+1+1""" - a = """Print(1, 1+1, 1+1+1)""" + a = """print(1, 1+1, 1+1+1)""" self.check(b, a) def test_2(self): b = """print 1, 2""" - a = """Print(1, 2)""" + a = """print(1, 2)""" self.check(b, a) def test_3(self): b = """print""" - a = """Print()""" + a = """print()""" self.check(b, a) # trailing commas def test_4(self): b = """print 1, 2, 3,""" - a = """Print(1, 2, 3, end=' ')""" + a = """print(1, 2, 3, end=' ')""" self.check(b, a) def test_5(self): b = """print 1, 2,""" - a = """Print(1, 2, end=' ')""" + a = """print(1, 2, end=' ')""" self.check(b, a) def test_6(self): b = """print 1,""" - a = """Print(1, end=' ')""" + a = """print(1, end=' ')""" self.check(b, a) # >> stuff @@ -369,25 +369,25 @@ # no trailing comma def test_7(self): b = """print >>sys.stderr, 1, 2, 3""" - a = """Print(1, 2, 3, file=sys.stderr)""" + a = """print(1, 2, 3, file=sys.stderr)""" self.check(b, a) # trailing comma def test_8(self): b = """print >>sys.stderr, 1, 2,""" - a = """Print(1, 2, end=' ', file=sys.stderr)""" + a = """print(1, 2, end=' ', file=sys.stderr)""" self.check(b, a) # no trailing comma def test_9(self): b = """print >>sys.stderr, 1+1""" - a = """Print(1+1, file=sys.stderr)""" + a = """print(1+1, file=sys.stderr)""" self.check(b, a) # spaces before sys.stderr def test_10(self): b = """print >> sys.stderr""" - a = """Print(file=sys.stderr)""" + a = """print(file=sys.stderr)""" self.check(b, a) From python-checkins at python.org Sat Feb 10 00:52:38 2007 From: python-checkins at python.org (guido.van.rossum) Date: Sat, 10 Feb 2007 00:52:38 +0100 (CET) Subject: [Python-checkins] r53720 - peps/trunk/pep-3100.txt Message-ID: <20070209235238.77D931E4012@bag.python.org> Author: guido.van.rossum Date: Sat Feb 10 00:52:38 2007 New Revision: 53720 Modified: peps/trunk/pep-3100.txt Log: Mark print() as done, period. Note that softspace is gone too. Modified: peps/trunk/pep-3100.txt ============================================================================== --- peps/trunk/pep-3100.txt (original) +++ peps/trunk/pep-3100.txt Sat Feb 10 00:52:38 2007 @@ -67,7 +67,8 @@ * ``exec`` as a statement is not worth it -- make it a function [done] * (Maybe) add optional declarations for static typing [#pep3107]_ [10]_ * Support only new-style classes; classic classes will be gone [1]_ [done] -* Replace ``print`` by a function [14]_ [#pep3105]_ [mostly done] +* Replace ``print`` by a function [14]_ [#pep3105]_ [done] +* The ``softspace`` attribute of files goes away. [done] * Use ``except E1, E2, E3 as err:`` if you want the error variable. [3]_ * ``None`` becomes a keyword [4]_ (What about ``True``, ``False``?) * ``...`` to become a general expression element [16]_ [done] From python-checkins at python.org Sat Feb 10 02:17:30 2007 From: python-checkins at python.org (collin.winter) Date: Sat, 10 Feb 2007 02:17:30 +0100 (CET) Subject: [Python-checkins] r53722 - peps/trunk/pep-3100.txt Message-ID: <20070210011730.2E32F1E4012@bag.python.org> Author: collin.winter Date: Sat Feb 10 02:17:29 2007 New Revision: 53722 Modified: peps/trunk/pep-3100.txt Log: Add sys.exc_clear for removal Modified: peps/trunk/pep-3100.txt ============================================================================== --- peps/trunk/pep-3100.txt (original) +++ peps/trunk/pep-3100.txt Sat Feb 10 02:17:29 2007 @@ -218,6 +218,8 @@ * ``sys.exc_type``, ``sys.exc_values``, ``sys.exc_traceback``: not thread-safe; use ``sys.exc_info()`` or an attribute of the exception [2]_ [11]_ [#sys-module]_ +* ``sys.exc_clear``: Python 3's except statements provide the same + functionality [24]_ [#pep3110]_ [#sys-module]_ * ``array.read``, ``array.write`` [#array-module]_ * ``operator.isCallable`` : ``callable()`` built-in is being removed [#operator-module]_ @@ -312,6 +314,9 @@ .. [23] python-3000 email ("__nonzero__ vs. __bool__") http://mail.python.org/pipermail/python-3000/2006-November/004524.html + +.. [24] python-3000 email ("Pre-peps on raise and except changes") + http://mail.python.org/pipermail/python-3000/2007-February/005672.html .. [#sys-module] Python docs (sys -- System-specific parameters and functions) http://docs.python.org/lib/module-sys.html @@ -363,6 +368,9 @@ .. [#pep3107] PEP 3107 (Function Annotations) http://www.python.org/dev/peps/pep-3107 + +.. [#pep3110] PEP 3110 (Catching Exceptions in Python 3000) + http://www.python.org/dev/peps/pep-3110/#semantic-changes Copyright From buildbot at python.org Sat Feb 10 19:42:19 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 10 Feb 2007 18:42:19 +0000 Subject: [Python-checkins] buildbot failure in g4 osx.4 2.5 Message-ID: <20070210184219.C6E141E4003@bag.python.org> The Buildbot has detected a new failure of g4 osx.4 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/g4%2520osx.4%25202.5/builds/210 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Dominick': Gannon Build Source Stamp: [branch Hugo] Silas Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Sat Feb 10 19:42:43 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 10 Feb 2007 18:42:43 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 2.5 Message-ID: <20070210184243.77EEE1E4003@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%2520solaris10%2520gcc%25202.5/builds/215 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Ezra': Erik Build Source Stamp: [branch Nathan] Kendell Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Sat Feb 10 19:45:11 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 10 Feb 2007 18:45:11 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.5 Message-ID: <20070210184511.4EF161E4003@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520gentoo%25202.5/builds/222 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Omari': Teddy Build Source Stamp: [branch Zechariah] Shaun Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Sat Feb 10 19:47:46 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 10 Feb 2007 18:47:46 +0000 Subject: [Python-checkins] buildbot failure in x86 XP 2.5 Message-ID: <20070210184751.28BA91E4003@bag.python.org> The Buildbot has detected a new failure of x86 XP 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520XP%25202.5/builds/111 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Peyton': Isiah Build Source Stamp: [branch Darien] Addison Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Sat Feb 10 19:53:42 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 10 Feb 2007 18:53:42 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 2.5 Message-ID: <20070210185342.2C7BC1E4003@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%2520gentoo%25202.5/builds/224 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'London': Donta Build Source Stamp: [branch Michel] Dana Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From python-checkins at python.org Sat Feb 10 20:38:59 2007 From: python-checkins at python.org (guido.van.rossum) Date: Sat, 10 Feb 2007 20:38:59 +0100 (CET) Subject: [Python-checkins] r53725 - sandbox/trunk/2to3/refactor.py Message-ID: <20070210193859.B53A01E4004@bag.python.org> Author: guido.van.rossum Date: Sat Feb 10 20:38:59 2007 New Revision: 53725 Modified: sandbox/trunk/2to3/refactor.py Log: Add -p option which assumes print() is a function, not a keyword. Modified: sandbox/trunk/2to3/refactor.py ============================================================================== --- sandbox/trunk/2to3/refactor.py (original) +++ sandbox/trunk/2to3/refactor.py Sat Feb 10 20:38:59 2007 @@ -47,6 +47,8 @@ help="Each FIX specifies a transformation; default all") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations (fixes/fix_*.py)") + parser.add_option("-p", "--print-function", action="store_true", + help="Modify the grammar so that print() is a function") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("-w", "--write", action="store_true", @@ -99,6 +101,8 @@ self.options = options self.errors = [] self.logger = logging.getLogger("RefactoringTool") + if self.options.print_function: + del pygram.python_grammar.keywords["print"] self.driver = driver.Driver(pygram.python_grammar, convert=pytree.convert, logger=self.logger) From python-checkins at python.org Sat Feb 10 22:23:31 2007 From: python-checkins at python.org (guido.van.rossum) Date: Sat, 10 Feb 2007 22:23:31 +0100 (CET) Subject: [Python-checkins] r53726 - sandbox/trunk/2to3/fixer_tests.py Message-ID: <20070210212331.C9E831E4004@bag.python.org> Author: guido.van.rossum Date: Sat Feb 10 22:23:30 2007 New Revision: 53726 Modified: sandbox/trunk/2to3/fixer_tests.py Log: Need to set options.print_function to make the tests pass now. Modified: sandbox/trunk/2to3/fixer_tests.py ============================================================================== --- sandbox/trunk/2to3/fixer_tests.py (original) +++ sandbox/trunk/2to3/fixer_tests.py Sat Feb 10 22:23:30 2007 @@ -37,7 +37,7 @@ class FixerTestCase(unittest.TestCase): def setUp(self): - options = Options(fix=[self.fixer]) + options = Options(fix=[self.fixer], print_function=False) self.refactor = refactor.RefactoringTool(options) self.logging_stream = StringIO() From buildbot at python.org Sun Feb 11 00:46:14 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 10 Feb 2007 23:46:14 +0000 Subject: [Python-checkins] buildbot failure in x86 OpenBSD 2.5 Message-ID: <20070210234614.355A61E4004@bag.python.org> The Buildbot has detected a new failure of x86 OpenBSD 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520OpenBSD%25202.5/builds/203 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Destin': Rasheed Build Source Stamp: [branch Tucker] Shane Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From python-checkins at python.org Sun Feb 11 00:52:29 2007 From: python-checkins at python.org (guido.van.rossum) Date: Sun, 11 Feb 2007 00:52:29 +0100 (CET) Subject: [Python-checkins] r53728 - sandbox/trunk/2to3/fixes/fix_dict2.py Message-ID: <20070210235229.F24501E4027@bag.python.org> Author: guido.van.rossum Date: Sun Feb 11 00:52:29 2007 New Revision: 53728 Added: sandbox/trunk/2to3/fixes/fix_dict2.py (contents, props changed) Log: Add a much simpler dict refactorer, which is less safe but more practical. Added: sandbox/trunk/2to3/fixes/fix_dict2.py ============================================================================== --- (empty file) +++ sandbox/trunk/2to3/fixes/fix_dict2.py Sun Feb 11 00:52:29 2007 @@ -0,0 +1,36 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. + +"""Fixer for dict methods, take 2. + +This is less correct but more pragmatic. + +.iterkeys -> .keys +.iteritems -> .items +.itervalues -> .values +""" + +# Python imports +import token + +# Local imports +import pytree +from fixes import basefix +from fixes import macros + +class FixDict2(basefix.BaseFix): + + PATTERN = """ + trailer< '.' method=('iterkeys'|'iteritems'|'itervalues') > + """ + + def transform(self, node): + results = self.match(node) + method = results["method"][0].value # Extract method name + assert method.startswith("iter") + newmethod = method[4:] + new = pytree.Node(self.syms.trailer, + [pytree.Leaf(token.DOT, '.'), + macros.Name(newmethod)]) + new.set_prefix(node.get_prefix()) + new.children[1].set_prefix(node.children[1].get_prefix()) + return new From python-checkins at python.org Sun Feb 11 01:18:47 2007 From: python-checkins at python.org (guido.van.rossum) Date: Sun, 11 Feb 2007 01:18:47 +0100 (CET) Subject: [Python-checkins] r53729 - in sandbox/trunk/2to3: Grammar.txt pgen2/grammar.py refactor.py tokenize.py Message-ID: <20070211001847.6FB3F1E4004@bag.python.org> Author: guido.van.rossum Date: Sun Feb 11 01:18:46 2007 New Revision: 53729 Modified: sandbox/trunk/2to3/Grammar.txt sandbox/trunk/2to3/pgen2/grammar.py sandbox/trunk/2to3/refactor.py sandbox/trunk/2to3/tokenize.py Log: Tweaks to the grammar and tokenizer to support parsing Py3k source code. This has become necessary now that I'm converting the stdelib one fix at a time. Modified: sandbox/trunk/2to3/Grammar.txt ============================================================================== --- sandbox/trunk/2to3/Grammar.txt (original) +++ sandbox/trunk/2to3/Grammar.txt Sun Feb 11 01:18:46 2007 @@ -33,13 +33,20 @@ decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE decorators: decorator+ -funcdef: [decorators] 'def' NAME parameters ':' suite -parameters: '(' [varargslist] ')' -varargslist: ((fpdef ['=' test] ',')* - ('*' NAME [',' '**' NAME] | '**' NAME) | - fpdef ['=' test] (',' fpdef ['=' test])* [',']) -fpdef: NAME | '(' fplist ')' -fplist: fpdef (',' fpdef)* [','] +funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite +parameters: '(' [typedargslist] ')' +typedargslist: ((tfpdef ['=' test] ',')* + ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname) + | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) +tname: NAME [':' test] +tfpdef: tname | '(' tfplist ')' +tfplist: tfpdef (',' tfpdef)* [','] +varargslist: ((vfpdef ['=' test] ',')* + ('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname) + | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) +vname: NAME +vfpdef: vname | '(' vfplist ')' +vfplist: vfpdef (',' vfpdef)* [','] stmt: simple_stmt | compound_stmt simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE @@ -113,19 +120,19 @@ power: atom trailer* ['**' factor] atom: ('(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']' | - '{' [dictmaker] '}' | + '{' [dictsetmaker] '}' | '`' testlist1 '`' | - NAME | NUMBER | STRING+) + NAME | NUMBER | STRING+ | '.' '.' '.') listmaker: test ( list_for | (',' test)* [','] ) testlist_gexp: test ( gen_for | (',' test)* [','] ) lambdef: 'lambda' [varargslist] ':' test trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] -subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop] +subscript: test | [test] ':' [test] [sliceop] sliceop: ':' [test] exprlist: expr (',' expr)* [','] testlist: test (',' test)* [','] -dictmaker: test ':' test (',' test ':' test)* [','] +dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [',']) classdef: 'class' NAME ['(' [testlist] ')'] ':' suite Modified: sandbox/trunk/2to3/pgen2/grammar.py ============================================================================== --- sandbox/trunk/2to3/pgen2/grammar.py (original) +++ sandbox/trunk/2to3/pgen2/grammar.py Sun Feb 11 01:18:46 2007 @@ -158,6 +158,7 @@ **= DOUBLESTAREQUAL // DOUBLESLASH //= DOUBLESLASHEQUAL +-> RARROW """ opmap = {} Modified: sandbox/trunk/2to3/refactor.py ============================================================================== --- sandbox/trunk/2to3/refactor.py (original) +++ sandbox/trunk/2to3/refactor.py Sun Feb 11 01:18:46 2007 @@ -20,13 +20,13 @@ import logging # Local imports +import tokenize import pytree import patcomp from pgen2 import driver import fixes import fixes.macros import pygram -import tokenize logging.basicConfig(format='%(name)s: %(message)s', level=logging.INFO) Modified: sandbox/trunk/2to3/tokenize.py ============================================================================== --- sandbox/trunk/2to3/tokenize.py (original) +++ sandbox/trunk/2to3/tokenize.py Sun Feb 11 01:18:46 2007 @@ -36,13 +36,17 @@ __all__ = [x for x in dir(token) if x[0] != '_'] + ["COMMENT", "tokenize", "generate_tokens", "NL", "untokenize"] del x -del token COMMENT = N_TOKENS tok_name[COMMENT] = 'COMMENT' NL = N_TOKENS + 1 tok_name[NL] = 'NL' -N_TOKENS += 2 +RARROW = N_TOKENS + 2 +token.RARROW = RARROW +tok_name[RARROW] = 'RARROW' +N_TOKENS += 3 + +del token def group(*choices): return '(' + '|'.join(choices) + ')' def any(*choices): return group(*choices) + '*' @@ -81,7 +85,7 @@ # longest operators first (e.g., if = came before ==, == would get # recognized as two instances of =). Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=", - r"//=?", + r"//=?", r"->", r"[+\-*/%&|^=<>]=?", r"~") From python-checkins at python.org Sun Feb 11 01:35:37 2007 From: python-checkins at python.org (guido.van.rossum) Date: Sun, 11 Feb 2007 01:35:37 +0100 (CET) Subject: [Python-checkins] r53730 - in sandbox/trunk/2to3: example.py fixes/fix_xrange.py Message-ID: <20070211003537.645A51E4004@bag.python.org> Author: guido.van.rossum Date: Sun Feb 11 01:35:36 2007 New Revision: 53730 Added: sandbox/trunk/2to3/fixes/fix_xrange.py (contents, props changed) Modified: sandbox/trunk/2to3/example.py Log: Add a converter that turns xrange() calls into range() calls. (Still waiting for Neal to implement the new range() :-). Modified: sandbox/trunk/2to3/example.py ============================================================================== --- sandbox/trunk/2to3/example.py (original) +++ sandbox/trunk/2to3/example.py Sun Feb 11 01:35:36 2007 @@ -311,4 +311,9 @@ # print h.keys()[0] +def xrange_examples(): + for i in xrange(100): print i + for i in xrange(0, 100): print i + for i in xrange(0, 100, 10): print i + # This is the last line. Added: sandbox/trunk/2to3/fixes/fix_xrange.py ============================================================================== --- (empty file) +++ sandbox/trunk/2to3/fixes/fix_xrange.py Sun Feb 11 01:35:36 2007 @@ -0,0 +1,28 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. + +"""Fixer that changes xrange(...) into range(...).""" + +# Python imports +import token + +# Local imports +import pytree +from fixes import basefix +from fixes import macros + +class FixXrange(basefix.BaseFix): + + PATTERN = """ + power< + 'xrange' + args=trailer< '(' [any] ')' > + > + """ + + def transform(self, node): + results = self.match(node) + args = results["args"] + new = pytree.Node(self.syms.power, + [macros.Name("range"), args.clone()]) + new.set_prefix(node.get_prefix()) + return new From python-checkins at python.org Sun Feb 11 06:36:01 2007 From: python-checkins at python.org (brett.cannon) Date: Sun, 11 Feb 2007 06:36:01 +0100 (CET) Subject: [Python-checkins] r53731 - python/trunk/Parser/Python.asdl Message-ID: <20070211053601.A06771E401F@bag.python.org> Author: brett.cannon Date: Sun Feb 11 06:36:00 2007 New Revision: 53731 Modified: python/trunk/Parser/Python.asdl Log: Change a very minor inconsistency (that is purely cosmetic) in the AST definition. Modified: python/trunk/Parser/Python.asdl ============================================================================== --- python/trunk/Parser/Python.asdl (original) +++ python/trunk/Parser/Python.asdl Sun Feb 11 06:36:00 2007 @@ -75,7 +75,7 @@ | Subscript(expr value, slice slice, expr_context ctx) | Name(identifier id, expr_context ctx) | List(expr* elts, expr_context ctx) - | Tuple(expr *elts, expr_context ctx) + | Tuple(expr* elts, expr_context ctx) -- col_offset is the byte offset in the utf8 string the parser uses attributes (int lineno, int col_offset) From python-checkins at python.org Sun Feb 11 08:03:45 2007 From: python-checkins at python.org (guido.van.rossum) Date: Sun, 11 Feb 2007 08:03:45 +0100 (CET) Subject: [Python-checkins] r53733 - in sandbox/trunk/2to3: example.py fixer_tests.py fixes/fix_dict.py Message-ID: <20070211070345.1B3111E4008@bag.python.org> Author: guido.van.rossum Date: Sun Feb 11 08:03:43 2007 New Revision: 53733 Modified: sandbox/trunk/2to3/example.py sandbox/trunk/2to3/fixer_tests.py sandbox/trunk/2to3/fixes/fix_dict.py Log: Make the dict fixer handle a "tail", e.g. d.keys()[0]. Modified: sandbox/trunk/2to3/example.py ============================================================================== --- sandbox/trunk/2to3/example.py (original) +++ sandbox/trunk/2to3/example.py Sun Feb 11 08:03:43 2007 @@ -299,6 +299,13 @@ for i in g.iterkeys(): print i [i for i in g.iterkeys()] (i for i in g.iterkeys()) + # + # Examples with a "tail"; these are never "special" + # + print h.iterkeys().next() + print h.keys()[0] + print list(h.iterkeys().next()) + for x in h.keys()[0]: print x def dict_negative_examples(): # @@ -306,10 +313,6 @@ # print list(h.keys()) print sorted(h.keys()) - # - # This should be left unchanged and trigger a warning: - # - print h.keys()[0] def xrange_examples(): for i in xrange(100): print i Modified: sandbox/trunk/2to3/fixer_tests.py ============================================================================== --- sandbox/trunk/2to3/fixer_tests.py (original) +++ sandbox/trunk/2to3/fixer_tests.py Sun Feb 11 08:03:43 2007 @@ -1020,6 +1020,27 @@ a = "foo(iter(d.keys()))" self.check(b, a) + def test_21(self): + b = "print h.iterkeys().next()" + a = "print iter(h.keys()).next()" + self.check(b, a) + + def test_22(self): + b = "print h.keys()[0]" + a = "print list(h.keys())[0]" + self.check(b, a) + + def test_23(self): + b = "print list(h.iterkeys().next())" + a = "print list(iter(h.keys()).next())" + self.check(b, a) + + def test_24(self): + b = "for x in h.keys()[0]: print x" + a = "for x in list(h.keys())[0]: print x" + self.check(b, a) + + if __name__ == "__main__": import sys Modified: sandbox/trunk/2to3/fixes/fix_dict.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_dict.py (original) +++ sandbox/trunk/2to3/fixes/fix_dict.py Sun Feb 11 08:03:43 2007 @@ -33,7 +33,7 @@ class FixDict(basefix.BaseFix): PATTERN = """ - power< prefix=any+ + power< head=any+ trailer< '.' method=('keys'|'items'|'values'| 'iterkeys'|'iteritems'|'itervalues') > trailer< '(' ')' > @@ -43,28 +43,29 @@ def transform(self, node): results = self.match(node) - prefix = results["prefix"] + head = results["head"] method = results["method"][0].value # Extract method name tail = results["tail"] - if tail: - return self.cannot_convert(node, - "stuff after .[iter]keys() etc. unsupported") syms = self.syms isiter = method.startswith("iter") if isiter: method = method[4:] assert method in ("keys", "items", "values"), repr(method) - prefix = [n.clone() for n in prefix] - new = pytree.Node(syms.power, - prefix + [pytree.Node(syms.trailer, - [pytree.Leaf(token.DOT, '.'), - macros.Name(method)]), - pytree.Node(syms.trailer, - [macros.lparen_leaf.clone(), - macros.rparen_leaf.clone()])]) - if not self.in_special_context(node, isiter): + head = [n.clone() for n in head] + tail = [n.clone() for n in tail] + special = not tail and self.in_special_context(node, isiter) + args = head + [pytree.Node(syms.trailer, + [pytree.Leaf(token.DOT, '.'), + macros.Name(method)]), + pytree.Node(syms.trailer, + [macros.lparen_leaf.clone(), + macros.rparen_leaf.clone()])] + new = pytree.Node(syms.power, args) + if not special: new.set_prefix("") new = macros.Call(macros.Name(isiter and "iter" or "list"), [new]) + if tail: + new = pytree.Node(syms.power, [new] + tail) new.set_prefix(node.get_prefix()) return new From buildbot at python.org Sun Feb 11 08:30:07 2007 From: buildbot at python.org (buildbot at python.org) Date: Sun, 11 Feb 2007 07:30:07 +0000 Subject: [Python-checkins] buildbot warnings in ia64 Ubuntu trunk trunk Message-ID: <20070211073008.2D7C71E4008@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu trunk trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%2520Ubuntu%2520trunk%2520trunk/builds/381 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: brett.cannon,georg.brandl,martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_timeout make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sun Feb 11 08:40:33 2007 From: buildbot at python.org (buildbot at python.org) Date: Sun, 11 Feb 2007 07:40:33 +0000 Subject: [Python-checkins] buildbot warnings in x86 cygwin trunk Message-ID: <20070211074033.5A44E1E4008@bag.python.org> The Buildbot has detected a new failure of x86 cygwin trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520cygwin%2520trunk/builds/14 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: brett.cannon,georg.brandl,martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Sun Feb 11 19:24:38 2007 From: python-checkins at python.org (skip.montanaro) Date: Sun, 11 Feb 2007 19:24:38 +0100 (CET) Subject: [Python-checkins] r53735 - in python/trunk: Lib/trace.py Misc/NEWS Message-ID: <20070211182438.CC7ED1E400C@bag.python.org> Author: skip.montanaro Date: Sun Feb 11 19:24:37 2007 New Revision: 53735 Modified: python/trunk/Lib/trace.py python/trunk/Misc/NEWS Log: fix trace.py --ignore-dir Modified: python/trunk/Lib/trace.py ============================================================================== --- python/trunk/Lib/trace.py (original) +++ python/trunk/Lib/trace.py Sun Feb 11 19:24:37 2007 @@ -587,7 +587,7 @@ """ if why == 'call': code = frame.f_code - filename = code.co_filename + filename = frame.f_globals.get('__file__', None) if filename: # XXX modname() doesn't work right for packages, so # the ignore support won't work right for packages Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Feb 11 19:24:37 2007 @@ -128,6 +128,9 @@ Library ------- +- Patch 1571379: Make trace's --ignore-dir facility work in the face of + relative directory names. + - Bug #1600860: Search for shared python library in LIBDIR, not lib/python/config, on "linux" and "gnu" systems. From python-checkins at python.org Sun Feb 11 19:37:55 2007 From: python-checkins at python.org (skip.montanaro) Date: Sun, 11 Feb 2007 19:37:55 +0100 (CET) Subject: [Python-checkins] r53736 - in python/branches/release24-maint: Lib/trace.py Misc/NEWS Message-ID: <20070211183755.008DD1E400C@bag.python.org> Author: skip.montanaro Date: Sun Feb 11 19:37:54 2007 New Revision: 53736 Modified: python/branches/release24-maint/Lib/trace.py python/branches/release24-maint/Misc/NEWS Log: backport: fix trace.py --ignore-dir Modified: python/branches/release24-maint/Lib/trace.py ============================================================================== --- python/branches/release24-maint/Lib/trace.py (original) +++ python/branches/release24-maint/Lib/trace.py Sun Feb 11 19:37:54 2007 @@ -583,7 +583,7 @@ """ if why == 'call': code = frame.f_code - filename = code.co_filename + filename = frame.f_globals.get('__file__', None) if filename: # XXX modname() doesn't work right for packages, so # the ignore support won't work right for packages Modified: python/branches/release24-maint/Misc/NEWS ============================================================================== --- python/branches/release24-maint/Misc/NEWS (original) +++ python/branches/release24-maint/Misc/NEWS Sun Feb 11 19:37:54 2007 @@ -192,6 +192,9 @@ Library ------- +- Patch 1571379: Make trace's --ignore-dir facility work in the face of + relative directory names. + - Bug #1545341: The 'classifier' keyword argument to the Distutils setup() function now accepts tuples as well as lists. From python-checkins at python.org Sun Feb 11 19:41:56 2007 From: python-checkins at python.org (skip.montanaro) Date: Sun, 11 Feb 2007 19:41:56 +0100 (CET) Subject: [Python-checkins] r53737 - in python/branches/release25-maint: Lib/trace.py Misc/NEWS Message-ID: <20070211184156.AF2311E400C@bag.python.org> Author: skip.montanaro Date: Sun Feb 11 19:41:56 2007 New Revision: 53737 Modified: python/branches/release25-maint/Lib/trace.py python/branches/release25-maint/Misc/NEWS Log: backport: fix trace.py --ignore-dir Modified: python/branches/release25-maint/Lib/trace.py ============================================================================== --- python/branches/release25-maint/Lib/trace.py (original) +++ python/branches/release25-maint/Lib/trace.py Sun Feb 11 19:41:56 2007 @@ -587,7 +587,7 @@ """ if why == 'call': code = frame.f_code - filename = code.co_filename + filename = frame.f_globals.get('__file__', None) if filename: # XXX modname() doesn't work right for packages, so # the ignore support won't work right for packages Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Sun Feb 11 19:41:56 2007 @@ -169,6 +169,9 @@ Library ------- +- Patch 1571379: Make trace's --ignore-dir facility work in the face of + relative directory names. + - Bug #1600860: Search for shared python library in LIBDIR, not lib/python/config, on "linux" and "gnu" systems. From python-checkins at python.org Sun Feb 11 20:44:42 2007 From: python-checkins at python.org (brett.cannon) Date: Sun, 11 Feb 2007 20:44:42 +0100 (CET) Subject: [Python-checkins] r53741 - python/trunk/Python/Python-ast.c Message-ID: <20070211194442.4233C1E400C@bag.python.org> Author: brett.cannon Date: Sun Feb 11 20:44:41 2007 New Revision: 53741 Modified: python/trunk/Python/Python-ast.c Log: Check in changed Python-ast.c from a cosmetic change to Python.asdl (in r53731). Modified: python/trunk/Python/Python-ast.c ============================================================================== --- python/trunk/Python/Python-ast.c (original) +++ python/trunk/Python/Python-ast.c Sun Feb 11 20:44:41 2007 @@ -3048,7 +3048,7 @@ if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return; if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0) return; - if (PyModule_AddStringConstant(m, "__version__", "43614") < 0) + if (PyModule_AddStringConstant(m, "__version__", "53731") < 0) return; if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return; if (PyDict_SetItemString(d, "Module", (PyObject*)Module_type) < 0) From buildbot at python.org Sun Feb 11 20:53:50 2007 From: buildbot at python.org (buildbot at python.org) Date: Sun, 11 Feb 2007 19:53:50 +0000 Subject: [Python-checkins] buildbot warnings in x86 Ubuntu edgy (icc) trunk Message-ID: <20070211195350.847A61E400C@bag.python.org> The Buildbot has detected a new failure of x86 Ubuntu edgy (icc) trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520Ubuntu%2520edgy%2520%2528icc%2529%2520trunk/builds/1177 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: skip.montanaro Build had warnings: warnings test Excerpt from the test logfile: 2 tests failed: test_timeout test_urllib2net ====================================================================== FAIL: testConnectTimeout (test.test_timeout.TimeoutTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/test/test_timeout.py", line 128, in testConnectTimeout %(_delta, self.fuzz, _timeout)) AssertionError: timeout (2.74149) is more than 2 seconds more than expected (0.001) sincerely, -The Buildbot From buildbot at python.org Sun Feb 11 22:14:05 2007 From: buildbot at python.org (buildbot at python.org) Date: Sun, 11 Feb 2007 21:14:05 +0000 Subject: [Python-checkins] buildbot warnings in x86 Ubuntu edgy (icc) 2.5 Message-ID: <20070211211405.D1E941E400C@bag.python.org> The Buildbot has detected a new failure of x86 Ubuntu edgy (icc) 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520Ubuntu%2520edgy%2520%2528icc%2529%25202.5/builds/160 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: georg.brandl,martin.v.loewis,skip.montanaro Build had warnings: warnings test Excerpt from the test logfile: 2 tests failed: test_timeout test_urllibnet ====================================================================== FAIL: testConnectTimeout (test.test_timeout.TimeoutTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/Buildbot/2.5.baxter-ubuntu/build/Lib/test/test_timeout.py", line 128, in testConnectTimeout %(_delta, self.fuzz, _timeout)) AssertionError: timeout (2.36012) is more than 2 seconds more than expected (0.001) sincerely, -The Buildbot From python-checkins at python.org Mon Feb 12 00:50:58 2007 From: python-checkins at python.org (david.goodger) Date: Mon, 12 Feb 2007 00:50:58 +0100 (CET) Subject: [Python-checkins] r53744 - peps/trunk/pep-0000.txt peps/trunk/pep-0363.txt Message-ID: <20070211235058.C060F1E400C@bag.python.org> Author: david.goodger Date: Mon Feb 12 00:50:57 2007 New Revision: 53744 Added: peps/trunk/pep-0363.txt (contents, props changed) Modified: peps/trunk/pep-0000.txt Log: added PEP 363 "Syntax For Dynamic Attribute Access" by Ben North Modified: peps/trunk/pep-0000.txt ============================================================================== --- peps/trunk/pep-0000.txt (original) +++ peps/trunk/pep-0000.txt Mon Feb 12 00:50:57 2007 @@ -98,6 +98,7 @@ S 355 Path - Object oriented filesystem paths Lindqvist S 358 The "bytes" Object Schemenauer S 362 Function Signature Object Cannon, Seo + S 363 Syntax For Dynamic Attribute Access North S 754 IEEE 754 Floating Point Special Values Warnes S 3101 Advanced String Formatting Talin S 3102 Keyword-Only Arguments Talin @@ -434,6 +435,7 @@ I 360 Externally Maintained Packages Cannon I 361 Python 2.6 Release Schedule Norwitz, et al S 362 Function Signature Object Cannon, Seo + S 363 Syntax For Dynamic Attribute Access North SR 666 Reject Foolish Indentation Creighton S 754 IEEE 754 Floating Point Special Values Warnes P 3000 Python 3000 GvR @@ -530,6 +532,7 @@ Meyer, Mike mwm at mired.org Montanaro, Skip skip at pobox.com Moore, Paul gustav at morpheus.demon.co.uk + North, Ben ben at redfrontdoor.org Norwitz, Neal nnorwitz at gmail.com Oliphant, Travis oliphant at ee.byu.edu Pedroni, Samuele pedronis at python.org Added: peps/trunk/pep-0363.txt ============================================================================== --- (empty file) +++ peps/trunk/pep-0363.txt Mon Feb 12 00:50:57 2007 @@ -0,0 +1,272 @@ +PEP: 363 +Title: Syntax For Dynamic Attribute Access +Version: $Revision$ +Last-Modified: $Date$ +Author: Ben North +Status: Draft +Type: Standards Track +Content-Type: text/plain +Created: 29-Jan-2007 +Post-History: + + +Abstract + + Dynamic attribute access is currently possible using the "getattr" + and "setattr" builtins. The present PEP suggests a new syntax to + make such access easier, allowing the coder for example to write + + x.('foo_%d' % n) += 1 + + z = y.('foo_%d' % n).('bar_%s' % s) + + instead of + + attr_name = 'foo_%d' % n + setattr(x, attr_name, getattr(x, attr_name) + 1) + + z = getattr(getattr(y, 'foo_%d' % n), 'bar_%s' % s) + + +Note + + I wrote this patch mostly to advance my own understanding of and + experiment with the python language, but I've written it up in the + style of a PEP in case it might be a useful idea. + + +Rationale + + Dictionary access and indexing both have a friendly invocation + syntax: instead of x.__getitem__(12) the coder can write x[12]. + This also allows the use of subscripted elements in an augmented + assignment, as in "x[12] += 1". The present proposal brings this + ease-of-use to dynamic attribute access too. + + Attribute access is currently possible in two ways: + + * When the attribute name is known at code-writing time, the + ".NAME" trailer can be used, as in + + x.foo = 42 + y.bar += 100 + + * When the attribute name is computed dynamically at run-time, the + "getattr" and "setattr" builtins must be used: + + x = getattr(y, 'foo_%d' % n) + setattr(z, 'bar_%s' % s, 99) + + The "getattr" builtin also allows the coder to specify a default + value to be returned in the event that the object does not have + an attribute of the given name: + + x = getattr(y, 'foo_%d' % n, 0) + + This PEP describes a new syntax for dynamic attribute access --- + "x.(expr)" --- with examples given in the Abstract above. The new + syntax also allows the provision of a default value in the "get" + case, as in: + + x = y.('foo_%d' % n, None) + + This 2-argument form of dynamic attribute access is not permitted as + the target of an (augmented or normal) assignment. Also, this part + of the new syntax was not as well received [6] in initial + discussions on python-ideas, and I agree that it does not fit so + cleanly. I'm happy to prepare a revised PEP/patch without the + 2-argument form if the consensus is that this would be preferred. + + Finally, the new syntax can be used with the "del" statement, as in + + del x.(attr_name) + + +Impact On Existing Code + + The proposed new syntax is not currently valid, so no existing + well-formed programs have their meaning altered by this proposal. + + Across all "*.py" files in the 2.5 distribution, there are around + 600 uses of "getattr", "setattr" or "delattr". They break down as + follows (figures have some room for error because they were + arrived at by partially-manual inspection): + + c.300 uses of plain "getattr(x, attr_name)", which could be + replaced with the new syntax; + + c.150 uses of the 3-argument form, i.e., with the default + value; these could be replaced with the 2-argument form + of the new syntax (the cases break down into c.125 cases + where the attribute name is a literal string, and c.25 + where it's only known at run-time); + + c.5 uses of the 2-argument form with a literal string + attribute name, which I think could be replaced with the + standard "x.attribute" syntax; + + c.120 uses of setattr, of which 15 use getattr to find the + new value; all could be replaced with the new syntax, + the 15 where getattr is also involved would show a + particular increase in clarity; + + c.5 uses which would have to stay as "getattr" because they + are calls of a variable named "getattr" whose default + value is the builtin "getattr"; + + c.5 uses of the 2-argument form, inside a try/except block + which catches AttributeError and uses a default value + instead; these could use 2-argument form of the new + syntax; + + c.10 uses of "delattr", which could use the new syntax. + + As examples, the line + + setattr(self, attr, change_root(self.root, getattr(self, attr))) + + from Lib/distutils/command/install.py could be rewritten + + self.(attr) = change_root(self.root, self.(attr)) + + and the line + + setattr(self, method_name, getattr(self.metadata, method_name)) + + from Lib/distutils/dist.py could be rewritten + + self.(method_name) = self.metadata.(method_name) + + +Performance Impact + + Initial pystone measurements are inconclusive, but suggest there may + be a performance penalty of around 1% in the pystones score with the + patched version. One suggestion is that this is because the longer + main loop in ceval.c hurts the cache behaviour, but this has not + been confirmed. (Maybe a tool like valgrind [2] could help here?) + + On the other hand, measurements suggest a speed-up of around 40--45% + for dynamic attribute access. + + +Discussion To Date + + Initial posting of this PEP in draft form was to python-ideas on + 20070209 [4], and the response was generally positive: + + I've thought of the same syntax. I think you should submit this + to the PEP editor and argue on Python-dev for its inclusion in + Python 2.6 -- there's no benefit that I see of waiting until + 3.0. --- Guido van Rossum [5] + + Wow! I have to say this is a compelling idea. The syntax is a + bit foreign looking, but [...] I feel like I could learn to like + it anyway. --- Greg Falcon [6] + + I look forward to seeing this in Python 2.6. --- Josiah + Carlson, further down the thread [8] + + with Greg Falcon expressing the reservations about the 2-argument + form already noted above, and Josiah Carlson raising a query about + performance: + + My only concern with your propsed change is your draft + implementation. [...] Specifically, your changes [...] may + negatively affect general Python performance. --- Josiah + Carlson [7] + + Some initial measurements (see above) suggest the performance + penalty is small, and Josiah Carlson said of such cost that it + "isn't really substantial". [8] + + +Questions To Be Resolved + + * Whether to allow the 2-argument form for default arguments. + + * Whether the performance impact is real; whether it is acceptable; + whether alternative implementations might improve this aspect. + + +Alternative Syntax For The New Feature + + Other syntaxes could be used, for example braces are currently + invalid in a "trailer", so could be used here, giving + + x{'foo_%d' % n} += 1 + + My personal preference is for the + + x.('foo_%d' % n) += 1 + + syntax though: the presence of the dot shows there is attribute + access going on; the parentheses have an analogous meaning to the + mathematical "work this out first" meaning. This is also the + syntax used in the language Matlab [1] for dynamic "field" access + (where "field" is the Matlab term analogous to Python's + "attribute"). + + Discussions on python-ideas (see above) made no comment on the brace + alternative, and the .() notation was well-enough received, so the + brace alternative should be considered rejected, I think. + + +Error Cases + + Only strings are permitted as attribute names, so for instance the + following error is produced: + + >>> x.(99) = 8 + Traceback (most recent call last): + File "", line 1, in + TypeError: attribute name must be string, not 'int' + + This is handled by the existing PyObject_GetAttr function. + + +Draft Implementation + + A draft implementation adds a new alternative to the "trailer" + clause in Grammar/Grammar; a new AST type, "DynamicAttribute" in + Python.asdl, with accompanying changes to symtable.c, ast.c, and + compile.c, and three new opcodes (load/store/del) with + accompanying changes to opcode.h and ceval.c. The patch consists + of c.180 additional lines in the core code, and c.100 additional + lines of tests. It is available as sourceforge patch #1657573 [3]. + + +References + + [1] Using Dynamic Field Names :: Data Types (MATLAB Programming) + http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_prog/f2-41859.html + + [2] Valgrind: "suite of tools for debugging and profiling Linux programs" + http://www.valgrind.org/ + + [3] Sourceforge patch #1657573 + http://sourceforge.net/tracker/index.php?func=detail&aid=1657573&group_id=5470&atid=305470 + + [4] http://mail.python.org/pipermail/python-ideas/2007-February/000210.html + + [5] http://mail.python.org/pipermail/python-ideas/2007-February/000211.html + + [6] http://mail.python.org/pipermail/python-ideas/2007-February/000212.html + + [7] http://mail.python.org/pipermail/python-ideas/2007-February/000213.html + + [8] http://mail.python.org/pipermail/python-ideas/2007-February/000227.html + + +Copyright + + This document has been placed in the public domain. + + +Local Variables: +mode: indented-text +indent-tabs-mode: nil +sentence-end-double-space: t +fill-column: 70 +coding: utf-8 +End: From python-checkins at python.org Mon Feb 12 01:00:19 2007 From: python-checkins at python.org (collin.winter) Date: Mon, 12 Feb 2007 01:00:19 +0100 (CET) Subject: [Python-checkins] r53745 - sandbox/trunk/2to3/fixer_tests.py Message-ID: <20070212000019.CA8531E4017@bag.python.org> Author: collin.winter Date: Mon Feb 12 01:00:19 2007 New Revision: 53745 Modified: sandbox/trunk/2to3/fixer_tests.py Log: Make Test_except actually run; fix related transformation errors Modified: sandbox/trunk/2to3/fixer_tests.py ============================================================================== --- sandbox/trunk/2to3/fixer_tests.py (original) +++ sandbox/trunk/2to3/fixer_tests.py Mon Feb 12 01:00:19 2007 @@ -4,6 +4,7 @@ # Python imports from StringIO import StringIO +import re import unittest import logging @@ -11,6 +12,15 @@ import pytree import refactor +skip_whitespace = re.compile(r"""\S""") + +def reformat(string): + indent = re.search(skip_whitespace, string).start() + if indent == 0: + code = string + else: + code = "\n".join(line[indent-1:] for line in string.split("\n")[1:]) + return code + "\n\n" # We wrap the RefactoringTool's fixer objects so we can intercept # the call to set_filename() and so modify the fixers' logging objects. @@ -46,8 +56,8 @@ self.refactor.fixers = [Fixer(f, sh) for f in self.refactor.fixers] def check(self, before, after): - before += "\n" - after += "\n" + before = reformat(before) + after = reformat(after) refactored = self.refactor_stream("", StringIO(before)) self.failUnlessEqual(after, refactored) @@ -475,25 +485,28 @@ a = """x = repr((1, 2 + repr((3, 4))))""" self.check(b, a) -class Test_except(): +class Test_except(FixerTestCase): fixer = "except" def test_1(self): b = """ - try: - pass - except Exception, (f, e): - pass - except ImportError, e: - pass""" + def foo(): + try: + pass + except Exception, (f, e): + pass + except ImportError, e: + pass""" a = """ - try: - pass - except Exception as (f, e): - pass - except ImportError as e: - pass""" + def foo(): + try: + pass + except Exception as xxx_todo_changeme: + (f, e) = xxx_todo_changeme.message + pass + except ImportError as e: + pass""" self.check(b, a) def test_2(self): @@ -520,7 +533,8 @@ a = """ try: pass - except Exception as (a, b): + except Exception as xxx_todo_changeme1: + (a, b) = xxx_todo_changeme1.message pass""" self.check(b, a) @@ -534,8 +548,8 @@ a = """ try: pass - except Exception as xxx_todo_changeme: - d[5] = xxx_todo_changeme + except Exception as xxx_todo_changeme2: + d[5] = xxx_todo_changeme2 pass""" self.check(b, a) @@ -549,8 +563,8 @@ a = """ try: pass - except Exception as xxx_todo_changeme1: - a.foo = xxx_todo_changeme1 + except Exception as xxx_todo_changeme3: + a.foo = xxx_todo_changeme3 pass""" self.check(b, a) @@ -564,8 +578,8 @@ a = """ try: pass - except Exception as xxx_todo_changeme2: - a().foo = xxx_todo_changeme2 + except Exception as xxx_todo_changeme4: + a().foo = xxx_todo_changeme4 pass""" self.check(b, a) @@ -650,9 +664,9 @@ b = """def foo(): raise Exception, 5, 6""" a = """def foo(): - xxx_todo_changeme = Exception(5) - xxx_todo_changeme.__traceback__ = 6 - raise xxx_todo_changeme""" + xxx_todo_changeme5 = Exception(5) + xxx_todo_changeme5.__traceback__ = 6 + raise xxx_todo_changeme5""" self.check(b, a) def test_tb_2(self): @@ -662,9 +676,9 @@ b = 6""" a = """def foo(): a = 5 - xxx_todo_changeme1 = Exception(5) - xxx_todo_changeme1.__traceback__ = 6 - raise xxx_todo_changeme1 + xxx_todo_changeme6 = Exception(5) + xxx_todo_changeme6.__traceback__ = 6 + raise xxx_todo_changeme6 b = 6""" self.check(b, a) @@ -672,9 +686,9 @@ b = """def foo(): raise Exception,5,6""" a = """def foo(): - xxx_todo_changeme2 = Exception(5) - xxx_todo_changeme2.__traceback__ = 6 - raise xxx_todo_changeme2""" + xxx_todo_changeme7 = Exception(5) + xxx_todo_changeme7.__traceback__ = 6 + raise xxx_todo_changeme7""" self.check(b, a) def test_tb_4(self): @@ -684,9 +698,9 @@ b = 6""" a = """def foo(): a = 5 - xxx_todo_changeme3 = Exception(5) - xxx_todo_changeme3.__traceback__ = 6 - raise xxx_todo_changeme3 + xxx_todo_changeme8 = Exception(5) + xxx_todo_changeme8.__traceback__ = 6 + raise xxx_todo_changeme8 b = 6""" self.check(b, a) @@ -694,9 +708,9 @@ b = """def foo(): raise Exception, (5, 6, 7), 6""" a = """def foo(): - xxx_todo_changeme4 = Exception((5, 6, 7)) - xxx_todo_changeme4.__traceback__ = 6 - raise xxx_todo_changeme4""" + xxx_todo_changeme9 = Exception((5, 6, 7)) + xxx_todo_changeme9.__traceback__ = 6 + raise xxx_todo_changeme9""" self.check(b, a) def test_tb_6(self): @@ -706,9 +720,9 @@ b = 6""" a = """def foo(): a = 5 - xxx_todo_changeme5 = Exception((5, 6, 7)) - xxx_todo_changeme5.__traceback__ = 6 - raise xxx_todo_changeme5 + xxx_todo_changeme10 = Exception((5, 6, 7)) + xxx_todo_changeme10.__traceback__ = 6 + raise xxx_todo_changeme10 b = 6""" self.check(b, a) @@ -759,9 +773,9 @@ b = """def foo(): g.throw(Exception, 5, 6)""" a = """def foo(): - xxx_todo_changeme6 = Exception(5) - xxx_todo_changeme6.__traceback__ = 6 - g.throw(xxx_todo_changeme6)""" + xxx_todo_changeme11 = Exception(5) + xxx_todo_changeme11.__traceback__ = 6 + g.throw(xxx_todo_changeme11)""" self.check(b, a) def test_tb_2(self): @@ -771,9 +785,9 @@ b = 6""" a = """def foo(): a = 5 - xxx_todo_changeme7 = Exception(5) - xxx_todo_changeme7.__traceback__ = 6 - g.throw(xxx_todo_changeme7) + xxx_todo_changeme12 = Exception(5) + xxx_todo_changeme12.__traceback__ = 6 + g.throw(xxx_todo_changeme12) b = 6""" self.check(b, a) @@ -781,9 +795,9 @@ b = """def foo(): g.throw(Exception,5,6)""" a = """def foo(): - xxx_todo_changeme8 = Exception(5) - xxx_todo_changeme8.__traceback__ = 6 - g.throw(xxx_todo_changeme8)""" + xxx_todo_changeme13 = Exception(5) + xxx_todo_changeme13.__traceback__ = 6 + g.throw(xxx_todo_changeme13)""" self.check(b, a) def test_tb_4(self): @@ -793,9 +807,9 @@ b = 6""" a = """def foo(): a = 5 - xxx_todo_changeme9 = Exception(5) - xxx_todo_changeme9.__traceback__ = 6 - g.throw(xxx_todo_changeme9) + xxx_todo_changeme14 = Exception(5) + xxx_todo_changeme14.__traceback__ = 6 + g.throw(xxx_todo_changeme14) b = 6""" self.check(b, a) @@ -803,9 +817,9 @@ b = """def foo(): g.throw(Exception, (5, 6, 7), 6)""" a = """def foo(): - xxx_todo_changeme10 = Exception((5, 6, 7)) - xxx_todo_changeme10.__traceback__ = 6 - g.throw(xxx_todo_changeme10)""" + xxx_todo_changeme15 = Exception((5, 6, 7)) + xxx_todo_changeme15.__traceback__ = 6 + g.throw(xxx_todo_changeme15)""" self.check(b, a) def test_tb_6(self): @@ -815,9 +829,9 @@ b = 6""" a = """def foo(): a = 5 - xxx_todo_changeme11 = Exception((5, 6, 7)) - xxx_todo_changeme11.__traceback__ = 6 - g.throw(xxx_todo_changeme11) + xxx_todo_changeme16 = Exception((5, 6, 7)) + xxx_todo_changeme16.__traceback__ = 6 + g.throw(xxx_todo_changeme16) b = 6""" self.check(b, a) @@ -825,9 +839,9 @@ b = """def foo(): a + g.throw(Exception, 5, 6)""" a = """def foo(): - xxx_todo_changeme12 = Exception(5) - xxx_todo_changeme12.__traceback__ = 6 - a + g.throw(xxx_todo_changeme12)""" + xxx_todo_changeme17 = Exception(5) + xxx_todo_changeme17.__traceback__ = 6 + a + g.throw(xxx_todo_changeme17)""" self.check(b, a) def test_tb_8(self): @@ -837,9 +851,9 @@ b = 6""" a = """def foo(): a = 5 - xxx_todo_changeme13 = Exception(5) - xxx_todo_changeme13.__traceback__ = 6 - a + g.throw(xxx_todo_changeme13) + xxx_todo_changeme18 = Exception(5) + xxx_todo_changeme18.__traceback__ = 6 + a + g.throw(xxx_todo_changeme18) b = 6""" self.check(b, a) From python-checkins at python.org Mon Feb 12 04:00:06 2007 From: python-checkins at python.org (brett.cannon) Date: Mon, 12 Feb 2007 04:00:06 +0100 (CET) Subject: [Python-checkins] r53750 - peps/trunk/pep-0339.txt Message-ID: <20070212030006.9239C1E4004@bag.python.org> Author: brett.cannon Date: Mon Feb 12 04:00:05 2007 New Revision: 53750 Modified: peps/trunk/pep-0339.txt Log: Mention how Python/Python-ast.c must be committed separately after every change to the grammar as its __version__ value is set to the AST grammar's revision number. Modified: peps/trunk/pep-0339.txt ============================================================================== --- peps/trunk/pep-0339.txt (original) +++ peps/trunk/pep-0339.txt Mon Feb 12 04:00:05 2007 @@ -443,7 +443,9 @@ Creates C structs corresponding to the ASDL types. Also contains code for marshaling AST nodes (core ASDL types have marshaling code in asdl.c). "File automatically generated by - Parser/asdl_c.py". + Parser/asdl_c.py". This file must be committed separately + after every grammar change is committed since the __version__ + value is set to the latest grammar change revision number. - asdl.c Contains code to handle the ASDL sequence type. Also has code From python-checkins at python.org Mon Feb 12 04:51:03 2007 From: python-checkins at python.org (brett.cannon) Date: Mon, 12 Feb 2007 04:51:03 +0100 (CET) Subject: [Python-checkins] r53751 - in python/trunk: Include/Python-ast.h Parser/asdl_c.py Python/Python-ast.c Message-ID: <20070212035103.F36DE1E4004@bag.python.org> Author: brett.cannon Date: Mon Feb 12 04:51:02 2007 New Revision: 53751 Modified: python/trunk/Include/Python-ast.h python/trunk/Parser/asdl_c.py python/trunk/Python/Python-ast.c Log: Modify Parser/asdl_c.py so that the __version__ number for Python/Python-ast.c is specified at the top of the file. Also add a note that Python/Python-ast.c needs to be committed separately after a change to the AST grammar to capture the revision number of the change (which is what __version__ is set to). Modified: python/trunk/Include/Python-ast.h ============================================================================== --- python/trunk/Include/Python-ast.h (original) +++ python/trunk/Include/Python-ast.h Mon Feb 12 04:51:02 2007 @@ -1,4 +1,4 @@ -/* File automatically generated by Parser/asdl_c.py */ +/* File automatically generated by Parser/asdl_c.py. */ #include "asdl.h" Modified: python/trunk/Parser/asdl_c.py ============================================================================== --- python/trunk/Parser/asdl_c.py (original) +++ python/trunk/Parser/asdl_c.py Mon Feb 12 04:51:02 2007 @@ -525,6 +525,9 @@ (cons.name, cons.name), 1) self.emit("if (!%s_singleton) return 0;" % cons.name, 1) +def parse_version(mod): + return mod.version.value[12:-3] + class ASTModuleVisitor(PickleVisitor): def visitModule(self, mod): @@ -540,7 +543,8 @@ self.emit('if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)', 1) self.emit("return;", 2) # Value of version: "$Revision$" - self.emit('if (PyModule_AddStringConstant(m, "__version__", "%s") < 0)' % mod.version.value[12:-3], 1) + self.emit('if (PyModule_AddStringConstant(m, "__version__", "%s") < 0)' + % parse_version(mod), 1) self.emit("return;", 2) for dfn in mod.dfns: self.visit(dfn) @@ -721,11 +725,23 @@ v.visit(object) v.emit("", 0) +common_msg = "/* File automatically generated by %s. */\n" + +c_file_msg = """ +/* + __version__ %s. + + This module must be committed separately after each AST grammar change; + The __version__ number is set to the revision number of the commit + containing the grammar change. +*/ +""" + def main(srcfile): argv0 = sys.argv[0] components = argv0.split(os.sep) argv0 = os.sep.join(components[-2:]) - auto_gen_msg = '/* File automatically generated by %s */\n' % argv0 + auto_gen_msg = common_msg % argv0 mod = asdl.parse(srcfile) if not asdl.check(mod): sys.exit(1) @@ -746,6 +762,7 @@ p = os.path.join(SRC_DIR, str(mod.name) + "-ast.c") f = open(p, "wb") print >> f, auto_gen_msg + print >> f, c_file_msg % parse_version(mod) print >> f, '#include "Python.h"' print >> f, '#include "%s-ast.h"' % mod.name print >> f Modified: python/trunk/Python/Python-ast.c ============================================================================== --- python/trunk/Python/Python-ast.c (original) +++ python/trunk/Python/Python-ast.c Mon Feb 12 04:51:02 2007 @@ -1,4 +1,13 @@ -/* File automatically generated by Parser/asdl_c.py */ +/* File automatically generated by Parser/asdl_c.py. */ + + +/* + __version__ 53731. + + This module must be committed separately after each AST grammar change; + The __version__ number is set to the revision number of the commit + containing the grammar change. +*/ #include "Python.h" #include "Python-ast.h" From python-checkins at python.org Mon Feb 12 10:25:54 2007 From: python-checkins at python.org (lars.gustaebel) Date: Mon, 12 Feb 2007 10:25:54 +0100 (CET) Subject: [Python-checkins] r53752 - python/trunk/Doc/lib/libtarfile.tex Message-ID: <20070212092554.720F81E4015@bag.python.org> Author: lars.gustaebel Date: Mon Feb 12 10:25:53 2007 New Revision: 53752 Modified: python/trunk/Doc/lib/libtarfile.tex Log: Bug #1656581: Point out that external file objects are supposed to be at position 0. Modified: python/trunk/Doc/lib/libtarfile.tex ============================================================================== --- python/trunk/Doc/lib/libtarfile.tex (original) +++ python/trunk/Doc/lib/libtarfile.tex Mon Feb 12 10:25:53 2007 @@ -49,8 +49,8 @@ avoid this. If a compression method is not supported, \exception{CompressionError} is raised. - If \var{fileobj} is specified, it is used as an alternative to - a file object opened for \var{name}. + If \var{fileobj} is specified, it is used as an alternative to a file + object opened for \var{name}. It is supposed to be at position 0. For special purposes, there is a second format for \var{mode}: \code{'filemode|[compression]'}. \function{open()} will return a @@ -161,6 +161,7 @@ If \var{fileobj} is given, it is used for reading or writing data. If it can be determined, \var{mode} is overridden by \var{fileobj}'s mode. + \var{fileobj} will be used from position 0. \begin{notice} \var{fileobj} is not closed, when \class{TarFile} is closed. \end{notice} From python-checkins at python.org Mon Feb 12 10:27:10 2007 From: python-checkins at python.org (lars.gustaebel) Date: Mon, 12 Feb 2007 10:27:10 +0100 (CET) Subject: [Python-checkins] r53753 - python/branches/release25-maint/Doc/lib/libtarfile.tex Message-ID: <20070212092710.E2E1D1E4004@bag.python.org> Author: lars.gustaebel Date: Mon Feb 12 10:27:10 2007 New Revision: 53753 Modified: python/branches/release25-maint/Doc/lib/libtarfile.tex Log: Bug #1656581: Point out that external file objects are supposed to be at position 0. (backport from rev. 53752) Modified: python/branches/release25-maint/Doc/lib/libtarfile.tex ============================================================================== --- python/branches/release25-maint/Doc/lib/libtarfile.tex (original) +++ python/branches/release25-maint/Doc/lib/libtarfile.tex Mon Feb 12 10:27:10 2007 @@ -48,8 +48,8 @@ avoid this. If a compression method is not supported, \exception{CompressionError} is raised. - If \var{fileobj} is specified, it is used as an alternative to - a file object opened for \var{name}. + If \var{fileobj} is specified, it is used as an alternative to a file + object opened for \var{name}. It is supposed to be at position 0. For special purposes, there is a second format for \var{mode}: \code{'filemode|[compression]'}. \function{open()} will return a @@ -155,6 +155,7 @@ If \var{fileobj} is given, it is used for reading or writing data. If it can be determined, \var{mode} is overridden by \var{fileobj}'s mode. + \var{fileobj} will be used from position 0. \begin{notice} \var{fileobj} is not closed, when \class{TarFile} is closed. \end{notice} From python-checkins at python.org Mon Feb 12 13:21:11 2007 From: python-checkins at python.org (martin.v.loewis) Date: Mon, 12 Feb 2007 13:21:11 +0100 (CET) Subject: [Python-checkins] r53754 - in python/trunk: Lib/test/test_sax.py Lib/xml/sax/saxutils.py Misc/NEWS Message-ID: <20070212122111.805291E400D@bag.python.org> Author: martin.v.loewis Date: Mon Feb 12 13:21:10 2007 New Revision: 53754 Modified: python/trunk/Lib/test/test_sax.py python/trunk/Lib/xml/sax/saxutils.py python/trunk/Misc/NEWS Log: Patch 1463026: Support default namespace in XMLGenerator. Fixes #847665. Will backport. Modified: python/trunk/Lib/test/test_sax.py ============================================================================== --- python/trunk/Lib/test/test_sax.py (original) +++ python/trunk/Lib/test/test_sax.py Mon Feb 12 13:21:10 2007 @@ -216,7 +216,44 @@ ('' % ns_uri) -# ===== XMLFilterBase +def test_1463026_1(): + result = StringIO() + gen = XMLGenerator(result) + + gen.startDocument() + gen.startElementNS((None, 'a'), 'a', {(None, 'b'):'c'}) + gen.endElementNS((None, 'a'), 'a') + gen.endDocument() + + return result.getvalue() == start+'' + +def test_1463026_2(): + result = StringIO() + gen = XMLGenerator(result) + + gen.startDocument() + gen.startPrefixMapping(None, 'qux') + gen.startElementNS(('qux', 'a'), 'a', {}) + gen.endElementNS(('qux', 'a'), 'a') + gen.endPrefixMapping(None) + gen.endDocument() + + return result.getvalue() == start+'' + +def test_1463026_3(): + result = StringIO() + gen = XMLGenerator(result) + + gen.startDocument() + gen.startPrefixMapping('my', 'qux') + gen.startElementNS(('qux', 'a'), 'a', {(None, 'b'):'c'}) + gen.endElementNS(('qux', 'a'), 'a') + gen.endPrefixMapping('my') + gen.endDocument() + + return result.getvalue() == start+'' + +# ===== Xmlfilterbase def test_filter_basic(): result = StringIO() Modified: python/trunk/Lib/xml/sax/saxutils.py ============================================================================== --- python/trunk/Lib/xml/sax/saxutils.py (original) +++ python/trunk/Lib/xml/sax/saxutils.py Mon Feb 12 13:21:10 2007 @@ -100,6 +100,17 @@ else: self._out.write(text.encode(self._encoding, _error_handling)) + def _qname(self, name): + """Builds a qualified name from a (ns_url, localname) pair""" + if name[0]: + # The name is in a non-empty namespace + prefix = self._current_context[name[0]] + if prefix: + # If it is not the default namespace, prepend the prefix + return prefix + ":" + name[1] + # Return the unqualified name + return name[1] + # ContentHandler methods def startDocument(self): @@ -125,29 +136,21 @@ self._write('' % name) def startElementNS(self, name, qname, attrs): - if name[0] is None: - # if the name was not namespace-scoped, use the unqualified part - name = name[1] - else: - # else try to restore the original prefix from the namespace - name = self._current_context[name[0]] + ":" + name[1] - self._write('<' + name) + self._write('<' + self._qname(name)) - for pair in self._undeclared_ns_maps: - self._write(' xmlns:%s="%s"' % pair) + for prefix, uri in self._undeclared_ns_maps: + if prefix: + self._out.write(' xmlns:%s="%s"' % (prefix, uri)) + else: + self._out.write(' xmlns="%s"' % uri) self._undeclared_ns_maps = [] for (name, value) in attrs.items(): - name = self._current_context[name[0]] + ":" + name[1] - self._write(' %s=%s' % (name, quoteattr(value))) + self._write(' %s=%s' % (self._qname(name), quoteattr(value))) self._write('>') def endElementNS(self, name, qname): - if name[0] is None: - name = name[1] - else: - name = self._current_context[name[0]] + ":" + name[1] - self._write('' % name) + self._write('' % self._qname(name)) def characters(self, content): self._write(escape(content)) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Feb 12 13:21:10 2007 @@ -128,6 +128,8 @@ Library ------- +- Patch 1463026: Support default namespace in XMLGenerator. + - Patch 1571379: Make trace's --ignore-dir facility work in the face of relative directory names. From python-checkins at python.org Mon Feb 12 13:21:42 2007 From: python-checkins at python.org (martin.v.loewis) Date: Mon, 12 Feb 2007 13:21:42 +0100 (CET) Subject: [Python-checkins] r53755 - in python/branches/release25-maint: Lib/test/test_sax.py Lib/xml/sax/saxutils.py Misc/NEWS Message-ID: <20070212122142.A97B31E4004@bag.python.org> Author: martin.v.loewis Date: Mon Feb 12 13:21:41 2007 New Revision: 53755 Modified: python/branches/release25-maint/Lib/test/test_sax.py python/branches/release25-maint/Lib/xml/sax/saxutils.py python/branches/release25-maint/Misc/NEWS Log: Patch 1463026: Support default namespace in XMLGenerator. Fixes #847665. Modified: python/branches/release25-maint/Lib/test/test_sax.py ============================================================================== --- python/branches/release25-maint/Lib/test/test_sax.py (original) +++ python/branches/release25-maint/Lib/test/test_sax.py Mon Feb 12 13:21:41 2007 @@ -216,7 +216,44 @@ ('' % ns_uri) -# ===== XMLFilterBase +def test_1463026_1(): + result = StringIO() + gen = XMLGenerator(result) + + gen.startDocument() + gen.startElementNS((None, 'a'), 'a', {(None, 'b'):'c'}) + gen.endElementNS((None, 'a'), 'a') + gen.endDocument() + + return result.getvalue() == start+'' + +def test_1463026_2(): + result = StringIO() + gen = XMLGenerator(result) + + gen.startDocument() + gen.startPrefixMapping(None, 'qux') + gen.startElementNS(('qux', 'a'), 'a', {}) + gen.endElementNS(('qux', 'a'), 'a') + gen.endPrefixMapping(None) + gen.endDocument() + + return result.getvalue() == start+'' + +def test_1463026_3(): + result = StringIO() + gen = XMLGenerator(result) + + gen.startDocument() + gen.startPrefixMapping('my', 'qux') + gen.startElementNS(('qux', 'a'), 'a', {(None, 'b'):'c'}) + gen.endElementNS(('qux', 'a'), 'a') + gen.endPrefixMapping('my') + gen.endDocument() + + return result.getvalue() == start+'' + +# ===== Xmlfilterbase def test_filter_basic(): result = StringIO() Modified: python/branches/release25-maint/Lib/xml/sax/saxutils.py ============================================================================== --- python/branches/release25-maint/Lib/xml/sax/saxutils.py (original) +++ python/branches/release25-maint/Lib/xml/sax/saxutils.py Mon Feb 12 13:21:41 2007 @@ -100,6 +100,17 @@ else: self._out.write(text.encode(self._encoding, _error_handling)) + def _qname(self, name): + """Builds a qualified name from a (ns_url, localname) pair""" + if name[0]: + # The name is in a non-empty namespace + prefix = self._current_context[name[0]] + if prefix: + # If it is not the default namespace, prepend the prefix + return prefix + ":" + name[1] + # Return the unqualified name + return name[1] + # ContentHandler methods def startDocument(self): @@ -125,29 +136,21 @@ self._write('' % name) def startElementNS(self, name, qname, attrs): - if name[0] is None: - # if the name was not namespace-scoped, use the unqualified part - name = name[1] - else: - # else try to restore the original prefix from the namespace - name = self._current_context[name[0]] + ":" + name[1] - self._write('<' + name) + self._write('<' + self._qname(name)) - for pair in self._undeclared_ns_maps: - self._write(' xmlns:%s="%s"' % pair) + for prefix, uri in self._undeclared_ns_maps: + if prefix: + self._out.write(' xmlns:%s="%s"' % (prefix, uri)) + else: + self._out.write(' xmlns="%s"' % uri) self._undeclared_ns_maps = [] for (name, value) in attrs.items(): - name = self._current_context[name[0]] + ":" + name[1] - self._write(' %s=%s' % (name, quoteattr(value))) + self._write(' %s=%s' % (self._qname(name), quoteattr(value))) self._write('>') def endElementNS(self, name, qname): - if name[0] is None: - name = name[1] - else: - name = self._current_context[name[0]] + ":" + name[1] - self._write('' % name) + self._write('' % self._qname(name)) def characters(self, content): self._write(escape(content)) Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Mon Feb 12 13:21:41 2007 @@ -169,6 +169,8 @@ Library ------- +- Patch 1463026: Support default namespace in XMLGenerator. + - Patch 1571379: Make trace's --ignore-dir facility work in the face of relative directory names. From buildbot at python.org Mon Feb 12 14:39:50 2007 From: buildbot at python.org (buildbot at python.org) Date: Mon, 12 Feb 2007 13:39:50 +0000 Subject: [Python-checkins] buildbot warnings in x86 Ubuntu edgy (icc) trunk Message-ID: <20070212133951.0FA451E4006@bag.python.org> The Buildbot has detected a new failure of x86 Ubuntu edgy (icc) trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520Ubuntu%2520edgy%2520%2528icc%2529%2520trunk/builds/1180 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: lars.gustaebel,martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: Traceback (most recent call last): File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/bsddb/test/test_thread.py", line 281, in readerThread rec = dbutils.DeadlockWrap(c.next, max_retries=10) File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/bsddb/dbutils.py", line 62, in DeadlockWrap return function(*_args, **_kwargs) DBLockDeadlockError: (-30995, 'DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock') 1 test failed: test_timeout sincerely, -The Buildbot From buildbot at python.org Mon Feb 12 15:00:06 2007 From: buildbot at python.org (buildbot at python.org) Date: Mon, 12 Feb 2007 14:00:06 +0000 Subject: [Python-checkins] buildbot warnings in ia64 Ubuntu trunk 2.5 Message-ID: <20070212140006.7D6331E4006@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu trunk 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%2520Ubuntu%2520trunk%25202.5/builds/192 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: lars.gustaebel,martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_ctypes make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Feb 12 17:22:30 2007 From: python-checkins at python.org (collin.winter) Date: Mon, 12 Feb 2007 17:22:30 +0100 (CET) Subject: [Python-checkins] r53756 - in sandbox/trunk/2to3: fixer_tests.py fixes/fix_raise.py fixes/macros.py Message-ID: <20070212162230.2304B1E4006@bag.python.org> Author: collin.winter Date: Mon Feb 12 17:22:29 2007 New Revision: 53756 Modified: sandbox/trunk/2to3/fixer_tests.py sandbox/trunk/2to3/fixes/fix_raise.py sandbox/trunk/2to3/fixes/macros.py Log: Make fix_raise smarter about dealing with parenthesized expressions Modified: sandbox/trunk/2to3/fixer_tests.py ============================================================================== --- sandbox/trunk/2to3/fixer_tests.py (original) +++ sandbox/trunk/2to3/fixer_tests.py Mon Feb 12 17:22:29 2007 @@ -643,20 +643,37 @@ def test_3(self): b = """raise Exception, (5, 6, 7)""" - a = """raise Exception((5, 6, 7))""" + a = """raise Exception(5, 6, 7)""" self.check(b, a) - - # These should not be touched - + def test_4(self): - b = """raise Exception""" - a = """raise Exception""" + b = """raise E, (5, 6) % (a, b)""" + a = """raise E((5, 6) % (a, b))""" self.check(b, a) - + def test_5(self): - b = """raise Exception(5, 6)""" - a = """raise Exception(5, 6)""" + b = """raise (((E1, E2), E3), E4), V""" + a = """raise E1(V)""" + self.check(b, a) + + def test_6(self): + b = """raise (E1, (E2, E3), E4), V""" + a = """raise E1(V)""" self.check(b, a) + + # These should produce a warning + + def test_warn_1(self): + s = """raise 'foo'""" + self.warns(s, s, "Python 3 does not support string exceptions") + + def test_warn_2(self): + s = """raise "foo", 5""" + self.warns(s, s, "Python 3 does not support string exceptions") + + def test_warn_3(self): + s = """raise "foo", 5, 6""" + self.warns(s, s, "Python 3 does not support string exceptions") # These should result in traceback-assignment @@ -708,7 +725,7 @@ b = """def foo(): raise Exception, (5, 6, 7), 6""" a = """def foo(): - xxx_todo_changeme9 = Exception((5, 6, 7)) + xxx_todo_changeme9 = Exception(5, 6, 7) xxx_todo_changeme9.__traceback__ = 6 raise xxx_todo_changeme9""" self.check(b, a) @@ -720,7 +737,7 @@ b = 6""" a = """def foo(): a = 5 - xxx_todo_changeme10 = Exception((5, 6, 7)) + xxx_todo_changeme10 = Exception(5, 6, 7) xxx_todo_changeme10.__traceback__ = 6 raise xxx_todo_changeme10 b = 6""" Modified: sandbox/trunk/2to3/fixes/fix_raise.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_raise.py (original) +++ sandbox/trunk/2to3/fixes/fix_raise.py Mon Feb 12 17:22:29 2007 @@ -7,22 +7,48 @@ # Local imports import pytree from fixes import basefix -from fixes.macros import Name, Call, Assign, Newline, Attr +from fixes.macros import Name, Call, Assign, Newline, Attr, is_tuple class FixRaise(basefix.BaseFix): PATTERN = """ - raise_stmt< 'raise' exc=any ',' val=any [',' tb=any] > + raise_stmt< 'raise' exc=any [',' val=any [',' tb=any]] > """ def transform(self, node): syms = self.syms results = self.match(node) assert results - + exc = results["exc"].clone() - args = [results["val"].clone()] - args[0].set_prefix("") + if exc.type is token.STRING: + self.cannot_convert(node, "Python 3 does not support string exceptions") + return + + # Python 2 supports + # raise ((((E1, E2), E3), E4), E5), V + # as a synonym for + # raise E1, V + # Since Python 3 will not support this, we recurse down any tuple + # literals, always taking the first element. + while is_tuple(exc): + # exc.children[1:-1] is the unparenthesized tuple + # exc.children[1].children[0] is the first element of the tuple + exc = exc.children[1].children[0].clone() + exc.set_prefix(" ") + + if "val" not in results: + # One-argument raise + new = pytree.Node(syms.raise_stmt, [Name("raise"), exc]) + new.set_prefix(node.get_prefix()) + return new + + val = results["val"].clone() + if is_tuple(val): + args = [c.clone() for c in val.children[1:-1]] + else: + val.set_prefix("") + args = [val] if "tb" in results: tb = results["tb"].clone() @@ -42,8 +68,7 @@ # Assign the traceback set_tb = pytree.Node(syms.simple_stmt, - [Assign(Attr(name.clone(), - Name("__traceback__")), tb), + [Assign(Attr(name.clone(), Name("__traceback__")), tb), Newline()]) set_tb.set_prefix(indent) set_tb.parent = node.parent.parent @@ -57,7 +82,6 @@ new.set_prefix(indent) return new else: - new = pytree.Node(syms.raise_stmt, - [Name("raise"), Call(exc, args)]) + new = pytree.Node(syms.raise_stmt, [Name("raise"), Call(exc, args)]) new.set_prefix(node.get_prefix()) return new Modified: sandbox/trunk/2to3/fixes/macros.py ============================================================================== --- sandbox/trunk/2to3/fixes/macros.py (original) +++ sandbox/trunk/2to3/fixes/macros.py Mon Feb 12 17:22:29 2007 @@ -55,3 +55,13 @@ def Newline(): """A newline literal""" return Leaf(token.NEWLINE, "\n") + +def is_tuple(node): + """Does the node represent a tuple literal?""" + + return (isinstance(node, Node) + and len(node.children) > 1 + and isinstance(node.children[0], Leaf) + and isinstance(node.children[-1], Leaf) + and node.children[0].value == "(" + and node.children[-1].value == ")") From python-checkins at python.org Mon Feb 12 17:23:25 2007 From: python-checkins at python.org (armin.rigo) Date: Mon, 12 Feb 2007 17:23:25 +0100 (CET) Subject: [Python-checkins] r53757 - python/trunk/Lib/test/test_descr.py Message-ID: <20070212162325.150241E4006@bag.python.org> Author: armin.rigo Date: Mon Feb 12 17:23:24 2007 New Revision: 53757 Modified: python/trunk/Lib/test/test_descr.py Log: Fix the line to what is my guess at the original author's meaning. (The line has no effect anyway, but is present because it's customary call the base class __init__). Modified: python/trunk/Lib/test/test_descr.py ============================================================================== --- python/trunk/Lib/test/test_descr.py (original) +++ python/trunk/Lib/test/test_descr.py Mon Feb 12 17:23:24 2007 @@ -2226,7 +2226,7 @@ __slots__ = ['prec'] def __init__(self, value=0.0, prec=12): self.prec = int(prec) - float.__init__(value) + float.__init__(self, value) def __repr__(self): return "%.*g" % (self.prec, self) vereq(repr(precfloat(1.1)), "1.1") From buildbot at python.org Mon Feb 12 17:47:38 2007 From: buildbot at python.org (buildbot at python.org) Date: Mon, 12 Feb 2007 16:47:38 +0000 Subject: [Python-checkins] buildbot warnings in x86 gentoo trunk Message-ID: <20070212164738.8D3E71E4006@bag.python.org> The Buildbot has detected a new failure of x86 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520gentoo%2520trunk/builds/1914 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: armin.rigo Build had warnings: warnings test Excerpt from the test logfile: Traceback (most recent call last): File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/bsddb/test/test_thread.py", line 260, in writerThread self.assertEqual(data, self.makeData(key)) File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/unittest.py", line 334, in failUnlessEqual (msg or '%r != %r' % (first, second)) AssertionError: None != '1001-1001-1001-1001-1001' Traceback (most recent call last): File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/bsddb/test/test_thread.py", line 260, in writerThread self.assertEqual(data, self.makeData(key)) File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/unittest.py", line 334, in failUnlessEqual (msg or '%r != %r' % (first, second)) AssertionError: None != '2000-2000-2000-2000-2000' Traceback (most recent call last): File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/bsddb/test/test_thread.py", line 260, in writerThread self.assertEqual(data, self.makeData(key)) File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/unittest.py", line 334, in failUnlessEqual (msg or '%r != %r' % (first, second)) AssertionError: None != '0002-0002-0002-0002-0002' 1 test failed: test_urllib2net make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Mon Feb 12 20:14:36 2007 From: buildbot at python.org (buildbot at python.org) Date: Mon, 12 Feb 2007 19:14:36 +0000 Subject: [Python-checkins] buildbot warnings in x86 XP-2 trunk Message-ID: <20070212191436.80A1E1E4006@bag.python.org> The Buildbot has detected a new failure of x86 XP-2 trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520XP-2%2520trunk/builds/955 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: andrew.kuchling,armin.rigo,brett.cannon,georg.brandl,kurt.kaiser,lars.gustaebel,martin.v.loewis,peter.astrand,raymond.hettinger,skip.montanaro,tim.peters Build had warnings: warnings failed slave lost sincerely, -The Buildbot From buildbot at python.org Mon Feb 12 21:12:13 2007 From: buildbot at python.org (buildbot at python.org) Date: Mon, 12 Feb 2007 20:12:13 +0000 Subject: [Python-checkins] buildbot warnings in x86 XP-2 trunk Message-ID: <20070212201213.4BF4E1E400D@bag.python.org> The Buildbot has detected a new failure of x86 XP-2 trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520XP-2%2520trunk/builds/958 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'tim': lost connection Build Source Stamp: [branch trunk] HEAD Blamelist: Build had warnings: warnings test Excerpt from the test logfile: 2 tests failed: test_socket_ssl test_tarfile ====================================================================== ERROR: test_fileobj (test.test_tarfile.AppendTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Code\bb_slave\trunk.peters-windows\build\lib\test\test_tarfile.py", line 355, in test_fileobj self._test(names=["foo", "bar"], fileobj=fobj) File "C:\Code\bb_slave\trunk.peters-windows\build\lib\test\test_tarfile.py", line 331, in _test tar = tarfile.open(self.tarname, fileobj=fileobj) File "C:\Code\bb_slave\trunk.peters-windows\build\lib\tarfile.py", line 1157, in open raise ReadError("file could not be opened successfully") ReadError: file could not be opened successfully sincerely, -The Buildbot From python-checkins at python.org Tue Feb 13 00:59:47 2007 From: python-checkins at python.org (collin.winter) Date: Tue, 13 Feb 2007 00:59:47 +0100 (CET) Subject: [Python-checkins] r53758 - in sandbox/trunk/2to3: fixes/fix_apply.py fixes/fix_dict.py fixes/fix_dict2.py fixes/fix_except.py fixes/fix_exec.py fixes/fix_has_key.py fixes/fix_intern.py fixes/fix_long.py fixes/fix_ne.py fixes/fix_print.py fixes/fix_raise.py fixes/fix_repr.py fixes/fix_sysexcinfo.py fixes/fix_throw.py fixes/fix_xrange.py fixes/macros.py patcomp.py pgen2/conv.py pgen2/driver.py pgen2/grammar.py pgen2/parse.py pgen2/pgen.py pgen2/token.py pgen2/tokenize.py pygram.py refactor.py tokenize.py Message-ID: <20070212235947.A3CCC1E400D@bag.python.org> Author: collin.winter Date: Tue Feb 13 00:59:44 2007 New Revision: 53758 Added: sandbox/trunk/2to3/pgen2/token.py (contents, props changed) sandbox/trunk/2to3/pgen2/tokenize.py - copied, changed from r53757, sandbox/trunk/2to3/tokenize.py Removed: sandbox/trunk/2to3/tokenize.py Modified: sandbox/trunk/2to3/fixes/fix_apply.py sandbox/trunk/2to3/fixes/fix_dict.py sandbox/trunk/2to3/fixes/fix_dict2.py sandbox/trunk/2to3/fixes/fix_except.py sandbox/trunk/2to3/fixes/fix_exec.py sandbox/trunk/2to3/fixes/fix_has_key.py sandbox/trunk/2to3/fixes/fix_intern.py sandbox/trunk/2to3/fixes/fix_long.py sandbox/trunk/2to3/fixes/fix_ne.py sandbox/trunk/2to3/fixes/fix_print.py sandbox/trunk/2to3/fixes/fix_raise.py sandbox/trunk/2to3/fixes/fix_repr.py sandbox/trunk/2to3/fixes/fix_sysexcinfo.py sandbox/trunk/2to3/fixes/fix_throw.py sandbox/trunk/2to3/fixes/fix_xrange.py sandbox/trunk/2to3/fixes/macros.py sandbox/trunk/2to3/patcomp.py sandbox/trunk/2to3/pgen2/conv.py sandbox/trunk/2to3/pgen2/driver.py sandbox/trunk/2to3/pgen2/grammar.py sandbox/trunk/2to3/pgen2/parse.py sandbox/trunk/2to3/pgen2/pgen.py sandbox/trunk/2to3/pygram.py sandbox/trunk/2to3/refactor.py Log: Move token and tokenize into pgen2 Modified: sandbox/trunk/2to3/fixes/fix_apply.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_apply.py (original) +++ sandbox/trunk/2to3/fixes/fix_apply.py Tue Feb 13 00:59:44 2007 @@ -3,11 +3,9 @@ """Fixer for apply().""" -# Python imports -import token - # Local imports import pytree +from pgen2 import token from fixes import basefix from fixes.macros import Call, Comma Modified: sandbox/trunk/2to3/fixes/fix_dict.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_dict.py (original) +++ sandbox/trunk/2to3/fixes/fix_dict.py Tue Feb 13 00:59:44 2007 @@ -21,12 +21,10 @@ as an argument to a function that introspects the argument). """ -# Python imports -import token - # Local imports import pytree import patcomp +from pgen2 import token from fixes import basefix from fixes import macros Modified: sandbox/trunk/2to3/fixes/fix_dict2.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_dict2.py (original) +++ sandbox/trunk/2to3/fixes/fix_dict2.py Tue Feb 13 00:59:44 2007 @@ -9,11 +9,9 @@ .itervalues -> .values """ -# Python imports -import token - # Local imports import pytree +from pgen2 import token from fixes import basefix from fixes import macros Modified: sandbox/trunk/2to3/fixes/fix_except.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_except.py (original) +++ sandbox/trunk/2to3/fixes/fix_except.py Tue Feb 13 00:59:44 2007 @@ -1,11 +1,9 @@ """Fixer for except statements with named exceptions.""" # Author: Collin Winter -# Python imports -import token - # Local imports import pytree +from pgen2 import token from fixes import basefix from fixes.macros import Assign, Attr, Name Modified: sandbox/trunk/2to3/fixes/fix_exec.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_exec.py (original) +++ sandbox/trunk/2to3/fixes/fix_exec.py Tue Feb 13 00:59:44 2007 @@ -3,11 +3,9 @@ """Fixer for exec.""" -# Python imports -import token - # Local imports import pytree +from pgen2 import token from fixes import basefix from fixes.macros import Comma, Name, Call Modified: sandbox/trunk/2to3/fixes/fix_has_key.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_has_key.py (original) +++ sandbox/trunk/2to3/fixes/fix_has_key.py Tue Feb 13 00:59:44 2007 @@ -3,11 +3,9 @@ """Fixer for has_key().""" -# Python imports -import token - # Local imports import pytree +from pgen2 import token from fixes import basefix from fixes.macros import Name Modified: sandbox/trunk/2to3/fixes/fix_intern.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_intern.py (original) +++ sandbox/trunk/2to3/fixes/fix_intern.py Tue Feb 13 00:59:44 2007 @@ -3,11 +3,9 @@ """Fixer for intern().""" -# Python imports -import token - # Local imports import pytree +from pgen2 import token from fixes import basefix from fixes.macros import Name, Attr Modified: sandbox/trunk/2to3/fixes/fix_long.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_long.py (original) +++ sandbox/trunk/2to3/fixes/fix_long.py Tue Feb 13 00:59:44 2007 @@ -6,11 +6,9 @@ This also strips the trailing 'L' or 'l' from long loterals. """ -# Python imports -import token - # Local imports import pytree +from pgen2 import token from fixes import basefix from fixes.macros import Name Modified: sandbox/trunk/2to3/fixes/fix_ne.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_ne.py (original) +++ sandbox/trunk/2to3/fixes/fix_ne.py Tue Feb 13 00:59:44 2007 @@ -6,11 +6,9 @@ This is so simple that we don't need the pattern compiler. """ -# Python imports -import token - # Local imports import pytree +from pgen2 import token from fixes import basefix Modified: sandbox/trunk/2to3/fixes/fix_print.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_print.py (original) +++ sandbox/trunk/2to3/fixes/fix_print.py Tue Feb 13 00:59:44 2007 @@ -10,11 +10,9 @@ 'print >>x, ...' into 'print(..., file=x)' """ -# Python imports -import token - # Local imports import pytree +from pgen2 import token from fixes import basefix from fixes.macros import Name, Call, Comma Modified: sandbox/trunk/2to3/fixes/fix_raise.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_raise.py (original) +++ sandbox/trunk/2to3/fixes/fix_raise.py Tue Feb 13 00:59:44 2007 @@ -1,11 +1,9 @@ """Fixer for 'raise E, V, T'""" # Author: Collin Winter -# Python imports -import token - # Local imports import pytree +from pgen2 import token from fixes import basefix from fixes.macros import Name, Call, Assign, Newline, Attr, is_tuple Modified: sandbox/trunk/2to3/fixes/fix_repr.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_repr.py (original) +++ sandbox/trunk/2to3/fixes/fix_repr.py Tue Feb 13 00:59:44 2007 @@ -3,11 +3,9 @@ """Fixer that transforms `xyzzy` into repr(xyzzy).""" -# Python imports -import token - # Local imports import pytree +from pgen2 import token from fixes import basefix from fixes.macros import Call, Name Modified: sandbox/trunk/2to3/fixes/fix_sysexcinfo.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_sysexcinfo.py (original) +++ sandbox/trunk/2to3/fixes/fix_sysexcinfo.py Tue Feb 13 00:59:44 2007 @@ -1,10 +1,8 @@ """Fixer/warner for sys.exc_{info,value,type,traceback}""" # Author: Collin Winter -# Python imports -import token - # Local imports +from pgen2 import token from pytree import Leaf from fixes import basefix Modified: sandbox/trunk/2to3/fixes/fix_throw.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_throw.py (original) +++ sandbox/trunk/2to3/fixes/fix_throw.py Tue Feb 13 00:59:44 2007 @@ -1,11 +1,9 @@ """Fixer for generator.throw(E, V, T)""" # Author: Collin Winter -# Python imports -import token - # Local imports import pytree +from pgen2 import token from fixes import basefix from fixes.macros import Name, Call, Assign, Newline, Attr Modified: sandbox/trunk/2to3/fixes/fix_xrange.py ============================================================================== --- sandbox/trunk/2to3/fixes/fix_xrange.py (original) +++ sandbox/trunk/2to3/fixes/fix_xrange.py Tue Feb 13 00:59:44 2007 @@ -2,11 +2,9 @@ """Fixer that changes xrange(...) into range(...).""" -# Python imports -import token - # Local imports import pytree +from pgen2 import token from fixes import basefix from fixes import macros Modified: sandbox/trunk/2to3/fixes/macros.py ============================================================================== --- sandbox/trunk/2to3/fixes/macros.py (original) +++ sandbox/trunk/2to3/fixes/macros.py Tue Feb 13 00:59:44 2007 @@ -1,10 +1,8 @@ """Abstract away often-used node construction routines.""" # Author: Collin Winter -# Python imports -import token - # Local imports +from pgen2 import token from pytree import Leaf, Node from pygram import python_symbols as syms Modified: sandbox/trunk/2to3/patcomp.py ============================================================================== --- sandbox/trunk/2to3/patcomp.py (original) +++ sandbox/trunk/2to3/patcomp.py Tue Feb 13 00:59:44 2007 @@ -12,12 +12,12 @@ # Python imports import os -import token -import tokenize # Fairly local imports from pgen2 import driver from pgen2 import literals +from pgen2 import token +from pgen2 import tokenize # Really local imports import pytree Modified: sandbox/trunk/2to3/pgen2/conv.py ============================================================================== --- sandbox/trunk/2to3/pgen2/conv.py (original) +++ sandbox/trunk/2to3/pgen2/conv.py Tue Feb 13 00:59:44 2007 @@ -28,9 +28,10 @@ # Python imports import re -import token -from pgen2 import grammar +# Local imports +from pgen2 import grammar, token + class Converter(grammar.Grammar): """Grammar subclass that reads classic pgen output files. Modified: sandbox/trunk/2to3/pgen2/driver.py ============================================================================== --- sandbox/trunk/2to3/pgen2/driver.py (original) +++ sandbox/trunk/2to3/pgen2/driver.py Tue Feb 13 00:59:44 2007 @@ -17,13 +17,10 @@ # Python imports import os -import token import logging -import tokenize # Pgen imports -from pgen2 import parse -from pgen2 import grammar +from pgen2 import grammar, parse, token, tokenize class Driver(object): Modified: sandbox/trunk/2to3/pgen2/grammar.py ============================================================================== --- sandbox/trunk/2to3/pgen2/grammar.py (original) +++ sandbox/trunk/2to3/pgen2/grammar.py Tue Feb 13 00:59:44 2007 @@ -13,9 +13,12 @@ """ # Python imports -import token, tokenize import cPickle as pickle +# Local imports +from pgen2 import token, tokenize + + class Grammar(object): """Pgen parsing tables tables conversion class. Modified: sandbox/trunk/2to3/pgen2/parse.py ============================================================================== --- sandbox/trunk/2to3/pgen2/parse.py (original) +++ sandbox/trunk/2to3/pgen2/parse.py Tue Feb 13 00:59:44 2007 @@ -10,8 +10,8 @@ """ -# Python imports -import token +# Local imports +from pgen2 import token class ParseError(Exception): """Exception to signal the parser is stuck.""" Modified: sandbox/trunk/2to3/pgen2/pgen.py ============================================================================== --- sandbox/trunk/2to3/pgen2/pgen.py (original) +++ sandbox/trunk/2to3/pgen2/pgen.py Tue Feb 13 00:59:44 2007 @@ -1,12 +1,8 @@ # Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement. -# Python imports -import token -import tokenize - # Pgen imports -from pgen2 import grammar +from pgen2 import grammar, token, tokenize class PgenGrammar(grammar.Grammar): pass Added: sandbox/trunk/2to3/pgen2/token.py ============================================================================== --- (empty file) +++ sandbox/trunk/2to3/pgen2/token.py Tue Feb 13 00:59:44 2007 @@ -0,0 +1,82 @@ +#! /usr/bin/env python + +"""Token constants (from "token.h").""" + +# Taken from Python (r53757) and modified to include some tokens +# originally monkeypatched in by pgen2.tokenize + +#--start constants-- +ENDMARKER = 0 +NAME = 1 +NUMBER = 2 +STRING = 3 +NEWLINE = 4 +INDENT = 5 +DEDENT = 6 +LPAR = 7 +RPAR = 8 +LSQB = 9 +RSQB = 10 +COLON = 11 +COMMA = 12 +SEMI = 13 +PLUS = 14 +MINUS = 15 +STAR = 16 +SLASH = 17 +VBAR = 18 +AMPER = 19 +LESS = 20 +GREATER = 21 +EQUAL = 22 +DOT = 23 +PERCENT = 24 +BACKQUOTE = 25 +LBRACE = 26 +RBRACE = 27 +EQEQUAL = 28 +NOTEQUAL = 29 +LESSEQUAL = 30 +GREATEREQUAL = 31 +TILDE = 32 +CIRCUMFLEX = 33 +LEFTSHIFT = 34 +RIGHTSHIFT = 35 +DOUBLESTAR = 36 +PLUSEQUAL = 37 +MINEQUAL = 38 +STAREQUAL = 39 +SLASHEQUAL = 40 +PERCENTEQUAL = 41 +AMPEREQUAL = 42 +VBAREQUAL = 43 +CIRCUMFLEXEQUAL = 44 +LEFTSHIFTEQUAL = 45 +RIGHTSHIFTEQUAL = 46 +DOUBLESTAREQUAL = 47 +DOUBLESLASH = 48 +DOUBLESLASHEQUAL = 49 +AT = 50 +OP = 51 +COMMENT = 52 +NL = 53 +RARROW = 54 +ERRORTOKEN = 55 +N_TOKENS = 56 +NT_OFFSET = 256 +#--end constants-- + +tok_name = {} +for _name, _value in globals().items(): + if type(_value) is type(0): + tok_name[_value] = _name + + +def ISTERMINAL(x): + return x < NT_OFFSET + +def ISNONTERMINAL(x): + return x >= NT_OFFSET + +def ISEOF(x): + return x == ENDMARKER Copied: sandbox/trunk/2to3/pgen2/tokenize.py (from r53757, sandbox/trunk/2to3/tokenize.py) ============================================================================== --- sandbox/trunk/2to3/tokenize.py (original) +++ sandbox/trunk/2to3/pgen2/tokenize.py Tue Feb 13 00:59:44 2007 @@ -30,23 +30,12 @@ 'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro' import string, re -from token import * +from pgen2.token import * -import token -__all__ = [x for x in dir(token) if x[0] != '_'] + ["COMMENT", "tokenize", - "generate_tokens", "NL", "untokenize"] -del x - -COMMENT = N_TOKENS -tok_name[COMMENT] = 'COMMENT' -NL = N_TOKENS + 1 -tok_name[NL] = 'NL' -RARROW = N_TOKENS + 2 -token.RARROW = RARROW -tok_name[RARROW] = 'RARROW' -N_TOKENS += 3 - -del token +from pgen2 import token +__all__ = [x for x in dir(token) if x[0] != '_'] + ["tokenize", + "generate_tokens", "untokenize"] +del x, token def group(*choices): return '(' + '|'.join(choices) + ')' def any(*choices): return group(*choices) + '*' Modified: sandbox/trunk/2to3/pygram.py ============================================================================== --- sandbox/trunk/2to3/pygram.py (original) +++ sandbox/trunk/2to3/pygram.py Tue Feb 13 00:59:44 2007 @@ -5,10 +5,10 @@ # Python imports import os -import token # Local imports import pytree +from pgen2 import token from pgen2 import driver # The grammar file Modified: sandbox/trunk/2to3/refactor.py ============================================================================== --- sandbox/trunk/2to3/refactor.py (original) +++ sandbox/trunk/2to3/refactor.py Tue Feb 13 00:59:44 2007 @@ -20,10 +20,10 @@ import logging # Local imports -import tokenize import pytree import patcomp from pgen2 import driver +from pgen2 import tokenize import fixes import fixes.macros import pygram Deleted: /sandbox/trunk/2to3/tokenize.py ============================================================================== --- /sandbox/trunk/2to3/tokenize.py Tue Feb 13 00:59:44 2007 +++ (empty file) @@ -1,399 +0,0 @@ -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation. -# All rights reserved. - -"""Tokenization help for Python programs. - -generate_tokens(readline) is a generator that breaks a stream of -text into Python tokens. It accepts a readline-like method which is called -repeatedly to get the next line of input (or "" for EOF). It generates -5-tuples with these members: - - the token type (see token.py) - the token (a string) - the starting (row, column) indices of the token (a 2-tuple of ints) - the ending (row, column) indices of the token (a 2-tuple of ints) - the original line (string) - -It is designed to match the working of the Python tokenizer exactly, except -that it produces COMMENT tokens for comments and gives type OP for all -operators - -Older entry points - tokenize_loop(readline, tokeneater) - tokenize(readline, tokeneater=printtoken) -are the same, except instead of generating tokens, tokeneater is a callback -function to which the 5 fields described above are passed as 5 arguments, -each time a new token is found.""" - -__author__ = 'Ka-Ping Yee ' -__credits__ = \ - 'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro' - -import string, re -from token import * - -import token -__all__ = [x for x in dir(token) if x[0] != '_'] + ["COMMENT", "tokenize", - "generate_tokens", "NL", "untokenize"] -del x - -COMMENT = N_TOKENS -tok_name[COMMENT] = 'COMMENT' -NL = N_TOKENS + 1 -tok_name[NL] = 'NL' -RARROW = N_TOKENS + 2 -token.RARROW = RARROW -tok_name[RARROW] = 'RARROW' -N_TOKENS += 3 - -del token - -def group(*choices): return '(' + '|'.join(choices) + ')' -def any(*choices): return group(*choices) + '*' -def maybe(*choices): return group(*choices) + '?' - -Whitespace = r'[ \f\t]*' -Comment = r'#[^\r\n]*' -Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment) -Name = r'[a-zA-Z_]\w*' - -Hexnumber = r'0[xX][\da-fA-F]*[lL]?' -Octnumber = r'0[0-7]*[lL]?' -Decnumber = r'[1-9]\d*[lL]?' -Intnumber = group(Hexnumber, Octnumber, Decnumber) -Exponent = r'[eE][-+]?\d+' -Pointfloat = group(r'\d+\.\d*', r'\.\d+') + maybe(Exponent) -Expfloat = r'\d+' + Exponent -Floatnumber = group(Pointfloat, Expfloat) -Imagnumber = group(r'\d+[jJ]', Floatnumber + r'[jJ]') -Number = group(Imagnumber, Floatnumber, Intnumber) - -# Tail end of ' string. -Single = r"[^'\\]*(?:\\.[^'\\]*)*'" -# Tail end of " string. -Double = r'[^"\\]*(?:\\.[^"\\]*)*"' -# Tail end of ''' string. -Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''" -# Tail end of """ string. -Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""' -Triple = group("[uU]?[rR]?'''", '[uU]?[rR]?"""') -# Single-line ' or " string. -String = group(r"[uU]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*'", - r'[uU]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*"') - -# Because of leftmost-then-longest match semantics, be sure to put the -# longest operators first (e.g., if = came before ==, == would get -# recognized as two instances of =). -Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=", - r"//=?", r"->", - r"[+\-*/%&|^=<>]=?", - r"~") - -Bracket = '[][(){}]' -Special = group(r'\r?\n', r'[:;.,`@]') -Funny = group(Operator, Bracket, Special) - -PlainToken = group(Number, Funny, String, Name) -Token = Ignore + PlainToken - -# First (or only) line of ' or " string. -ContStr = group(r"[uU]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*" + - group("'", r'\\\r?\n'), - r'[uU]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*' + - group('"', r'\\\r?\n')) -PseudoExtras = group(r'\\\r?\n', Comment, Triple) -PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name) - -tokenprog, pseudoprog, single3prog, double3prog = map( - re.compile, (Token, PseudoToken, Single3, Double3)) -endprogs = {"'": re.compile(Single), '"': re.compile(Double), - "'''": single3prog, '"""': double3prog, - "r'''": single3prog, 'r"""': double3prog, - "u'''": single3prog, 'u"""': double3prog, - "ur'''": single3prog, 'ur"""': double3prog, - "R'''": single3prog, 'R"""': double3prog, - "U'''": single3prog, 'U"""': double3prog, - "uR'''": single3prog, 'uR"""': double3prog, - "Ur'''": single3prog, 'Ur"""': double3prog, - "UR'''": single3prog, 'UR"""': double3prog, - 'r': None, 'R': None, 'u': None, 'U': None} - -triple_quoted = {} -for t in ("'''", '"""', - "r'''", 'r"""', "R'''", 'R"""', - "u'''", 'u"""', "U'''", 'U"""', - "ur'''", 'ur"""', "Ur'''", 'Ur"""', - "uR'''", 'uR"""', "UR'''", 'UR"""'): - triple_quoted[t] = t -single_quoted = {} -for t in ("'", '"', - "r'", 'r"', "R'", 'R"', - "u'", 'u"', "U'", 'U"', - "ur'", 'ur"', "Ur'", 'Ur"', - "uR'", 'uR"', "UR'", 'UR"' ): - single_quoted[t] = t - -tabsize = 8 - -class TokenError(Exception): pass - -class StopTokenizing(Exception): pass - -def printtoken(type, token, (srow, scol), (erow, ecol), line): # for testing - print "%d,%d-%d,%d:\t%s\t%s" % \ - (srow, scol, erow, ecol, tok_name[type], repr(token)) - -def tokenize(readline, tokeneater=printtoken): - """ - The tokenize() function accepts two parameters: one representing the - input stream, and one providing an output mechanism for tokenize(). - - The first parameter, readline, must be a callable object which provides - the same interface as the readline() method of built-in file objects. - Each call to the function should return one line of input as a string. - - The second parameter, tokeneater, must also be a callable object. It is - called once for each token, with five arguments, corresponding to the - tuples generated by generate_tokens(). - """ - try: - tokenize_loop(readline, tokeneater) - except StopTokenizing: - pass - -# backwards compatible interface -def tokenize_loop(readline, tokeneater): - for token_info in generate_tokens(readline): - tokeneater(*token_info) - -class Untokenizer: - - def __init__(self): - self.tokens = [] - self.prev_row = 1 - self.prev_col = 0 - - def add_whitespace(self, start): - row, col = start - assert row <= self.prev_row - col_offset = col - self.prev_col - if col_offset: - self.tokens.append(" " * col_offset) - - def untokenize(self, iterable): - for t in iterable: - if len(t) == 2: - self.compat(t, iterable) - break - tok_type, token, start, end, line = t - self.add_whitespace(start) - self.tokens.append(token) - self.prev_row, self.prev_col = end - if tok_type in (NEWLINE, NL): - self.prev_row += 1 - self.prev_col = 0 - return "".join(self.tokens) - - def compat(self, token, iterable): - startline = False - indents = [] - toks_append = self.tokens.append - toknum, tokval = token - if toknum in (NAME, NUMBER): - tokval += ' ' - if toknum in (NEWLINE, NL): - startline = True - for tok in iterable: - toknum, tokval = tok[:2] - - if toknum in (NAME, NUMBER): - tokval += ' ' - - if toknum == INDENT: - indents.append(tokval) - continue - elif toknum == DEDENT: - indents.pop() - continue - elif toknum in (NEWLINE, NL): - startline = True - elif startline and indents: - toks_append(indents[-1]) - startline = False - toks_append(tokval) - -def untokenize(iterable): - """Transform tokens back into Python source code. - - Each element returned by the iterable must be a token sequence - with at least two elements, a token number and token value. If - only two tokens are passed, the resulting output is poor. - - Round-trip invariant for full input: - Untokenized source will match input source exactly - - Round-trip invariant for limited intput: - # Output text will tokenize the back to the input - t1 = [tok[:2] for tok in generate_tokens(f.readline)] - newcode = untokenize(t1) - readline = iter(newcode.splitlines(1)).next - t2 = [tok[:2] for tokin generate_tokens(readline)] - assert t1 == t2 - """ - ut = Untokenizer() - return ut.untokenize(iterable) - -def generate_tokens(readline): - """ - The generate_tokens() generator requires one argment, readline, which - must be a callable object which provides the same interface as the - readline() method of built-in file objects. Each call to the function - should return one line of input as a string. Alternately, readline - can be a callable function terminating with StopIteration: - readline = open(myfile).next # Example of alternate readline - - The generator produces 5-tuples with these members: the token type; the - token string; a 2-tuple (srow, scol) of ints specifying the row and - column where the token begins in the source; a 2-tuple (erow, ecol) of - ints specifying the row and column where the token ends in the source; - and the line on which the token was found. The line passed is the - logical line; continuation lines are included. - """ - lnum = parenlev = continued = 0 - namechars, numchars = string.ascii_letters + '_', '0123456789' - contstr, needcont = '', 0 - contline = None - indents = [0] - - while 1: # loop over lines in stream - try: - line = readline() - except StopIteration: - line = '' - lnum = lnum + 1 - pos, max = 0, len(line) - - if contstr: # continued string - if not line: - raise TokenError, ("EOF in multi-line string", strstart) - endmatch = endprog.match(line) - if endmatch: - pos = end = endmatch.end(0) - yield (STRING, contstr + line[:end], - strstart, (lnum, end), contline + line) - contstr, needcont = '', 0 - contline = None - elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': - yield (ERRORTOKEN, contstr + line, - strstart, (lnum, len(line)), contline) - contstr = '' - contline = None - continue - else: - contstr = contstr + line - contline = contline + line - continue - - elif parenlev == 0 and not continued: # new statement - if not line: break - column = 0 - while pos < max: # measure leading whitespace - if line[pos] == ' ': column = column + 1 - elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize - elif line[pos] == '\f': column = 0 - else: break - pos = pos + 1 - if pos == max: break - - if line[pos] in '#\r\n': # skip comments or blank lines - if line[pos] == '#': - comment_token = line[pos:].rstrip('\r\n') - nl_pos = pos + len(comment_token) - yield (COMMENT, comment_token, - (lnum, pos), (lnum, pos + len(comment_token)), line) - yield (NL, line[nl_pos:], - (lnum, nl_pos), (lnum, len(line)), line) - else: - yield ((NL, COMMENT)[line[pos] == '#'], line[pos:], - (lnum, pos), (lnum, len(line)), line) - continue - - if column > indents[-1]: # count indents or dedents - indents.append(column) - yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line) - while column < indents[-1]: - if column not in indents: - raise IndentationError( - "unindent does not match any outer indentation level", - ("", lnum, pos, line)) - indents = indents[:-1] - yield (DEDENT, '', (lnum, pos), (lnum, pos), line) - - else: # continued statement - if not line: - raise TokenError, ("EOF in multi-line statement", (lnum, 0)) - continued = 0 - - while pos < max: - pseudomatch = pseudoprog.match(line, pos) - if pseudomatch: # scan for tokens - start, end = pseudomatch.span(1) - spos, epos, pos = (lnum, start), (lnum, end), end - token, initial = line[start:end], line[start] - - if initial in numchars or \ - (initial == '.' and token != '.'): # ordinary number - yield (NUMBER, token, spos, epos, line) - elif initial in '\r\n': - yield (NL if parenlev > 0 else NEWLINE, - token, spos, epos, line) - elif initial == '#': - assert not token.endswith("\n") - yield (COMMENT, token, spos, epos, line) - elif token in triple_quoted: - endprog = endprogs[token] - endmatch = endprog.match(line, pos) - if endmatch: # all on one line - pos = endmatch.end(0) - token = line[start:pos] - yield (STRING, token, spos, (lnum, pos), line) - else: - strstart = (lnum, start) # multiple lines - contstr = line[start:] - contline = line - break - elif initial in single_quoted or \ - token[:2] in single_quoted or \ - token[:3] in single_quoted: - if token[-1] == '\n': # continued string - strstart = (lnum, start) - endprog = (endprogs[initial] or endprogs[token[1]] or - endprogs[token[2]]) - contstr, needcont = line[start:], 1 - contline = line - break - else: # ordinary string - yield (STRING, token, spos, epos, line) - elif initial in namechars: # ordinary name - yield (NAME, token, spos, epos, line) - elif initial == '\\': # continued stmt - # This yield is new; needed for better idempotency: - yield (NL, token, spos, (lnum, pos), line) - continued = 1 - else: - if initial in '([{': parenlev = parenlev + 1 - elif initial in ')]}': parenlev = parenlev - 1 - yield (OP, token, spos, epos, line) - else: - yield (ERRORTOKEN, line[pos], - (lnum, pos), (lnum, pos+1), line) - pos = pos + 1 - - for indent in indents[1:]: # pop remaining indent levels - yield (DEDENT, '', (lnum, 0), (lnum, 0), '') - yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '') - -if __name__ == '__main__': # testing - import sys - if len(sys.argv) > 1: tokenize(open(sys.argv[1]).readline) - else: tokenize(sys.stdin.readline) From python-checkins at python.org Tue Feb 13 07:25:50 2007 From: python-checkins at python.org (brett.cannon) Date: Tue, 13 Feb 2007 07:25:50 +0100 (CET) Subject: [Python-checkins] r53760 - python/branches/bcannon-sandboxing/BRANCH_NOTES Message-ID: <20070213062550.EFF521E4009@bag.python.org> Author: brett.cannon Date: Tue Feb 13 07:25:50 2007 New Revision: 53760 Added: python/branches/bcannon-sandboxing/BRANCH_NOTES (contents, props changed) Log: Add a file documenting some things about this branch. Added: python/branches/bcannon-sandboxing/BRANCH_NOTES ============================================================================== --- (empty file) +++ python/branches/bcannon-sandboxing/BRANCH_NOTES Tue Feb 13 07:25:50 2007 @@ -0,0 +1,24 @@ +======= +Purpose +======= +This branch is to try to track how memory is used throughout the interpreter. +The goal was to be able to ask questions like, "how many bytes are being used +by integers?" and the like. + +The hope was that people would be able to tell where all of their memory usage +was going. This could also help with finding reference leaks if a certain type +of object was taking up more memory than it was supposed to. + +====== +Status +====== +Tracking "leaks" a few bytes after every pressing of Enter at an interpreter +prompt. + +This branch was meant as a proof-of-concept of the idea. It was to work out +how one could track pymalloc and malloc usage. + +========== +References +========== +* PEP.txt in this branch. From python-checkins at python.org Tue Feb 13 07:29:09 2007 From: python-checkins at python.org (brett.cannon) Date: Tue, 13 Feb 2007 07:29:09 +0100 (CET) Subject: [Python-checkins] r53761 - python/branches/bcannon-objcap/BRANCH_NOTES Message-ID: <20070213062909.9645C1E4009@bag.python.org> Author: brett.cannon Date: Tue Feb 13 07:29:09 2007 New Revision: 53761 Added: python/branches/bcannon-objcap/BRANCH_NOTES (contents, props changed) Log: Doc to contain basic info about this branch. Added: python/branches/bcannon-objcap/BRANCH_NOTES ============================================================================== --- (empty file) +++ python/branches/bcannon-objcap/BRANCH_NOTES Tue Feb 13 07:29:09 2007 @@ -0,0 +1,17 @@ +======= +Purpose +======= +Attempt to develop some form of security model for Python. + +====== +Status +====== +Working on an interpreter-wide security model for Python. This is not a +replacement for rexec but should allow someone who embeds Python to be able to +execute Python code safely. + +========== +References +========== +* securing_python.txt +* http://docs.google.com/Doc?id=dg7fctr4_4d8tdbq From python-checkins at python.org Tue Feb 13 07:41:31 2007 From: python-checkins at python.org (brett.cannon) Date: Tue, 13 Feb 2007 07:41:31 +0100 (CET) Subject: [Python-checkins] r53762 - python/branches/pep302_phase2/BRANCH_NOTES Message-ID: <20070213064131.B7C941E4009@bag.python.org> Author: brett.cannon Date: Tue Feb 13 07:41:27 2007 New Revision: 53762 Added: python/branches/pep302_phase2/BRANCH_NOTES (contents, props changed) Log: Doc describing what this branch is for. Added: python/branches/pep302_phase2/BRANCH_NOTES ============================================================================== --- (empty file) +++ python/branches/pep302_phase2/BRANCH_NOTES Tue Feb 13 07:41:27 2007 @@ -0,0 +1,15 @@ +======= +Purpose +======= +Replace the C implementation of import with Python implementation. + +====== +Status +====== +Rewrite of import in Pure Python contained is in Python's sandbox under +import_in_py. + + +========== +References +========== From python-checkins at python.org Tue Feb 13 09:34:46 2007 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 13 Feb 2007 09:34:46 +0100 (CET) Subject: [Python-checkins] r53763 - in python/trunk: Lib/imputil.py Misc/NEWS Message-ID: <20070213083446.AA8FB1E400D@bag.python.org> Author: martin.v.loewis Date: Tue Feb 13 09:34:45 2007 New Revision: 53763 Modified: python/trunk/Lib/imputil.py python/trunk/Misc/NEWS Log: Patch #685268: Consider a package's __path__ in imputil. Will backport. Modified: python/trunk/Lib/imputil.py ============================================================================== --- python/trunk/Lib/imputil.py (original) +++ python/trunk/Lib/imputil.py Tue Feb 13 09:34:45 2007 @@ -552,6 +552,10 @@ # This method is only used when we look for a module within a package. assert parent + for submodule_path in parent.__path__: + code = self._import_pathname(_os_path_join(submodule_path, modname), fqname) + if code is not None: + return code return self._import_pathname(_os_path_join(parent.__pkgdir__, modname), fqname) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Feb 13 09:34:45 2007 @@ -128,6 +128,8 @@ Library ------- +- Patch #685268: Consider a package's __path__ in imputil. + - Patch 1463026: Support default namespace in XMLGenerator. - Patch 1571379: Make trace's --ignore-dir facility work in the face of From python-checkins at python.org Tue Feb 13 09:35:02 2007 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 13 Feb 2007 09:35:02 +0100 (CET) Subject: [Python-checkins] r53764 - in python/branches/release25-maint: Lib/imputil.py Misc/NEWS Message-ID: <20070213083502.5BCC01E400D@bag.python.org> Author: martin.v.loewis Date: Tue Feb 13 09:35:01 2007 New Revision: 53764 Modified: python/branches/release25-maint/Lib/imputil.py python/branches/release25-maint/Misc/NEWS Log: Patch #685268: Consider a package's __path__ in imputil. Modified: python/branches/release25-maint/Lib/imputil.py ============================================================================== --- python/branches/release25-maint/Lib/imputil.py (original) +++ python/branches/release25-maint/Lib/imputil.py Tue Feb 13 09:35:01 2007 @@ -552,6 +552,10 @@ # This method is only used when we look for a module within a package. assert parent + for submodule_path in parent.__path__: + code = self._import_pathname(_os_path_join(submodule_path, modname), fqname) + if code is not None: + return code return self._import_pathname(_os_path_join(parent.__pkgdir__, modname), fqname) Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Tue Feb 13 09:35:01 2007 @@ -169,6 +169,8 @@ Library ------- +- Patch #685268: Consider a package's __path__ in imputil. + - Patch 1463026: Support default namespace in XMLGenerator. - Patch 1571379: Make trace's --ignore-dir facility work in the face of From python-checkins at python.org Tue Feb 13 10:49:40 2007 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 13 Feb 2007 10:49:40 +0100 (CET) Subject: [Python-checkins] r53765 - in python/trunk: Doc/lib/libzipfile.tex Lib/test/test_zipfile.py Lib/zipfile.py Misc/NEWS Message-ID: <20070213094940.540B31E400D@bag.python.org> Author: martin.v.loewis Date: Tue Feb 13 10:49:38 2007 New Revision: 53765 Modified: python/trunk/Doc/lib/libzipfile.tex python/trunk/Lib/test/test_zipfile.py python/trunk/Lib/zipfile.py python/trunk/Misc/NEWS Log: Patch #698833: Support file decryption in zipfile. Modified: python/trunk/Doc/lib/libzipfile.tex ============================================================================== --- python/trunk/Doc/lib/libzipfile.tex (original) +++ python/trunk/Doc/lib/libzipfile.tex Tue Feb 13 10:49:38 2007 @@ -17,8 +17,10 @@ {PKZIP Application Note}. This module does not currently handle ZIP files which have appended -comments, or multi-disk ZIP files. It can handle ZIP files that use the -ZIP64 extensions (that is ZIP files that are more than 4 GByte in size). +comments, or multi-disk ZIP files. It can handle ZIP files that use +the ZIP64 extensions (that is ZIP files that are more than 4 GByte in +size). It supports decryption of encrypted files in ZIP archives, but +it cannot currently create an encrypted file. The available attributes of this module are: @@ -138,9 +140,18 @@ Print a table of contents for the archive to \code{sys.stdout}. \end{methoddesc} -\begin{methoddesc}{read}{name} +\begin{methoddesc}{setpassword}{pwd} + Set \var{pwd} as default password to extract encrypted files. + \versionadded{2.6} +\end{methoddesc} + +\begin{methoddesc}{read}{name\optional{, pwd}} Return the bytes of the file in the archive. The archive must be - open for read or append. + open for read or append. \var{pwd} is the password used for encrypted + files and, if specified, it will override the default password set with + \method{setpassword()}. + + \versionchanged[\var{pwd} was added]{2.6} \end{methoddesc} \begin{methoddesc}{testzip}{} Modified: python/trunk/Lib/test/test_zipfile.py ============================================================================== --- python/trunk/Lib/test/test_zipfile.py (original) +++ python/trunk/Lib/test/test_zipfile.py Tue Feb 13 10:49:38 2007 @@ -349,8 +349,49 @@ # and report that the first file in the archive was corrupt. self.assertRaises(RuntimeError, zipf.testzip) + +class DecryptionTests(unittest.TestCase): + # This test checks that ZIP decryption works. Since the library does not + # support encryption at the moment, we use a pre-generated encrypted + # ZIP file + + data = ( + 'PK\x03\x04\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00\x1a\x00' + '\x00\x00\x08\x00\x00\x00test.txt\xfa\x10\xa0gly|\xfa-\xc5\xc0=\xf9y' + '\x18\xe0\xa8r\xb3Z}Lg\xbc\xae\xf9|\x9b\x19\xe4\x8b\xba\xbb)\x8c\xb0\xdbl' + 'PK\x01\x02\x14\x00\x14\x00\x01\x00\x00\x00n\x92i.#y\xef?&\x00\x00\x00' + '\x1a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00 \x00\xb6\x81' + '\x00\x00\x00\x00test.txtPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x006\x00' + '\x00\x00L\x00\x00\x00\x00\x00' ) + + plain = 'zipfile.py encryption test' + + def setUp(self): + fp = open(TESTFN, "wb") + fp.write(self.data) + fp.close() + self.zip = zipfile.ZipFile(TESTFN, "r") + + def tearDown(self): + self.zip.close() + os.unlink(TESTFN) + + def testNoPassword(self): + # Reading the encrypted file without password + # must generate a RunTime exception + self.assertRaises(RuntimeError, self.zip.read, "test.txt") + + def testBadPassword(self): + self.zip.setpassword("perl") + self.assertRaises(RuntimeError, self.zip.read, "test.txt") + + def testGoodPassword(self): + self.zip.setpassword("python") + self.assertEquals(self.zip.read("test.txt"), self.plain) + def test_main(): - run_unittest(TestsWithSourceFile, TestZip64InSmallFiles, OtherTests, PyZipFileTests) + run_unittest(TestsWithSourceFile, TestZip64InSmallFiles, OtherTests, + PyZipFileTests, DecryptionTests) #run_unittest(TestZip64InSmallFiles) if __name__ == "__main__": Modified: python/trunk/Lib/zipfile.py ============================================================================== --- python/trunk/Lib/zipfile.py (original) +++ python/trunk/Lib/zipfile.py Tue Feb 13 10:49:38 2007 @@ -296,6 +296,65 @@ extra = extra[ln+4:] +class _ZipDecrypter: + """Class to handle decryption of files stored within a ZIP archive. + + ZIP supports a password-based form of encryption. Even though known + plaintext attacks have been found against it, it is still useful + for low-level securicy. + + Usage: + zd = _ZipDecrypter(mypwd) + plain_char = zd(cypher_char) + plain_text = map(zd, cypher_text) + """ + + def _GenerateCRCTable(): + """Generate a CRC-32 table. + + ZIP encryption uses the CRC32 one-byte primitive for scrambling some + internal keys. We noticed that a direct implementation is faster than + relying on binascii.crc32(). + """ + poly = 0xedb88320 + table = [0] * 256 + for i in range(256): + crc = i + for j in range(8): + if crc & 1: + crc = ((crc >> 1) & 0x7FFFFFFF) ^ poly + else: + crc = ((crc >> 1) & 0x7FFFFFFF) + table[i] = crc + return table + crctable = _GenerateCRCTable() + + def _crc32(self, ch, crc): + """Compute the CRC32 primitive on one byte.""" + return ((crc >> 8) & 0xffffff) ^ self.crctable[(crc ^ ord(ch)) & 0xff] + + def __init__(self, pwd): + self.key0 = 305419896 + self.key1 = 591751049 + self.key2 = 878082192 + for p in pwd: + self._UpdateKeys(p) + + def _UpdateKeys(self, c): + self.key0 = self._crc32(c, self.key0) + self.key1 = (self.key1 + (self.key0 & 255)) & 4294967295 + self.key1 = (self.key1 * 134775813 + 1) & 4294967295 + self.key2 = self._crc32(chr((self.key1 >> 24) & 255), self.key2) + + def __call__(self, c): + """Decrypt a single character.""" + c = ord(c) + k = self.key2 | 2 + c = c ^ (((k * (k^1)) >> 8) & 255) + c = chr(c) + self._UpdateKeys(c) + return c + class ZipFile: """ Class with methods to open, read, write, close, list zip files. @@ -330,6 +389,7 @@ self.filelist = [] # List of ZipInfo instances for archive self.compression = compression # Method of compression self.mode = key = mode.replace('b', '')[0] + self.pwd = None # Check if we were passed a file-like object if isinstance(file, basestring): @@ -461,7 +521,11 @@ """Return the instance of ZipInfo given 'name'.""" return self.NameToInfo[name] - def read(self, name): + def setpassword(self, pwd): + """Set default password for encrypted files.""" + self.pwd = pwd + + def read(self, name, pwd=None): """Return file bytes (as a string) for name.""" if self.mode not in ("r", "a"): raise RuntimeError, 'read() requires mode "r" or "a"' @@ -469,6 +533,13 @@ raise RuntimeError, \ "Attempt to read ZIP archive that was already closed" zinfo = self.getinfo(name) + is_encrypted = zinfo.flag_bits & 0x1 + if is_encrypted: + if not pwd: + pwd = self.pwd + if not pwd: + raise RuntimeError, "File %s is encrypted, " \ + "password required for extraction" % name filepos = self.fp.tell() self.fp.seek(zinfo.header_offset, 0) @@ -489,6 +560,18 @@ zinfo.orig_filename, fname) bytes = self.fp.read(zinfo.compress_size) + # Go with decryption + if is_encrypted: + zd = _ZipDecrypter(pwd) + # The first 12 bytes in the cypher stream is an encryption header + # used to strengthen the algorithm. The first 11 bytes are + # completely random, while the 12th contains the MSB of the CRC, + # and is used to check the correctness of the password. + h = map(zd, bytes[0:12]) + if ord(h[11]) != ((zinfo.CRC>>24)&255): + raise RuntimeError, "Bad password for file %s" % name + bytes = "".join(map(zd, bytes[12:])) + # Go with decompression self.fp.seek(filepos, 0) if zinfo.compress_type == ZIP_STORED: pass Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Feb 13 10:49:38 2007 @@ -128,6 +128,8 @@ Library ------- +- Patch #698833: Support file decryption in zipfile. + - Patch #685268: Consider a package's __path__ in imputil. - Patch 1463026: Support default namespace in XMLGenerator. From python-checkins at python.org Tue Feb 13 11:10:40 2007 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 13 Feb 2007 11:10:40 +0100 (CET) Subject: [Python-checkins] r53766 - in python/trunk: Doc/lib/libzipfile.tex Lib/test/test_zipfile.py Lib/zipfile.py Misc/NEWS Message-ID: <20070213101040.E77081E4021@bag.python.org> Author: martin.v.loewis Date: Tue Feb 13 11:10:39 2007 New Revision: 53766 Modified: python/trunk/Doc/lib/libzipfile.tex python/trunk/Lib/test/test_zipfile.py python/trunk/Lib/zipfile.py python/trunk/Misc/NEWS Log: Patch #1517891: Make 'a' create the file if it doesn't exist. Fixes #1514451. Modified: python/trunk/Doc/lib/libzipfile.tex ============================================================================== --- python/trunk/Doc/lib/libzipfile.tex (original) +++ python/trunk/Doc/lib/libzipfile.tex Tue Feb 13 11:10:39 2007 @@ -101,6 +101,8 @@ \end{verbatim} also works, and at least \program{WinZip} can read such files. + If \var{mode} is \code{a} and the file does not exist at all, + it is created. \var{compression} is the ZIP compression method to use when writing the archive, and should be \constant{ZIP_STORED} or \constant{ZIP_DEFLATED}; unrecognized values will cause @@ -114,6 +116,9 @@ ZIP file would require ZIP64 extensions. ZIP64 extensions are disabled by default because the default \program{zip} and \program{unzip} commands on \UNIX{} (the InfoZIP utilities) don't support these extensions. + + \versionchanged[If the file does not exist, it is created if the + mode is 'a']{2.6} \end{classdesc} \begin{methoddesc}{close}{} Modified: python/trunk/Lib/test/test_zipfile.py ============================================================================== --- python/trunk/Lib/test/test_zipfile.py (original) +++ python/trunk/Lib/test/test_zipfile.py Tue Feb 13 11:10:39 2007 @@ -307,6 +307,28 @@ class OtherTests(unittest.TestCase): + def testCreateNonExistentFileForAppend(self): + if os.path.exists(TESTFN): + os.unlink(TESTFN) + + filename = 'testfile.txt' + content = 'hello, world. this is some content.' + + try: + zf = zipfile.ZipFile(TESTFN, 'a') + zf.writestr(filename, content) + zf.close() + except IOError, (errno, errmsg): + self.fail('Could not append data to a non-existent zip file.') + + self.assert_(os.path.exists(TESTFN)) + + zf = zipfile.ZipFile(TESTFN, 'r') + self.assertEqual(zf.read(filename), content) + zf.close() + + os.unlink(TESTFN) + def testCloseErroneousFile(self): # This test checks that the ZipFile constructor closes the file object # it opens if there's an error in the file. If it doesn't, the traceback Modified: python/trunk/Lib/zipfile.py ============================================================================== --- python/trunk/Lib/zipfile.py (original) +++ python/trunk/Lib/zipfile.py Tue Feb 13 11:10:39 2007 @@ -396,7 +396,14 @@ self._filePassed = 0 self.filename = file modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'} - self.fp = open(file, modeDict[mode]) + try: + self.fp = open(file, modeDict[mode]) + except IOError: + if mode == 'a': + mode = key = 'w' + self.fp = open(file, modeDict[mode]) + else: + raise else: self._filePassed = 1 self.fp = file Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Feb 13 11:10:39 2007 @@ -128,6 +128,9 @@ Library ------- +- Patch #1517891: Mode 'a' for ZipFile now creates the file if it + doesn't exist. + - Patch #698833: Support file decryption in zipfile. - Patch #685268: Consider a package's __path__ in imputil. From buildbot at python.org Tue Feb 13 11:33:03 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 13 Feb 2007 10:33:03 +0000 Subject: [Python-checkins] buildbot warnings in S-390 Debian 2.5 Message-ID: <20070213103303.858F91E400F@bag.python.org> The Buildbot has detected a new failure of S-390 Debian 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/S-390%2520Debian%25202.5/builds/179 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_timeout ====================================================================== FAIL: testConnectTimeout (test.test_timeout.TimeoutTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/2.5.klose-debian-s390/build/Lib/test/test_timeout.py", line 128, in testConnectTimeout %(_delta, self.fuzz, _timeout)) AssertionError: timeout (5.00805) is more than 2 seconds more than expected (0.001) make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Tue Feb 13 11:36:04 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 13 Feb 2007 10:36:04 +0000 Subject: [Python-checkins] buildbot warnings in PPC64 Debian trunk Message-ID: <20070213103604.876061E400E@bag.python.org> The Buildbot has detected a new failure of PPC64 Debian trunk. Full details are available at: http://www.python.org/dev/buildbot/all/PPC64%2520Debian%2520trunk/builds/67 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_timeout make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Tue Feb 13 12:32:24 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 13 Feb 2007 11:32:24 +0000 Subject: [Python-checkins] buildbot warnings in S-390 Debian trunk Message-ID: <20070213113224.DA8971E400F@bag.python.org> The Buildbot has detected a new failure of S-390 Debian trunk. Full details are available at: http://www.python.org/dev/buildbot/all/S-390%2520Debian%2520trunk/builds/668 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_timeout ====================================================================== FAIL: testConnectTimeout (test.test_timeout.TimeoutTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-s390/build/Lib/test/test_timeout.py", line 128, in testConnectTimeout %(_delta, self.fuzz, _timeout)) AssertionError: timeout (5.00804) is more than 2 seconds more than expected (0.001) make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Tue Feb 13 13:08:24 2007 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 13 Feb 2007 13:08:24 +0100 (CET) Subject: [Python-checkins] r53767 - python/trunk/Doc/lib/liblocale.tex Message-ID: <20070213120824.A11181E400F@bag.python.org> Author: martin.v.loewis Date: Tue Feb 13 13:08:24 2007 New Revision: 53767 Modified: python/trunk/Doc/lib/liblocale.tex Log: Bug #1658794: Remove extraneous 'this'. Will backport to 2.5. Modified: python/trunk/Doc/lib/liblocale.tex ============================================================================== --- python/trunk/Doc/lib/liblocale.tex (original) +++ python/trunk/Doc/lib/liblocale.tex Tue Feb 13 13:08:24 2007 @@ -481,7 +481,7 @@ locale settings. When a call to the \function{setlocale()} function changes the \constant{LC_CTYPE} settings, the variables \code{string.lowercase}, \code{string.uppercase} and -\code{string.letters} are recalculated. Note that this code that uses +\code{string.letters} are recalculated. Note that code that uses these variable through `\keyword{from} ... \keyword{import} ...', e.g.\ \code{from string import letters}, is not affected by subsequent \function{setlocale()} calls. From python-checkins at python.org Tue Feb 13 13:08:35 2007 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 13 Feb 2007 13:08:35 +0100 (CET) Subject: [Python-checkins] r53768 - python/branches/release25-maint/Doc/lib/liblocale.tex Message-ID: <20070213120835.17CFD1E400F@bag.python.org> Author: martin.v.loewis Date: Tue Feb 13 13:08:34 2007 New Revision: 53768 Modified: python/branches/release25-maint/Doc/lib/liblocale.tex Log: Bug #1658794: Remove extraneous 'this'. Modified: python/branches/release25-maint/Doc/lib/liblocale.tex ============================================================================== --- python/branches/release25-maint/Doc/lib/liblocale.tex (original) +++ python/branches/release25-maint/Doc/lib/liblocale.tex Tue Feb 13 13:08:34 2007 @@ -481,7 +481,7 @@ locale settings. When a call to the \function{setlocale()} function changes the \constant{LC_CTYPE} settings, the variables \code{string.lowercase}, \code{string.uppercase} and -\code{string.letters} are recalculated. Note that this code that uses +\code{string.letters} are recalculated. Note that code that uses these variable through `\keyword{from} ... \keyword{import} ...', e.g.\ \code{from string import letters}, is not affected by subsequent \function{setlocale()} calls. From python-checkins at python.org Tue Feb 13 13:14:20 2007 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 13 Feb 2007 13:14:20 +0100 (CET) Subject: [Python-checkins] r53769 - in python/trunk: Misc/NEWS Modules/socketmodule.c Message-ID: <20070213121420.A50C91E400F@bag.python.org> Author: martin.v.loewis Date: Tue Feb 13 13:14:19 2007 New Revision: 53769 Modified: python/trunk/Misc/NEWS python/trunk/Modules/socketmodule.c Log: Patch #1657276: Make NETLINK_DNRTMSG conditional. Will backport. Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Feb 13 13:14:19 2007 @@ -364,6 +364,8 @@ Extension Modules ----------------- +- Patch #1657276: Make NETLINK_DNRTMSG conditional. + - Bug #1653736: Complain about keyword arguments to time.isoformat. - Bug #1486663: don't reject keyword arguments for subclasses of builtin Modified: python/trunk/Modules/socketmodule.c ============================================================================== --- python/trunk/Modules/socketmodule.c (original) +++ python/trunk/Modules/socketmodule.c Tue Feb 13 13:14:19 2007 @@ -4383,7 +4383,9 @@ PyModule_AddIntConstant(m, "NETLINK_ROUTE6", NETLINK_ROUTE6); #endif PyModule_AddIntConstant(m, "NETLINK_IP6_FW", NETLINK_IP6_FW); +#ifdef NETLINK_DNRTMSG PyModule_AddIntConstant(m, "NETLINK_DNRTMSG", NETLINK_DNRTMSG); +#endif #ifdef NETLINK_TAPBASE PyModule_AddIntConstant(m, "NETLINK_TAPBASE", NETLINK_TAPBASE); #endif From python-checkins at python.org Tue Feb 13 13:14:30 2007 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 13 Feb 2007 13:14:30 +0100 (CET) Subject: [Python-checkins] r53770 - in python/branches/release25-maint: Misc/NEWS Modules/socketmodule.c Message-ID: <20070213121430.09D801E400F@bag.python.org> Author: martin.v.loewis Date: Tue Feb 13 13:14:29 2007 New Revision: 53770 Modified: python/branches/release25-maint/Misc/NEWS python/branches/release25-maint/Modules/socketmodule.c Log: Patch #1657276: Make NETLINK_DNRTMSG conditional. Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Tue Feb 13 13:14:29 2007 @@ -107,6 +107,8 @@ Extension Modules ----------------- +- Patch #1657276: Make NETLINK_DNRTMSG conditional. + - Bug #1653736: Complain about keyword arguments to time.isoformat. - operator.count() now raises an OverflowError when the count reaches sys.maxint. Modified: python/branches/release25-maint/Modules/socketmodule.c ============================================================================== --- python/branches/release25-maint/Modules/socketmodule.c (original) +++ python/branches/release25-maint/Modules/socketmodule.c Tue Feb 13 13:14:29 2007 @@ -4363,7 +4363,9 @@ PyModule_AddIntConstant(m, "NETLINK_ROUTE6", NETLINK_ROUTE6); #endif PyModule_AddIntConstant(m, "NETLINK_IP6_FW", NETLINK_IP6_FW); +#ifdef NETLINK_DNRTMSG PyModule_AddIntConstant(m, "NETLINK_DNRTMSG", NETLINK_DNRTMSG); +#endif #ifdef NETLINK_TAPBASE PyModule_AddIntConstant(m, "NETLINK_TAPBASE", NETLINK_TAPBASE); #endif From buildbot at python.org Tue Feb 13 15:53:04 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 13 Feb 2007 14:53:04 +0000 Subject: [Python-checkins] buildbot warnings in alpha Tru64 5.1 trunk Message-ID: <20070213145304.3B96A1E400F@bag.python.org> The Buildbot has detected a new failure of alpha Tru64 5.1 trunk. Full details are available at: http://www.python.org/dev/buildbot/all/alpha%2520Tru64%25205.1%2520trunk/builds/1405 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_socket sincerely, -The Buildbot From buildbot at python.org Tue Feb 13 16:39:34 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 13 Feb 2007 15:39:34 +0000 Subject: [Python-checkins] buildbot warnings in x86 Ubuntu edgy (icc) trunk Message-ID: <20070213153934.541721E400F@bag.python.org> The Buildbot has detected a new failure of x86 Ubuntu edgy (icc) trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520Ubuntu%2520edgy%2520%2528icc%2529%2520trunk/builds/1185 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_timeout ====================================================================== FAIL: testConnectTimeout (test.test_timeout.TimeoutTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/test/test_timeout.py", line 128, in testConnectTimeout %(_delta, self.fuzz, _timeout)) AssertionError: timeout (3.38121) is more than 2 seconds more than expected (0.001) sincerely, -The Buildbot From python-checkins at python.org Tue Feb 13 17:09:25 2007 From: python-checkins at python.org (lars.gustaebel) Date: Tue, 13 Feb 2007 17:09:25 +0100 (CET) Subject: [Python-checkins] r53771 - in python/trunk: Lib/gzip.py Lib/test/test_gzip.py Misc/NEWS Message-ID: <20070213160925.86A031E400F@bag.python.org> Author: lars.gustaebel Date: Tue Feb 13 17:09:24 2007 New Revision: 53771 Modified: python/trunk/Lib/gzip.py python/trunk/Lib/test/test_gzip.py python/trunk/Misc/NEWS Log: Patch #1647484: Renamed GzipFile's filename attribute to name. The filename attribute is still accessible as a property that emits a DeprecationWarning. Modified: python/trunk/Lib/gzip.py ============================================================================== --- python/trunk/Lib/gzip.py (original) +++ python/trunk/Lib/gzip.py Tue Feb 13 17:09:24 2007 @@ -106,7 +106,7 @@ self._new_member = True self.extrabuf = "" self.extrasize = 0 - self.filename = filename + self.name = filename # Starts small, scales exponentially self.min_readsize = 100 @@ -127,14 +127,20 @@ if self.mode == WRITE: self._write_gzip_header() + @property + def filename(self): + import warnings + warnings.warn("use the name attribute", DeprecationWarning) + if self.mode == WRITE and self.name[-3:] != ".gz": + return self.name + ".gz" + return self.name + def __repr__(self): s = repr(self.fileobj) return '' def _init_write(self, filename): - if filename[-3:] != '.gz': - filename = filename + '.gz' - self.filename = filename + self.name = filename self.crc = zlib.crc32("") self.size = 0 self.writebuf = [] @@ -143,16 +149,15 @@ def _write_gzip_header(self): self.fileobj.write('\037\213') # magic header self.fileobj.write('\010') # compression method - fname = self.filename[:-3] flags = 0 - if fname: + if self.name: flags = FNAME self.fileobj.write(chr(flags)) write32u(self.fileobj, long(time.time())) self.fileobj.write('\002') self.fileobj.write('\377') - if fname: - self.fileobj.write(fname + '\000') + if self.name: + self.fileobj.write(self.name + '\000') def _init_read(self): self.crc = zlib.crc32("") Modified: python/trunk/Lib/test/test_gzip.py ============================================================================== --- python/trunk/Lib/test/test_gzip.py (original) +++ python/trunk/Lib/test/test_gzip.py Tue Feb 13 17:09:24 2007 @@ -153,6 +153,13 @@ self.assertEqual(f.myfileobj.mode, 'rb') f.close() + def test_1647484(self): + for mode in ('wb', 'rb'): + f = gzip.GzipFile(self.filename, mode) + self.assert_(hasattr(f, "name")) + self.assertEqual(f.name, self.filename) + f.close() + def test_main(verbose=None): test_support.run_unittest(TestGzip) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Feb 13 17:09:24 2007 @@ -128,6 +128,8 @@ Library ------- +- Patch #1647484: Renamed GzipFile's filename attribute to name. + - Patch #1517891: Mode 'a' for ZipFile now creates the file if it doesn't exist. From python-checkins at python.org Tue Feb 13 17:24:00 2007 From: python-checkins at python.org (lars.gustaebel) Date: Tue, 13 Feb 2007 17:24:00 +0100 (CET) Subject: [Python-checkins] r53772 - python/trunk/Lib/gzip.py Message-ID: <20070213162400.ED07C1E400F@bag.python.org> Author: lars.gustaebel Date: Tue Feb 13 17:24:00 2007 New Revision: 53772 Modified: python/trunk/Lib/gzip.py Log: Strip the '.gz' extension from the filename that is written to the gzip header. Modified: python/trunk/Lib/gzip.py ============================================================================== --- python/trunk/Lib/gzip.py (original) +++ python/trunk/Lib/gzip.py Tue Feb 13 17:24:00 2007 @@ -149,15 +149,18 @@ def _write_gzip_header(self): self.fileobj.write('\037\213') # magic header self.fileobj.write('\010') # compression method + fname = self.name + if fname.endswith(".gz"): + fname = fname[:-3] flags = 0 - if self.name: + if fname: flags = FNAME self.fileobj.write(chr(flags)) write32u(self.fileobj, long(time.time())) self.fileobj.write('\002') self.fileobj.write('\377') - if self.name: - self.fileobj.write(self.name + '\000') + if fname: + self.fileobj.write(fname + '\000') def _init_read(self): self.crc = zlib.crc32("") From buildbot at python.org Tue Feb 13 18:18:12 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 13 Feb 2007 17:18:12 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.5 Message-ID: <20070213171812.74F3A1E4005@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520gentoo%25202.5/builds/229 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Layne': Hamza Build Source Stamp: [branch Miles] Anibal Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Tue Feb 13 18:19:42 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 13 Feb 2007 17:19:42 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 2.5 Message-ID: <20070213171942.B8E291E4005@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%2520gentoo%25202.5/builds/231 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Terry': Royce Build Source Stamp: [branch Aldo] Arron Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Tue Feb 13 18:30:44 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 13 Feb 2007 17:30:44 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 2.5 Message-ID: <20070213173044.8CE3C1E4005@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%2520solaris10%2520gcc%25202.5/builds/222 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Chaim': Jaime Build Source Stamp: [branch Gannon] Rey Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Tue Feb 13 18:33:00 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 13 Feb 2007 17:33:00 +0000 Subject: [Python-checkins] buildbot failure in x86 OpenBSD 2.5 Message-ID: <20070213173300.D05951E4005@bag.python.org> The Buildbot has detected a new failure of x86 OpenBSD 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520OpenBSD%25202.5/builds/208 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Elian': Luc Build Source Stamp: [branch Allen] Dan Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Tue Feb 13 18:37:12 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 13 Feb 2007 17:37:12 +0000 Subject: [Python-checkins] buildbot failure in g4 osx.4 2.5 Message-ID: <20070213173712.804D51E4005@bag.python.org> The Buildbot has detected a new failure of g4 osx.4 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/g4%2520osx.4%25202.5/builds/216 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Elliott': Rolando Build Source Stamp: [branch Destin] Jordy Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Tue Feb 13 23:02:28 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 13 Feb 2007 22:02:28 +0000 Subject: [Python-checkins] buildbot failure in x86 XP 2.5 Message-ID: <20070213220228.7A2951E4007@bag.python.org> The Buildbot has detected a new failure of x86 XP 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520XP%25202.5/builds/115 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Weston': Kelly Build Source Stamp: [branch Neal] Brady Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From python-checkins at python.org Wed Feb 14 11:07:39 2007 From: python-checkins at python.org (martin.v.loewis) Date: Wed, 14 Feb 2007 11:07:39 +0100 (CET) Subject: [Python-checkins] r53774 - in python/trunk: Misc/NEWS Modules/socketmodule.c Modules/socketmodule.h Message-ID: <20070214100739.527271E4015@bag.python.org> Author: martin.v.loewis Date: Wed Feb 14 11:07:37 2007 New Revision: 53774 Modified: python/trunk/Misc/NEWS python/trunk/Modules/socketmodule.c python/trunk/Modules/socketmodule.h Log: Patch #1432399: Add HCI sockets. Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Feb 14 11:07:37 2007 @@ -366,6 +366,8 @@ Extension Modules ----------------- +- Patch #1432399: Support the HCI protocol for bluetooth sockets + - Patch #1657276: Make NETLINK_DNRTMSG conditional. - Bug #1653736: Complain about keyword arguments to time.isoformat. Modified: python/trunk/Modules/socketmodule.c ============================================================================== --- python/trunk/Modules/socketmodule.c (original) +++ python/trunk/Modules/socketmodule.c Wed Feb 14 11:07:37 2007 @@ -362,20 +362,25 @@ #if defined(__FreeBSD__) #define BTPROTO_L2CAP BLUETOOTH_PROTO_L2CAP #define BTPROTO_RFCOMM BLUETOOTH_PROTO_RFCOMM +#define BTPROTO_HCI BLUETOOTH_PROTO_HCI #define sockaddr_l2 sockaddr_l2cap #define sockaddr_rc sockaddr_rfcomm #define _BT_L2_MEMB(sa, memb) ((sa)->l2cap_##memb) #define _BT_RC_MEMB(sa, memb) ((sa)->rfcomm_##memb) +#define _BT_HCI_MEMB(sa, memb) ((sa)->hci_##memb) #elif defined(__NetBSD__) #define sockaddr_l2 sockaddr_bt #define sockaddr_rc sockaddr_bt +#define sockaddr_hci sockaddr_bt #define sockaddr_sco sockaddr_bt #define _BT_L2_MEMB(sa, memb) ((sa)->bt_##memb) #define _BT_RC_MEMB(sa, memb) ((sa)->bt_##memb) +#define _BT_HCI_MEMB(sa, memb) ((sa)->bt_##memb) #define _BT_SCO_MEMB(sa, memb) ((sa)->bt_##memb) #else #define _BT_L2_MEMB(sa, memb) ((sa)->l2_##memb) #define _BT_RC_MEMB(sa, memb) ((sa)->rc_##memb) +#define _BT_HCI_MEMB(sa, memb) ((sa)->hci_##memb) #define _BT_SCO_MEMB(sa, memb) ((sa)->sco_##memb) #endif #endif @@ -1119,6 +1124,14 @@ return ret; } + case BTPROTO_HCI: + { + struct sockaddr_hci *a = (struct sockaddr_hci *) addr; + PyObject *ret = NULL; + ret = Py_BuildValue("i", _BT_HCI_MEMB(a, dev)); + return ret; + } + #if !defined(__FreeBSD__) case BTPROTO_SCO: { @@ -1347,6 +1360,19 @@ *len_ret = sizeof *addr; return 1; } + case BTPROTO_HCI: + { + struct sockaddr_hci *addr = (struct sockaddr_hci *) _BT_SOCKADDR_MEMB(s, hci); + _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH; + if (!PyArg_ParseTuple(args, "i", &_BT_HCI_MEMB(addr, dev))) { + PyErr_SetString(socket_error, "getsockaddrarg: " + "wrong format"); + return 0; + } + *addr_ret = (struct sockaddr *) addr; + *len_ret = sizeof *addr; + return 1; + } #if !defined(__FreeBSD__) case BTPROTO_SCO: { @@ -1485,6 +1511,9 @@ case BTPROTO_RFCOMM: *len_ret = sizeof (struct sockaddr_rc); return 1; + case BTPROTO_HCI: + *len_ret = sizeof (struct sockaddr_hci); + return 1; #if !defined(__FreeBSD__) case BTPROTO_SCO: *len_ret = sizeof (struct sockaddr_sco); @@ -4430,6 +4459,11 @@ #ifdef USE_BLUETOOTH PyModule_AddIntConstant(m, "AF_BLUETOOTH", AF_BLUETOOTH); PyModule_AddIntConstant(m, "BTPROTO_L2CAP", BTPROTO_L2CAP); + PyModule_AddIntConstant(m, "BTPROTO_HCI", BTPROTO_HCI); + PyModule_AddIntConstant(m, "SOL_HCI", SOL_HCI); + PyModule_AddIntConstant(m, "HCI_TIME_STAMP", HCI_TIME_STAMP); + PyModule_AddIntConstant(m, "HCI_DATA_DIR", HCI_DATA_DIR); + PyModule_AddIntConstant(m, "HCI_FILTER", HCI_FILTER); #if !defined(__FreeBSD__) PyModule_AddIntConstant(m, "BTPROTO_SCO", BTPROTO_SCO); #endif Modified: python/trunk/Modules/socketmodule.h ============================================================================== --- python/trunk/Modules/socketmodule.h (original) +++ python/trunk/Modules/socketmodule.h Wed Feb 14 11:07:37 2007 @@ -46,6 +46,7 @@ #include #include #include +#include #endif #ifdef HAVE_BLUETOOTH_H @@ -98,6 +99,7 @@ struct sockaddr_l2 bt_l2; struct sockaddr_rc bt_rc; struct sockaddr_sco bt_sco; + struct sockaddr_hci bt_hci; #endif #ifdef HAVE_NETPACKET_PACKET_H struct sockaddr_ll ll; From buildbot at python.org Wed Feb 14 11:49:23 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 14 Feb 2007 10:49:23 +0000 Subject: [Python-checkins] buildbot warnings in ppc Debian unstable trunk Message-ID: <20070214104923.9B57D1E4015@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%2520Debian%2520unstable%2520trunk/builds/73 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 6 tests failed: test___all__ test_cookielib test_mimetools test_pickletools test_pyclbr test_site Traceback (most recent call last): File "./Lib/test/regrtest.py", line 1381, in main() File "./Lib/test/regrtest.py", line 416, in main e = _ExpectedSkips() File "./Lib/test/regrtest.py", line 1318, in __init__ from test import test_socket_ssl File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/test/test_socket_ssl.py", line 5, in import socket File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/socket.py", line 45, in import _socket ImportError: No module named _socket make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Wed Feb 14 11:51:19 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 14 Feb 2007 10:51:19 +0000 Subject: [Python-checkins] buildbot warnings in PPC64 Debian trunk Message-ID: <20070214105119.51FC61E4015@bag.python.org> The Buildbot has detected a new failure of PPC64 Debian trunk. Full details are available at: http://www.python.org/dev/buildbot/all/PPC64%2520Debian%2520trunk/builds/72 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 6 tests failed: test___all__ test_cookielib test_mimetools test_pickletools test_pyclbr test_site Traceback (most recent call last): File "./Lib/test/regrtest.py", line 1381, in main() File "./Lib/test/regrtest.py", line 416, in main e = _ExpectedSkips() File "./Lib/test/regrtest.py", line 1318, in __init__ from test import test_socket_ssl File "/home/pybot/buildarea64/trunk.klose-debian-ppc64/build/Lib/test/test_socket_ssl.py", line 5, in import socket File "/home/pybot/buildarea64/trunk.klose-debian-ppc64/build/Lib/socket.py", line 45, in import _socket ImportError: No module named _socket make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Wed Feb 14 12:02:13 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 14 Feb 2007 11:02:13 +0000 Subject: [Python-checkins] buildbot warnings in S-390 Debian trunk Message-ID: <20070214110213.C6BE71E4015@bag.python.org> The Buildbot has detected a new failure of S-390 Debian trunk. Full details are available at: http://www.python.org/dev/buildbot/all/S-390%2520Debian%2520trunk/builds/673 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 5 tests failed: test___all__ test_cookielib test_mimetools test_pickletools test_pyclbr Traceback (most recent call last): File "./Lib/test/regrtest.py", line 1381, in main() File "./Lib/test/regrtest.py", line 416, in main e = _ExpectedSkips() File "./Lib/test/regrtest.py", line 1318, in __init__ from test import test_socket_ssl File "/home/pybot/buildarea/trunk.klose-debian-s390/build/Lib/test/test_socket_ssl.py", line 5, in import socket File "/home/pybot/buildarea/trunk.klose-debian-s390/build/Lib/socket.py", line 45, in import _socket ImportError: No module named _socket make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Wed Feb 14 12:14:39 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 14 Feb 2007 11:14:39 +0000 Subject: [Python-checkins] buildbot warnings in x86 Ubuntu edgy (icc) trunk Message-ID: <20070214111439.82D211E4016@bag.python.org> The Buildbot has detected a new failure of x86 Ubuntu edgy (icc) trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520Ubuntu%2520edgy%2520%2528icc%2529%2520trunk/builds/1188 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: Traceback (most recent call last): File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/bsddb/test/test_thread.py", line 281, in readerThread rec = dbutils.DeadlockWrap(c.next, max_retries=10) File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/bsddb/dbutils.py", line 62, in DeadlockWrap return function(*_args, **_kwargs) DBLockDeadlockError: (-30995, 'DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock') Traceback (most recent call last): File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/bsddb/test/test_thread.py", line 281, in readerThread rec = dbutils.DeadlockWrap(c.next, max_retries=10) File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/bsddb/dbutils.py", line 62, in DeadlockWrap return function(*_args, **_kwargs) DBLockDeadlockError: (-30995, 'DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock') Traceback (most recent call last): File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/bsddb/test/test_thread.py", line 281, in readerThread rec = dbutils.DeadlockWrap(c.next, max_retries=10) File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/bsddb/dbutils.py", line 62, in DeadlockWrap return function(*_args, **_kwargs) DBLockDeadlockError: (-30995, 'DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock') 6 tests failed: test___all__ test_cookielib test_mimetools test_pickletools test_pyclbr test_site Traceback (most recent call last): File "./Lib/test/regrtest.py", line 1381, in main() File "./Lib/test/regrtest.py", line 416, in main e = _ExpectedSkips() File "./Lib/test/regrtest.py", line 1318, in __init__ from test import test_socket_ssl File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/test/test_socket_ssl.py", line 5, in import socket File "/home/buildbot/Buildbot/trunk.baxter-ubuntu/build/Lib/socket.py", line 45, in import _socket ImportError: No module named _socket sincerely, -The Buildbot From python-checkins at python.org Wed Feb 14 12:30:08 2007 From: python-checkins at python.org (martin.v.loewis) Date: Wed, 14 Feb 2007 12:30:08 +0100 (CET) Subject: [Python-checkins] r53775 - python/trunk/Modules/socketmodule.c Message-ID: <20070214113008.44E871E4016@bag.python.org> Author: martin.v.loewis Date: Wed Feb 14 12:30:07 2007 New Revision: 53775 Modified: python/trunk/Modules/socketmodule.c Log: Update 1432399 to removal of _BT_SOCKADDR_MEMB. Modified: python/trunk/Modules/socketmodule.c ============================================================================== --- python/trunk/Modules/socketmodule.c (original) +++ python/trunk/Modules/socketmodule.c Wed Feb 14 12:30:07 2007 @@ -1362,14 +1362,13 @@ } case BTPROTO_HCI: { - struct sockaddr_hci *addr = (struct sockaddr_hci *) _BT_SOCKADDR_MEMB(s, hci); + struct sockaddr_hci *addr = (struct sockaddr_hci *)addr_ret; _BT_HCI_MEMB(addr, family) = AF_BLUETOOTH; if (!PyArg_ParseTuple(args, "i", &_BT_HCI_MEMB(addr, dev))) { PyErr_SetString(socket_error, "getsockaddrarg: " "wrong format"); return 0; } - *addr_ret = (struct sockaddr *) addr; *len_ret = sizeof *addr; return 1; } From python-checkins at python.org Wed Feb 14 12:30:56 2007 From: python-checkins at python.org (martin.v.loewis) Date: Wed, 14 Feb 2007 12:30:56 +0100 (CET) Subject: [Python-checkins] r53776 - python/trunk/setup.py Message-ID: <20070214113056.C8C3B1E4016@bag.python.org> Author: martin.v.loewis Date: Wed Feb 14 12:30:56 2007 New Revision: 53776 Modified: python/trunk/setup.py Log: Ignore directory time stamps when considering whether to rerun libffi configure. Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Wed Feb 14 12:30:56 2007 @@ -1319,7 +1319,8 @@ from distutils.dep_util import newer_group config_sources = [os.path.join(ffi_srcdir, fname) - for fname in os.listdir(ffi_srcdir)] + for fname in os.listdir(ffi_srcdir) + if os.path.isfile(os.path.join(ffi_srcdir, fname))] if self.force or newer_group(config_sources, ffi_configfile): from distutils.dir_util import mkpath From python-checkins at python.org Wed Feb 14 13:53:42 2007 From: python-checkins at python.org (martin.v.loewis) Date: Wed, 14 Feb 2007 13:53:42 +0100 (CET) Subject: [Python-checkins] r53777 - python/branches/release25-maint/setup.py Message-ID: <20070214125342.AA8161E4016@bag.python.org> Author: martin.v.loewis Date: Wed Feb 14 13:53:41 2007 New Revision: 53777 Modified: python/branches/release25-maint/setup.py Log: Backport 53776: Ignore directory time stamps when considering whether to rerun libffi configure. Modified: python/branches/release25-maint/setup.py ============================================================================== --- python/branches/release25-maint/setup.py (original) +++ python/branches/release25-maint/setup.py Wed Feb 14 13:53:41 2007 @@ -1316,7 +1316,8 @@ from distutils.dep_util import newer_group config_sources = [os.path.join(ffi_srcdir, fname) - for fname in os.listdir(ffi_srcdir)] + for fname in os.listdir(ffi_srcdir) + if os.path.isfile(os.path.join(ffi_srcdir, fname))] if self.force or newer_group(config_sources, ffi_configfile): from distutils.dir_util import mkpath From buildbot at python.org Wed Feb 14 14:08:13 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 14 Feb 2007 13:08:13 +0000 Subject: [Python-checkins] buildbot warnings in MIPS Debian trunk Message-ID: <20070214130813.CC7FB1E4016@bag.python.org> The Buildbot has detected a new failure of MIPS Debian trunk. Full details are available at: http://www.python.org/dev/buildbot/all/MIPS%2520Debian%2520trunk/builds/618 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 5 tests failed: test___all__ test_cookielib test_mimetools test_pyclbr test_site Traceback (most recent call last): File "./Lib/test/regrtest.py", line 1381, in main() File "./Lib/test/regrtest.py", line 416, in main e = _ExpectedSkips() File "./Lib/test/regrtest.py", line 1318, in __init__ from test import test_socket_ssl File "/home/pybot/buildarea/trunk.klose-debian-mips/build/Lib/test/test_socket_ssl.py", line 5, in import socket File "/home/pybot/buildarea/trunk.klose-debian-mips/build/Lib/socket.py", line 45, in import _socket ImportError: No module named _socket make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Wed Feb 14 15:45:13 2007 From: python-checkins at python.org (lars.gustaebel) Date: Wed, 14 Feb 2007 15:45:13 +0100 (CET) Subject: [Python-checkins] r53778 - python/trunk/Lib/test/test_tarfile.py Message-ID: <20070214144513.A3F621E401F@bag.python.org> Author: lars.gustaebel Date: Wed Feb 14 15:45:12 2007 New Revision: 53778 Modified: python/trunk/Lib/test/test_tarfile.py Log: A missing binary mode in AppendTest caused failures in Windows Buildbot. Modified: python/trunk/Lib/test/test_tarfile.py ============================================================================== --- python/trunk/Lib/test/test_tarfile.py (original) +++ python/trunk/Lib/test/test_tarfile.py Wed Feb 14 15:45:12 2007 @@ -336,7 +336,7 @@ self._test() def test_empty(self): - open(self.tarname, "w").close() + open(self.tarname, "wb").close() self._add_testfile() self._test() @@ -348,7 +348,7 @@ def test_fileobj(self): self._create_testtar() - data = open(self.tarname).read() + data = open(self.tarname, "rb").read() fobj = StringIO.StringIO(data) self._add_testfile(fobj) fobj.seek(0) From thomas at python.org Wed Feb 14 20:13:20 2007 From: thomas at python.org (Thomas Wouters) Date: Wed, 14 Feb 2007 11:13:20 -0800 Subject: [Python-checkins] r53672 - in python/branches/release25-maint: Lib/test/test_datetime.py Misc/NEWS Modules/datetimemodule.c In-Reply-To: <20070208091352.8FC4B1E4005@bag.python.org> References: <20070208091352.8FC4B1E4005@bag.python.org> Message-ID: <9e804ac0702141113x13f68b41g59e5abd5e255ce03@mail.gmail.com> This should not be backported; it introduces a new exception where there previously was just working (albeit potentially bugged) code. (I'm working through some backlog, so apologies if someone caught it already.) On 2/8/07, martin.v.loewis < python-checkins at python.org> wrote: > > Author: martin.v.loewis > Date: Thu Feb 8 10:13:51 2007 > New Revision: 53672 > > Modified: > python/branches/release25-maint/Lib/test/test_datetime.py > python/branches/release25-maint/Misc/NEWS > python/branches/release25-maint/Modules/datetimemodule.c > Log: > Bug #1653736: Complain about keyword arguments to time.isoformat. > > > Modified: python/branches/release25-maint/Lib/test/test_datetime.py > ============================================================================== > > --- python/branches/release25-maint/Lib/test/test_datetime.py (original) > +++ python/branches/release25-maint/Lib/test/test_datetime.py Thu Feb 8 > 10:13:51 2007 > @@ -1740,6 +1740,11 @@ > self.assertEqual (t.isoformat(), "00:00:00.100000") > self.assertEqual(t.isoformat(), str(t)) > > + def test_1653736(self): > + # verify it doesn't accept extra keyword arguments > + t = self.theclass (second=1) > + self.assertRaises(TypeError, t.isoformat, foo=3) > + > def test_strftime(self): > t = self.theclass(1, 2, 3, 4) > self.assertEqual(t.strftime('%H %M %S'), "01 02 03") > > Modified: python/branches/release25-maint/Misc/NEWS > > ============================================================================== > --- python/branches/release25-maint/Misc/NEWS (original) > +++ python/branches/release25-maint/Misc/NEWS Thu Feb 8 10:13:51 2007 > @@ -105,6 +105,8 @@ > Extension Modules > ----------------- > > +- Bug #1653736: Complain about keyword arguments to time.isoformat. > + > - operator.count() now raises an OverflowError when the count reaches > sys.maxint. > > - Bug #1575169: operator.isSequenceType() now returns False for subclasses > of dict. > > Modified: python/branches/release25-maint/Modules/datetimemodule.c > ============================================================================== > > --- python/branches/release25-maint/Modules/datetimemodule.c (original) > +++ python/branches/release25-maint/Modules/datetimemodule.c Thu Feb 8 > 10:13:51 2007 > @@ -3167,7 +3167,7 @@ > } > > static PyObject * > -time_isoformat(PyDateTime_Time *self) > +time_isoformat(PyDateTime_Time *self, PyObject *unused) > { > char buf[100]; > PyObject *result; > @@ -3411,7 +3411,7 @@ > > static PyMethodDef time_methods[] = { > > - {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS, > + {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS, > PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]" > "[+HH:MM].")}, > > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > -- Thomas Wouters Hi! I'm a .signature virus! copy me into your .signature file to help me spread! -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/python-checkins/attachments/20070214/6e5765d7/attachment-0001.htm From martin at v.loewis.de Wed Feb 14 20:35:50 2007 From: martin at v.loewis.de (=?UTF-8?B?Ik1hcnRpbiB2LiBMw7Z3aXMi?=) Date: Wed, 14 Feb 2007 20:35:50 +0100 Subject: [Python-checkins] r53672 - in python/branches/release25-maint: Lib/test/test_datetime.py Misc/NEWS Modules/datetimemodule.c In-Reply-To: <9e804ac0702141113x13f68b41g59e5abd5e255ce03@mail.gmail.com> References: <20070208091352.8FC4B1E4005@bag.python.org> <9e804ac0702141113x13f68b41g59e5abd5e255ce03@mail.gmail.com> Message-ID: <45D36496.50700@v.loewis.de> Thomas Wouters schrieb: > This should not be backported; it introduces a new exception where there > previously was just working (albeit potentially bugged) code. (I'm > working through some backlog, so apologies if someone caught it already.) Ok. It still should be backported, but to not reject the arguments. Instead, the signature of the function should match its MethodDef entry. Regards, Martin From python-checkins at python.org Thu Feb 15 10:51:38 2007 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 15 Feb 2007 10:51:38 +0100 (CET) Subject: [Python-checkins] r53782 - python/trunk/Objects/dictnotes.txt Message-ID: <20070215095138.A42641E401A@bag.python.org> Author: martin.v.loewis Date: Thu Feb 15 10:51:35 2007 New Revision: 53782 Modified: python/trunk/Objects/dictnotes.txt Log: Patch #1397848: add the reasoning behind no-resize-on-shrinkage. Modified: python/trunk/Objects/dictnotes.txt ============================================================================== --- python/trunk/Objects/dictnotes.txt (original) +++ python/trunk/Objects/dictnotes.txt Thu Feb 15 10:51:35 2007 @@ -98,6 +98,17 @@ depending on the size of the dictionary. Setting to *4 eliminates every other resize step. +* Maximum sparseness (minimum dictionary load). What percentage + of entries can be unused before the dictionary shrinks to + free up memory and speed up iteration? (The current CPython + code does not represent this parameter directly.) + +* Shrinkage rate upon exceeding maximum sparseness. The current + CPython code never even checks sparseness when deleting a + key. When a new key is added, it resizes based on the number + of active keys, so that the addition may trigger shrinkage + rather than growth. + Tune-ups should be measured across a broad range of applications and use cases. A change to any parameter will help in some situations and hurt in others. The key is to find settings that help the most common @@ -115,6 +126,15 @@ Also, every dictionary iterates at least twice, once for the memset() when it is created and once by dealloc(). +Dictionary operations involving only a single key can be O(1) unless +resizing is possible. By checking for a resize only when the +dictionary can grow (and may *require* resizing), other operations +remain O(1), and the odds of resize thrashing or memory fragmentation +are reduced. In particular, an algorithm that empties a dictionary +by repeatedly invoking .pop will see no resizing, which might +not be necessary at all because the dictionary is eventually +discarded entirely. + Results of Cache Locality Experiments ------------------------------------- From python-checkins at python.org Thu Feb 15 11:38:00 2007 From: python-checkins at python.org (georg.brandl) Date: Thu, 15 Feb 2007 11:38:00 +0100 (CET) Subject: [Python-checkins] r53783 - python/trunk/Doc/lib/libfunctools.tex Message-ID: <20070215103800.1026F1E4019@bag.python.org> Author: georg.brandl Date: Thu Feb 15 11:37:59 2007 New Revision: 53783 Modified: python/trunk/Doc/lib/libfunctools.tex Log: Make functools.wraps() docs a bit clearer. Modified: python/trunk/Doc/lib/libfunctools.tex ============================================================================== --- python/trunk/Doc/lib/libfunctools.tex (original) +++ python/trunk/Doc/lib/libfunctools.tex Thu Feb 15 11:37:59 2007 @@ -53,15 +53,16 @@ \begin{funcdesc}{update_wrapper} {wrapper, wrapped\optional{, assigned}\optional{, updated}} -Update a wrapper function to look like the wrapped function. The optional -arguments are tuples to specify which attributes of the original +Update a \var{wrapper} function to look like the \var{wrapped} function. +The optional arguments are tuples to specify which attributes of the original function are assigned directly to the matching attributes on the wrapper function and which attributes of the wrapper function are updated with the corresponding attributes from the original function. The default values for these arguments are the module level constants -\var{WRAPPER_ASSIGNMENTS} (which assigns to the wrapper function's name, -module and documentation string) and \var{WRAPPER_UPDATES} (which -updates the wrapper function's instance dictionary). +\var{WRAPPER_ASSIGNMENTS} (which assigns to the wrapper function's +\var{__name__}, \var{__module__} and \var{__doc__}, the documentation string) +and \var{WRAPPER_UPDATES} (which updates the wrapper function's \var{__dict__}, +i.e. the instance dictionary). The main intended use for this function is in decorator functions which wrap the decorated function and return the wrapper. If the @@ -85,6 +86,7 @@ ... >>> @my_decorator ... def example(): + ... """Docstring""" ... print 'Called example function' ... >>> example() @@ -92,9 +94,12 @@ Called example function >>> example.__name__ 'example' + >>> example.__doc__ + 'Docstring' \end{verbatim} Without the use of this decorator factory, the name of the example -function would have been \code{'wrapper'}. +function would have been \code{'wrapper'}, and the docstring of the +original \function{example()} would have been lost. \end{funcdesc} From python-checkins at python.org Thu Feb 15 11:38:03 2007 From: python-checkins at python.org (georg.brandl) Date: Thu, 15 Feb 2007 11:38:03 +0100 (CET) Subject: [Python-checkins] r53784 - python/branches/release25-maint/Doc/lib/libfunctools.tex Message-ID: <20070215103803.BFB841E401D@bag.python.org> Author: georg.brandl Date: Thu Feb 15 11:38:03 2007 New Revision: 53784 Modified: python/branches/release25-maint/Doc/lib/libfunctools.tex Log: Make functools.wraps() docs a bit clearer. (backport from rev. 53783) Modified: python/branches/release25-maint/Doc/lib/libfunctools.tex ============================================================================== --- python/branches/release25-maint/Doc/lib/libfunctools.tex (original) +++ python/branches/release25-maint/Doc/lib/libfunctools.tex Thu Feb 15 11:38:03 2007 @@ -53,15 +53,16 @@ \begin{funcdesc}{update_wrapper} {wrapper, wrapped\optional{, assigned}\optional{, updated}} -Update a wrapper function to look like the wrapped function. The optional -arguments are tuples to specify which attributes of the original +Update a \var{wrapper} function to look like the \var{wrapped} function. +The optional arguments are tuples to specify which attributes of the original function are assigned directly to the matching attributes on the wrapper function and which attributes of the wrapper function are updated with the corresponding attributes from the original function. The default values for these arguments are the module level constants -\var{WRAPPER_ASSIGNMENTS} (which assigns to the wrapper function's name, -module and documentation string) and \var{WRAPPER_UPDATES} (which -updates the wrapper function's instance dictionary). +\var{WRAPPER_ASSIGNMENTS} (which assigns to the wrapper function's +\var{__name__}, \var{__module__} and \var{__doc__}, the documentation string) +and \var{WRAPPER_UPDATES} (which updates the wrapper function's \var{__dict__}, +i.e. the instance dictionary). The main intended use for this function is in decorator functions which wrap the decorated function and return the wrapper. If the @@ -85,6 +86,7 @@ ... >>> @my_decorator ... def example(): + ... """Docstring""" ... print 'Called example function' ... >>> example() @@ -92,9 +94,12 @@ Called example function >>> example.__name__ 'example' + >>> example.__doc__ + 'Docstring' \end{verbatim} Without the use of this decorator factory, the name of the example -function would have been \code{'wrapper'}. +function would have been \code{'wrapper'}, and the docstring of the +original \function{example()} would have been lost. \end{funcdesc} From buildbot at python.org Thu Feb 15 11:49:33 2007 From: buildbot at python.org (buildbot at python.org) Date: Thu, 15 Feb 2007 10:49:33 +0000 Subject: [Python-checkins] buildbot warnings in alpha Tru64 5.1 trunk Message-ID: <20070215104933.9BF1F1E4019@bag.python.org> The Buildbot has detected a new failure of alpha Tru64 5.1 trunk. Full details are available at: http://www.python.org/dev/buildbot/all/alpha%2520Tru64%25205.1%2520trunk/builds/1411 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_socket ====================================================================== FAIL: testInterruptedTimeout (test.test_socket.TCPTimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/net/ringneck/scratch1/nnorwitz/python/trunk.norwitz-tru64/build/Lib/test/test_socket.py", line 886, in testInterruptedTimeout self.fail("got Alarm in wrong place") AssertionError: got Alarm in wrong place sincerely, -The Buildbot From python-checkins at python.org Thu Feb 15 12:29:05 2007 From: python-checkins at python.org (georg.brandl) Date: Thu, 15 Feb 2007 12:29:05 +0100 (CET) Subject: [Python-checkins] r53785 - in python/trunk: Doc/lib/libstruct.tex Misc/NEWS Message-ID: <20070215112905.691071E4019@bag.python.org> Author: georg.brandl Date: Thu Feb 15 12:29:04 2007 New Revision: 53785 Modified: python/trunk/Doc/lib/libstruct.tex python/trunk/Misc/NEWS Log: Patch #1494140: Add documentation for the new struct.Struct object. Modified: python/trunk/Doc/lib/libstruct.tex ============================================================================== --- python/trunk/Doc/lib/libstruct.tex (original) +++ python/trunk/Doc/lib/libstruct.tex Thu Feb 15 12:29:04 2007 @@ -29,6 +29,13 @@ exactly. \end{funcdesc} +\begin{funcdesc}{pack_into}{fmt, buffer, offset, v1, v2, \moreargs} + Pack the values \code{\var{v1}, \var{v2}, \textrm{\ldots}} according to the given + format, write the packed bytes into the writable \var{buffer} starting at + \var{offset}. + Note that the offset is not an optional argument. +\end{funcdesc} + \begin{funcdesc}{unpack}{fmt, string} Unpack the string (presumably packed by \code{pack(\var{fmt}, \textrm{\ldots})}) according to the given format. The result is a @@ -37,6 +44,14 @@ (\code{len(\var{string})} must equal \code{calcsize(\var{fmt})}). \end{funcdesc} +\begin{funcdesc}{unpack_from}{fmt, buffer\optional{,offset \code{= 0}}} + Unpack the \var{buffer} according to tthe given format. + The result is a tuple even if it contains exactly one item. The + \var{buffer} must contain at least the amount of data required by the + format (\code{len(buffer[offset:])} must be at least + \code{calcsize(\var{fmt})}). +\end{funcdesc} + \begin{funcdesc}{calcsize}{fmt} Return the size of the struct (and hence of the string) corresponding to the given format. @@ -208,3 +223,43 @@ \seemodule{array}{Packed binary storage of homogeneous data.} \seemodule{xdrlib}{Packing and unpacking of XDR data.} \end{seealso} + +\subsection{Struct Objects \label{struct-objects}} + +The \module{struct} module also defines the following type: + +\begin{classdesc}{Struct}{format} + Return a new Struct object which writes and reads binary data according to + the format string \var{format}. Creating a Struct object once and calling + its methods is more efficient than calling the \module{struct} functions + with the same format since the format string only needs to be compiled once. + + \versionadded{2.5} +\end{classdesc} + +Compiled Struct objects support the following methods and attributes: + +\begin{methoddesc}[Struct]{pack}{v1, v2, \moreargs} + Identical to the \function{pack()} function, using the compiled format. + (\code{len(result)} will equal \member{self.size}.) +\end{methoddesc} + +\begin{methoddesc}[Struct]{pack_into}{buffer, offset, v1, v2, \moreargs} + Identical to the \function{pack_into()} function, using the compiled format. +\end{methoddesc} + +\begin{methoddesc}[Struct]{unpack}{string} + Identical to the \function{unpack()} function, using the compiled format. + (\code{len(string)} must equal \member{self.size}). +\end{methoddesc} + +\begin{methoddesc}[Struct]{unpack_from}{buffer\optional{,offset + \code{= 0}}} + Identical to the \function{unpack_from()} function, using the compiled format. + (\code{len(buffer[offset:])} must be at least \member{self.size}). +\end{methoddesc} + +\begin{memberdesc}[Struct]{format} + The format string used to construct this Struct object. +\end{memberdesc} + Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Feb 15 12:29:04 2007 @@ -366,6 +366,8 @@ Extension Modules ----------------- +- Patch #1494140: Add documentation for the new struct.Struct object. + - Patch #1432399: Support the HCI protocol for bluetooth sockets - Patch #1657276: Make NETLINK_DNRTMSG conditional. From python-checkins at python.org Thu Feb 15 12:29:09 2007 From: python-checkins at python.org (georg.brandl) Date: Thu, 15 Feb 2007 12:29:09 +0100 (CET) Subject: [Python-checkins] r53786 - in python/branches/release25-maint: Doc/lib/libstruct.tex Misc/NEWS Message-ID: <20070215112909.D68A51E401C@bag.python.org> Author: georg.brandl Date: Thu Feb 15 12:29:08 2007 New Revision: 53786 Modified: python/branches/release25-maint/Doc/lib/libstruct.tex python/branches/release25-maint/Misc/NEWS Log: Patch #1494140: Add documentation for the new struct.Struct object. (backport from rev. 53785) Modified: python/branches/release25-maint/Doc/lib/libstruct.tex ============================================================================== --- python/branches/release25-maint/Doc/lib/libstruct.tex (original) +++ python/branches/release25-maint/Doc/lib/libstruct.tex Thu Feb 15 12:29:08 2007 @@ -29,6 +29,13 @@ exactly. \end{funcdesc} +\begin{funcdesc}{pack_into}{fmt, buffer, offset, v1, v2, \moreargs} + Pack the values \code{\var{v1}, \var{v2}, \textrm{\ldots}} according to the given + format, write the packed bytes into the writable \var{buffer} starting at + \var{offset}. + Note that the offset is not an optional argument. +\end{funcdesc} + \begin{funcdesc}{unpack}{fmt, string} Unpack the string (presumably packed by \code{pack(\var{fmt}, \textrm{\ldots})}) according to the given format. The result is a @@ -37,6 +44,14 @@ (\code{len(\var{string})} must equal \code{calcsize(\var{fmt})}). \end{funcdesc} +\begin{funcdesc}{unpack_from}{fmt, buffer\optional{,offset \code{= 0}}} + Unpack the \var{buffer} according to tthe given format. + The result is a tuple even if it contains exactly one item. The + \var{buffer} must contain at least the amount of data required by the + format (\code{len(buffer[offset:])} must be at least + \code{calcsize(\var{fmt})}). +\end{funcdesc} + \begin{funcdesc}{calcsize}{fmt} Return the size of the struct (and hence of the string) corresponding to the given format. @@ -195,3 +210,43 @@ \seemodule{array}{Packed binary storage of homogeneous data.} \seemodule{xdrlib}{Packing and unpacking of XDR data.} \end{seealso} + +\subsection{Struct Objects \label{struct-objects}} + +The \module{struct} module also defines the following type: + +\begin{classdesc}{Struct}{format} + Return a new Struct object which writes and reads binary data according to + the format string \var{format}. Creating a Struct object once and calling + its methods is more efficient than calling the \module{struct} functions + with the same format since the format string only needs to be compiled once. + + \versionadded{2.5} +\end{classdesc} + +Compiled Struct objects support the following methods and attributes: + +\begin{methoddesc}[Struct]{pack}{v1, v2, \moreargs} + Identical to the \function{pack()} function, using the compiled format. + (\code{len(result)} will equal \member{self.size}.) +\end{methoddesc} + +\begin{methoddesc}[Struct]{pack_into}{buffer, offset, v1, v2, \moreargs} + Identical to the \function{pack_into()} function, using the compiled format. +\end{methoddesc} + +\begin{methoddesc}[Struct]{unpack}{string} + Identical to the \function{unpack()} function, using the compiled format. + (\code{len(string)} must equal \member{self.size}). +\end{methoddesc} + +\begin{methoddesc}[Struct]{unpack_from}{buffer\optional{,offset + \code{= 0}}} + Identical to the \function{unpack_from()} function, using the compiled format. + (\code{len(buffer[offset:])} must be at least \member{self.size}). +\end{methoddesc} + +\begin{memberdesc}[Struct]{format} + The format string used to construct this Struct object. +\end{memberdesc} + Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Thu Feb 15 12:29:08 2007 @@ -107,6 +107,8 @@ Extension Modules ----------------- +- Patch #1494140: Add documentation for the new struct.Struct object. + - Patch #1657276: Make NETLINK_DNRTMSG conditional. - Bug #1653736: Complain about keyword arguments to time.isoformat. From python-checkins at python.org Thu Feb 15 12:29:55 2007 From: python-checkins at python.org (georg.brandl) Date: Thu, 15 Feb 2007 12:29:55 +0100 (CET) Subject: [Python-checkins] r53787 - python/trunk/Doc/lib/libstruct.tex Message-ID: <20070215112955.B514B1E4019@bag.python.org> Author: georg.brandl Date: Thu Feb 15 12:29:55 2007 New Revision: 53787 Modified: python/trunk/Doc/lib/libstruct.tex Log: Add missing \versionadded. Modified: python/trunk/Doc/lib/libstruct.tex ============================================================================== --- python/trunk/Doc/lib/libstruct.tex (original) +++ python/trunk/Doc/lib/libstruct.tex Thu Feb 15 12:29:55 2007 @@ -34,6 +34,8 @@ format, write the packed bytes into the writable \var{buffer} starting at \var{offset}. Note that the offset is not an optional argument. + + \versionadded{2.5} \end{funcdesc} \begin{funcdesc}{unpack}{fmt, string} @@ -50,6 +52,8 @@ \var{buffer} must contain at least the amount of data required by the format (\code{len(buffer[offset:])} must be at least \code{calcsize(\var{fmt})}). + + \versionadded{2.5} \end{funcdesc} \begin{funcdesc}{calcsize}{fmt} From python-checkins at python.org Thu Feb 15 12:29:58 2007 From: python-checkins at python.org (georg.brandl) Date: Thu, 15 Feb 2007 12:29:58 +0100 (CET) Subject: [Python-checkins] r53788 - python/branches/release25-maint/Doc/lib/libstruct.tex Message-ID: <20070215112958.A55AF1E4019@bag.python.org> Author: georg.brandl Date: Thu Feb 15 12:29:58 2007 New Revision: 53788 Modified: python/branches/release25-maint/Doc/lib/libstruct.tex Log: Add missing \versionadded. (backport from rev. 53787) Modified: python/branches/release25-maint/Doc/lib/libstruct.tex ============================================================================== --- python/branches/release25-maint/Doc/lib/libstruct.tex (original) +++ python/branches/release25-maint/Doc/lib/libstruct.tex Thu Feb 15 12:29:58 2007 @@ -34,6 +34,8 @@ format, write the packed bytes into the writable \var{buffer} starting at \var{offset}. Note that the offset is not an optional argument. + + \versionadded{2.5} \end{funcdesc} \begin{funcdesc}{unpack}{fmt, string} @@ -50,6 +52,8 @@ \var{buffer} must contain at least the amount of data required by the format (\code{len(buffer[offset:])} must be at least \code{calcsize(\var{fmt})}). + + \versionadded{2.5} \end{funcdesc} \begin{funcdesc}{calcsize}{fmt} From python-checkins at python.org Thu Feb 15 20:19:43 2007 From: python-checkins at python.org (phillip.eby) Date: Thu, 15 Feb 2007 20:19:43 +0100 (CET) Subject: [Python-checkins] r53790 - in sandbox/trunk/setuptools: setuptools.txt setuptools/command/develop.py Message-ID: <20070215191943.36D9A1E4019@bag.python.org> Author: phillip.eby Date: Thu Feb 15 20:19:41 2007 New Revision: 53790 Modified: sandbox/trunk/setuptools/setuptools.txt sandbox/trunk/setuptools/setuptools/command/develop.py Log: Add --egg-path option to force .egg-link files to use relative paths (allowing them to be shared across platforms on a networked drive). Modified: sandbox/trunk/setuptools/setuptools.txt ============================================================================== --- sandbox/trunk/setuptools/setuptools.txt (original) +++ sandbox/trunk/setuptools/setuptools.txt Thu Feb 15 20:19:41 2007 @@ -1888,6 +1888,15 @@ a requirement can be met using a distribution that is already available in a directory on ``sys.path``, it will not be copied to the staging area. +``--egg-path=DIR`` + Force the generated ``.egg-link`` file to use a specified relative path + to the source directory. This can be useful in circumstances where your + installation directory is being shared by code running under multiple + platforms (e.g. Mac and Windows) which have different absolute locations + for the code under development, but the same *relative* locations with + respect to the installation directory. If you use this option when + installing, you must supply the same relative path when uninstalling. + In addition to the above options, the ``develop`` command also accepts all of the same options accepted by ``easy_install``. If you've configured any ``easy_install`` settings in your ``setup.cfg`` (or other distutils config Modified: sandbox/trunk/setuptools/setuptools/command/develop.py ============================================================================== --- sandbox/trunk/setuptools/setuptools/command/develop.py (original) +++ sandbox/trunk/setuptools/setuptools/command/develop.py Thu Feb 15 20:19:41 2007 @@ -12,6 +12,7 @@ user_options = easy_install.user_options + [ ("uninstall", "u", "Uninstall this source package"), + ("egg-path=", None, "Set the path to be used in the .egg-link file"), ] boolean_options = easy_install.boolean_options + ['uninstall'] @@ -28,6 +29,7 @@ def initialize_options(self): self.uninstall = None + self.egg_path = None easy_install.initialize_options(self) @@ -37,8 +39,6 @@ - - def finalize_options(self): ei = self.get_finalized_command("egg_info") if ei.broken_egg_info: @@ -50,14 +50,36 @@ easy_install.finalize_options(self) self.egg_link = os.path.join(self.install_dir, ei.egg_name+'.egg-link') self.egg_base = ei.egg_base - self.egg_path = os.path.abspath(ei.egg_base) + + if self.egg_path is None: + self.egg_path = os.path.abspath(ei.egg_base) + + target = normalize_path(self.egg_base) + if normalize_path(os.path.join(self.install_dir, self.egg_path)) != target: + raise DistutilsOptionError( + "--egg-path must be a relative path from the install" + " directory to "+target + ) + # Make a distribution for the package's source self.dist = Distribution( - normalize_path(self.egg_path), - PathMetadata(self.egg_path, os.path.abspath(ei.egg_info)), + target, + PathMetadata(target, os.path.abspath(ei.egg_info)), project_name = ei.egg_name ) + + + + + + + + + + + + def install_for_development(self): # Ensure metadata is up-to-date self.run_command('egg_info') @@ -75,11 +97,11 @@ f = open(self.egg_link,"w") f.write(self.egg_path) f.close() - # postprocess the installed distro, fixing up .pth, installing scripts, # and handling requirements self.process_distribution(None, self.dist, not self.no_deps) + def uninstall_link(self): if os.path.exists(self.egg_link): log.info("Removing %s (link to %s)", self.egg_link, self.egg_base) @@ -96,6 +118,9 @@ log.warn("Note: you must uninstall or replace scripts manually!") + + + def install_egg_scripts(self, dist): if dist is not self.dist: # Installing a dependency, so fall back to normal behavior @@ -121,3 +146,19 @@ + + + + + + + + + + + + + + + + From python-checkins at python.org Thu Feb 15 20:22:20 2007 From: python-checkins at python.org (phillip.eby) Date: Thu, 15 Feb 2007 20:22:20 +0100 (CET) Subject: [Python-checkins] r53791 - in sandbox/branches/setuptools-0.6: setuptools.txt setuptools/command/develop.py Message-ID: <20070215192220.2EC6C1E4019@bag.python.org> Author: phillip.eby Date: Thu Feb 15 20:22:19 2007 New Revision: 53791 Modified: sandbox/branches/setuptools-0.6/setuptools.txt sandbox/branches/setuptools-0.6/setuptools/command/develop.py Log: Added ``--egg-path`` option to ``develop`` command, allowing you to force ``.egg-link`` files to use relative paths (allowing them to be shared across platforms on a networked drive). (backport from trunk) Modified: sandbox/branches/setuptools-0.6/setuptools.txt ============================================================================== --- sandbox/branches/setuptools-0.6/setuptools.txt (original) +++ sandbox/branches/setuptools-0.6/setuptools.txt Thu Feb 15 20:22:19 2007 @@ -1910,6 +1910,15 @@ a requirement can be met using a distribution that is already available in a directory on ``sys.path``, it will not be copied to the staging area. +``--egg-path=DIR`` + Force the generated ``.egg-link`` file to use a specified relative path + to the source directory. This can be useful in circumstances where your + installation directory is being shared by code running under multiple + platforms (e.g. Mac and Windows) which have different absolute locations + for the code under development, but the same *relative* locations with + respect to the installation directory. If you use this option when + installing, you must supply the same relative path when uninstalling. + In addition to the above options, the ``develop`` command also accepts all of the same options accepted by ``easy_install``. If you've configured any ``easy_install`` settings in your ``setup.cfg`` (or other distutils config @@ -2601,6 +2610,10 @@ ---------------------------- 0.6c6 + * Added ``--egg-path`` option to ``develop`` command, allowing you to force + ``.egg-link`` files to use relative paths (allowing them to be shared across + platforms on a networked drive). + * Fix not building binary RPMs correctly. * Fix "eggsecutables" (such as setuptools' own egg) only being runnable with Modified: sandbox/branches/setuptools-0.6/setuptools/command/develop.py ============================================================================== --- sandbox/branches/setuptools-0.6/setuptools/command/develop.py (original) +++ sandbox/branches/setuptools-0.6/setuptools/command/develop.py Thu Feb 15 20:22:19 2007 @@ -12,6 +12,7 @@ user_options = easy_install.user_options + [ ("uninstall", "u", "Uninstall this source package"), + ("egg-path=", None, "Set the path to be used in the .egg-link file"), ] boolean_options = easy_install.boolean_options + ['uninstall'] @@ -28,6 +29,7 @@ def initialize_options(self): self.uninstall = None + self.egg_path = None easy_install.initialize_options(self) @@ -37,8 +39,6 @@ - - def finalize_options(self): ei = self.get_finalized_command("egg_info") if ei.broken_egg_info: @@ -50,14 +50,36 @@ easy_install.finalize_options(self) self.egg_link = os.path.join(self.install_dir, ei.egg_name+'.egg-link') self.egg_base = ei.egg_base - self.egg_path = os.path.abspath(ei.egg_base) + + if self.egg_path is None: + self.egg_path = os.path.abspath(ei.egg_base) + + target = normalize_path(self.egg_base) + if normalize_path(os.path.join(self.install_dir, self.egg_path)) != target: + raise DistutilsOptionError( + "--egg-path must be a relative path from the install" + " directory to "+target + ) + # Make a distribution for the package's source self.dist = Distribution( - normalize_path(self.egg_path), - PathMetadata(self.egg_path, os.path.abspath(ei.egg_info)), + target, + PathMetadata(target, os.path.abspath(ei.egg_info)), project_name = ei.egg_name ) + + + + + + + + + + + + def install_for_development(self): # Ensure metadata is up-to-date self.run_command('egg_info') @@ -75,11 +97,11 @@ f = open(self.egg_link,"w") f.write(self.egg_path) f.close() - # postprocess the installed distro, fixing up .pth, installing scripts, # and handling requirements self.process_distribution(None, self.dist, not self.no_deps) + def uninstall_link(self): if os.path.exists(self.egg_link): log.info("Removing %s (link to %s)", self.egg_link, self.egg_base) @@ -96,6 +118,9 @@ log.warn("Note: you must uninstall or replace scripts manually!") + + + def install_egg_scripts(self, dist): if dist is not self.dist: # Installing a dependency, so fall back to normal behavior @@ -121,3 +146,19 @@ + + + + + + + + + + + + + + + + From python-checkins at python.org Thu Feb 15 20:35:09 2007 From: python-checkins at python.org (phillip.eby) Date: Thu, 15 Feb 2007 20:35:09 +0100 (CET) Subject: [Python-checkins] r53792 - sandbox/trunk/setuptools/pkg_resources.py Message-ID: <20070215193509.5B40E1E4019@bag.python.org> Author: phillip.eby Date: Thu Feb 15 20:35:08 2007 New Revision: 53792 Modified: sandbox/trunk/setuptools/pkg_resources.py Log: Support .egg-link paths being relative Modified: sandbox/trunk/setuptools/pkg_resources.py ============================================================================== --- sandbox/trunk/setuptools/pkg_resources.py (original) +++ sandbox/trunk/setuptools/pkg_resources.py Thu Feb 15 20:35:08 2007 @@ -1551,7 +1551,7 @@ elif not only and lower.endswith('.egg-link'): for line in file(os.path.join(path_item, entry)): if not line.strip(): continue - for item in find_distributions(line.rstrip()): + for item in find_distributions(os.path.join(path_item,line.rstrip())): yield item register_finder(pkgutil.ImpImporter, find_on_path) From python-checkins at python.org Thu Feb 15 20:37:03 2007 From: python-checkins at python.org (phillip.eby) Date: Thu, 15 Feb 2007 20:37:03 +0100 (CET) Subject: [Python-checkins] r53793 - sandbox/trunk/setuptools/doc/formats.txt Message-ID: <20070215193703.4C63D1E4019@bag.python.org> Author: phillip.eby Date: Thu Feb 15 20:37:02 2007 New Revision: 53793 Modified: sandbox/trunk/setuptools/doc/formats.txt Log: Internals updated for relative .egg-link support Modified: sandbox/trunk/setuptools/doc/formats.txt ============================================================================== --- sandbox/trunk/setuptools/doc/formats.txt (original) +++ sandbox/trunk/setuptools/doc/formats.txt Thu Feb 15 20:37:02 2007 @@ -220,7 +220,8 @@ with no newlines. This filename should be the base location of one or more eggs. That is, the name must either end in ``.egg``, or else it should be the parent directory of one or more ``.egg-info`` format eggs. - +As of setuptools 0.6c6, the path may be specified as a relative path +from the directory containing the ``.egg-link`` file. ----------------- From python-checkins at python.org Thu Feb 15 20:38:21 2007 From: python-checkins at python.org (phillip.eby) Date: Thu, 15 Feb 2007 20:38:21 +0100 (CET) Subject: [Python-checkins] r53794 - sandbox/branches/setuptools-0.6/pkg_resources.py sandbox/branches/setuptools-0.6/pkg_resources.txt Message-ID: <20070215193821.5BEEF1E401D@bag.python.org> Author: phillip.eby Date: Thu Feb 15 20:38:20 2007 New Revision: 53794 Modified: sandbox/branches/setuptools-0.6/pkg_resources.py sandbox/branches/setuptools-0.6/pkg_resources.txt Log: Actually process relative .egg-link files (backport from trunk) Modified: sandbox/branches/setuptools-0.6/pkg_resources.py ============================================================================== --- sandbox/branches/setuptools-0.6/pkg_resources.py (original) +++ sandbox/branches/setuptools-0.6/pkg_resources.py Thu Feb 15 20:38:20 2007 @@ -1633,7 +1633,7 @@ elif not only and lower.endswith('.egg-link'): for line in file(os.path.join(path_item, entry)): if not line.strip(): continue - for item in find_distributions(line.rstrip()): + for item in find_distributions(os.path.join(path_item,line.rstrip())): yield item register_finder(ImpWrapper,find_on_path) Modified: sandbox/branches/setuptools-0.6/pkg_resources.txt ============================================================================== --- sandbox/branches/setuptools-0.6/pkg_resources.txt (original) +++ sandbox/branches/setuptools-0.6/pkg_resources.txt Thu Feb 15 20:38:20 2007 @@ -1695,6 +1695,8 @@ 0.6c6 * Fix extracted C extensions not having executable permissions under Cygwin. + * Allow ``.egg-link`` files to contain relative paths. + 0.6c4 * Fix "dev" versions being considered newer than release candidates. From python-checkins at python.org Thu Feb 15 23:54:40 2007 From: python-checkins at python.org (brett.cannon) Date: Thu, 15 Feb 2007 23:54:40 +0100 (CET) Subject: [Python-checkins] r53800 - in python/trunk: Lib/encodings/__init__.py Misc/NEWS Message-ID: <20070215225440.A72841E4003@bag.python.org> Author: brett.cannon Date: Thu Feb 15 23:54:39 2007 New Revision: 53800 Modified: python/trunk/Lib/encodings/__init__.py python/trunk/Misc/NEWS Log: Update the encoding package's search function to use absolute imports when calling __import__. This helps make the expected search locations for encoding modules be more explicit. One could use an explicit value for __path__ when making the call to __import__ to force the exact location searched for encodings. This would give the most strict search path possible if one is worried about malicious code being imported. The unfortunate side-effect of that is that if __path__ was modified on 'encodings' on purpose in a safe way it would not be picked up in future __import__ calls. Modified: python/trunk/Lib/encodings/__init__.py ============================================================================== --- python/trunk/Lib/encodings/__init__.py (original) +++ python/trunk/Lib/encodings/__init__.py Thu Feb 15 23:54:39 2007 @@ -93,8 +93,10 @@ if not modname or '.' in modname: continue try: - mod = __import__('encodings.' + modname, - globals(), locals(), _import_tail) + # Import equivalent to `` from .modname import *``. + # '*' is used so that __import__ returns the desired module and not + # 'encodings' itself. + mod = __import__(modname, globals(), locals(), ['*'], 1) except ImportError: pass else: Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Feb 15 23:54:39 2007 @@ -128,6 +128,9 @@ Library ------- +- Have the encoding package's search function dynamically import using absolute + import semantics. + - Patch #1647484: Renamed GzipFile's filename attribute to name. - Patch #1517891: Mode 'a' for ZipFile now creates the file if it From mal at egenix.com Fri Feb 16 00:08:20 2007 From: mal at egenix.com (M.-A. Lemburg) Date: Fri, 16 Feb 2007 00:08:20 +0100 Subject: [Python-checkins] r53800 - in python/trunk: Lib/encodings/__init__.py Misc/NEWS In-Reply-To: <20070215225440.A72841E4003@bag.python.org> References: <20070215225440.A72841E4003@bag.python.org> Message-ID: <45D4E7E4.7030006@egenix.com> On 2007-02-15 23:54, brett.cannon wrote: > Author: brett.cannon > Date: Thu Feb 15 23:54:39 2007 > New Revision: 53800 > > Modified: > python/trunk/Lib/encodings/__init__.py > python/trunk/Misc/NEWS > Log: > Update the encoding package's search function to use absolute imports when > calling __import__. This helps make the expected search locations for encoding > modules be more explicit. Your change does not make the import absolute - to the contrary: we now have a relative import. Please change that back to the original scheme which is indeed an absolute import. If you want to make sure that the search function is not importing from encodings.encodings, then you can add a 0 parameter as last parameter to __import__(). The other changes are not necessary. Thanks. > One could use an explicit value for __path__ when making the call to __import__ > to force the exact location searched for encodings. This would give the most > strict search path possible if one is worried about malicious code being > imported. The unfortunate side-effect of that is that if __path__ was modified > on 'encodings' on purpose in a safe way it would not be picked up in future > __import__ calls. > > > Modified: python/trunk/Lib/encodings/__init__.py > ============================================================================== > --- python/trunk/Lib/encodings/__init__.py (original) > +++ python/trunk/Lib/encodings/__init__.py Thu Feb 15 23:54:39 2007 > @@ -93,8 +93,10 @@ > if not modname or '.' in modname: > continue > try: > - mod = __import__('encodings.' + modname, > - globals(), locals(), _import_tail) > + # Import equivalent to `` from .modname import *``. > + # '*' is used so that __import__ returns the desired module and not > + # 'encodings' itself. > + mod = __import__(modname, globals(), locals(), ['*'], 1) > except ImportError: > pass > else: > > Modified: python/trunk/Misc/NEWS > ============================================================================== > --- python/trunk/Misc/NEWS (original) > +++ python/trunk/Misc/NEWS Thu Feb 15 23:54:39 2007 > @@ -128,6 +128,9 @@ > Library > ------- > > +- Have the encoding package's search function dynamically import using absolute > + import semantics. > + > - Patch #1647484: Renamed GzipFile's filename attribute to name. > > - Patch #1517891: Mode 'a' for ZipFile now creates the file if it > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Feb 16 2007) >>> Python/Zope Consulting and Support ... http://www.egenix.com/ >>> mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ >>> mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/ ________________________________________________________________________ :::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: From brett at python.org Fri Feb 16 00:51:51 2007 From: brett at python.org (Brett Cannon) Date: Thu, 15 Feb 2007 15:51:51 -0800 Subject: [Python-checkins] r53800 - in python/trunk: Lib/encodings/__init__.py Misc/NEWS In-Reply-To: <45D4E7E4.7030006@egenix.com> References: <20070215225440.A72841E4003@bag.python.org> <45D4E7E4.7030006@egenix.com> Message-ID: On 2/15/07, M.-A. Lemburg wrote: > On 2007-02-15 23:54, brett.cannon wrote: > > Author: brett.cannon > > Date: Thu Feb 15 23:54:39 2007 > > New Revision: 53800 > > > > Modified: > > python/trunk/Lib/encodings/__init__.py > > python/trunk/Misc/NEWS > > Log: > > Update the encoding package's search function to use absolute imports when > > calling __import__. This helps make the expected search locations for encoding > > modules be more explicit. > > Your change does not make the import absolute - to the contrary: we > now have a relative import. > Right, but I just associate it with the absolute import PEP and the term. Probably could have called it a "new-style import" or something. > Please change that back to the original scheme which is indeed an > absolute import. Why? What's wrong with a relative import? > If you want to make sure that the search function > is not importing from encodings.encodings, then you can add > a 0 parameter as last parameter to __import__(). Right. But that will essentially do the same thing I just committed since what you are proposing will grab 'encodings' from sys.modules, pull out its __path__ entry, and then do the import from there. What I did above skips that look up for 'encodings' and instead uses the module that the function was defined in. -Brett > The other changes > are not necessary. > > Thanks. > > > One could use an explicit value for __path__ when making the call to __import__ > > to force the exact location searched for encodings. This would give the most > > strict search path possible if one is worried about malicious code being > > imported. The unfortunate side-effect of that is that if __path__ was modified > > on 'encodings' on purpose in a safe way it would not be picked up in future > > __import__ calls. > > > > > > Modified: python/trunk/Lib/encodings/__init__.py > > ============================================================================== > > --- python/trunk/Lib/encodings/__init__.py (original) > > +++ python/trunk/Lib/encodings/__init__.py Thu Feb 15 23:54:39 2007 > > @@ -93,8 +93,10 @@ > > if not modname or '.' in modname: > > continue > > try: > > - mod = __import__('encodings.' + modname, > > - globals(), locals(), _import_tail) > > + # Import equivalent to `` from .modname import *``. > > + # '*' is used so that __import__ returns the desired module and not > > + # 'encodings' itself. > > + mod = __import__(modname, globals(), locals(), ['*'], 1) > > except ImportError: > > pass > > else: > > > > Modified: python/trunk/Misc/NEWS > > ============================================================================== > > --- python/trunk/Misc/NEWS (original) > > +++ python/trunk/Misc/NEWS Thu Feb 15 23:54:39 2007 > > @@ -128,6 +128,9 @@ > > Library > > ------- > > > > +- Have the encoding package's search function dynamically import using absolute > > + import semantics. > > + > > - Patch #1647484: Renamed GzipFile's filename attribute to name. > > > > - Patch #1517891: Mode 'a' for ZipFile now creates the file if it > > _______________________________________________ > > Python-checkins mailing list > > Python-checkins at python.org > > http://mail.python.org/mailman/listinfo/python-checkins > > -- > Marc-Andre Lemburg > eGenix.com > > Professional Python Services directly from the Source (#1, Feb 16 2007) > >>> Python/Zope Consulting and Support ... http://www.egenix.com/ > >>> mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ > >>> mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/ > ________________________________________________________________________ > > :::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: > From mal at egenix.com Fri Feb 16 12:20:24 2007 From: mal at egenix.com (M.-A. Lemburg) Date: Fri, 16 Feb 2007 12:20:24 +0100 Subject: [Python-checkins] r53800 - in python/trunk: Lib/encodings/__init__.py Misc/NEWS In-Reply-To: References: <20070215225440.A72841E4003@bag.python.org> <45D4E7E4.7030006@egenix.com> Message-ID: <45D59378.60203@egenix.com> On 2007-02-16 00:51, Brett Cannon wrote: > On 2/15/07, M.-A. Lemburg wrote: >> On 2007-02-15 23:54, brett.cannon wrote: >>> Author: brett.cannon >>> Date: Thu Feb 15 23:54:39 2007 >>> New Revision: 53800 >>> >>> Modified: >>> python/trunk/Lib/encodings/__init__.py >>> python/trunk/Misc/NEWS >>> Log: >>> Update the encoding package's search function to use absolute imports when >>> calling __import__. This helps make the expected search locations for encoding >>> modules be more explicit. >> Your change does not make the import absolute - to the contrary: we >> now have a relative import. >> > > Right, but I just associate it with the absolute import PEP and the > term. Probably could have called it a "new-style import" or > something. > >> Please change that back to the original scheme which is indeed an >> absolute import. > > Why? What's wrong with a relative import? Whenever possible we should use absolute imports. Relative imports are really only necessary when you want to make packages relocatable which is not the case for the encodings package. >> If you want to make sure that the search function >> is not importing from encodings.encodings, then you can add >> a 0 parameter as last parameter to __import__(). > > Right. But that will essentially do the same thing I just committed > since what you are proposing will grab 'encodings' from sys.modules, > pull out its __path__ entry, and then do the import from there. What > I did above skips that look up for 'encodings' and instead uses the > module that the function was defined in. If you look at the import source code, you'll find that both methods turn out to do the same thing. They both end up with a lookup for 'encodings'. > -Brett > > >> The other changes >> are not necessary. >> >> Thanks. >> >>> One could use an explicit value for __path__ when making the call to __import__ >>> to force the exact location searched for encodings. This would give the most >>> strict search path possible if one is worried about malicious code being >>> imported. The unfortunate side-effect of that is that if __path__ was modified >>> on 'encodings' on purpose in a safe way it would not be picked up in future >>> __import__ calls. >>> >>> >>> Modified: python/trunk/Lib/encodings/__init__.py >>> ============================================================================== >>> --- python/trunk/Lib/encodings/__init__.py (original) >>> +++ python/trunk/Lib/encodings/__init__.py Thu Feb 15 23:54:39 2007 >>> @@ -93,8 +93,10 @@ >>> if not modname or '.' in modname: >>> continue >>> try: >>> - mod = __import__('encodings.' + modname, >>> - globals(), locals(), _import_tail) >>> + # Import equivalent to `` from .modname import *``. >>> + # '*' is used so that __import__ returns the desired module and not >>> + # 'encodings' itself. >>> + mod = __import__(modname, globals(), locals(), ['*'], 1) >>> except ImportError: >>> pass >>> else: >>> >>> Modified: python/trunk/Misc/NEWS >>> ============================================================================== >>> --- python/trunk/Misc/NEWS (original) >>> +++ python/trunk/Misc/NEWS Thu Feb 15 23:54:39 2007 >>> @@ -128,6 +128,9 @@ >>> Library >>> ------- >>> >>> +- Have the encoding package's search function dynamically import using absolute >>> + import semantics. >>> + >>> - Patch #1647484: Renamed GzipFile's filename attribute to name. >>> >>> - Patch #1517891: Mode 'a' for ZipFile now creates the file if it >>> _______________________________________________ >>> Python-checkins mailing list >>> Python-checkins at python.org >>> http://mail.python.org/mailman/listinfo/python-checkins >> -- >> Marc-Andre Lemburg >> eGenix.com >> >> Professional Python Services directly from the Source (#1, Feb 16 2007) >>>>> Python/Zope Consulting and Support ... http://www.egenix.com/ >>>>> mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ >>>>> mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/ >> ________________________________________________________________________ >> >> :::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: >> > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Feb 16 2007) >>> Python/Zope Consulting and Support ... http://www.egenix.com/ >>> mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ >>> mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/ ________________________________________________________________________ :::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! :::: From buildbot at python.org Fri Feb 16 13:02:01 2007 From: buildbot at python.org (buildbot at python.org) Date: Fri, 16 Feb 2007 12:02:01 +0000 Subject: [Python-checkins] buildbot warnings in hppa Ubuntu dapper trunk Message-ID: <20070216120201.A1FF41E4022@bag.python.org> The Buildbot has detected a new failure of hppa Ubuntu dapper trunk. Full details are available at: http://www.python.org/dev/buildbot/all/hppa%2520Ubuntu%2520dapper%2520trunk/builds/71 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: armin.rigo,brett.cannon,georg.brandl,lars.gustaebel,martin.v.loewis,skip.montanaro Build had warnings: warnings test Excerpt from the test logfile: sincerely, -The Buildbot From udgwms at weichertclark.com Fri Feb 16 13:41:17 2007 From: udgwms at weichertclark.com (Crow F.Hilary) Date: Fri, 16 Feb 2007 21:41:17 +0900 Subject: [Python-checkins] He didn't seem all that impressed though. Message-ID: <45D5A66D.1020907@jeanerette.com> An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/python-checkins/attachments/20070216/09b51bb4/attachment-0001.html -------------- next part -------------- A non-text attachment was scrubbed... Name: political.gif Type: image/gif Size: 18982 bytes Desc: not available Url : http://mail.python.org/pipermail/python-checkins/attachments/20070216/09b51bb4/attachment-0001.gif From guido at python.org Fri Feb 16 17:44:45 2007 From: guido at python.org (Guido van Rossum) Date: Fri, 16 Feb 2007 08:44:45 -0800 Subject: [Python-checkins] r53800 - in python/trunk: Lib/encodings/__init__.py Misc/NEWS In-Reply-To: <45D59378.60203@egenix.com> References: <20070215225440.A72841E4003@bag.python.org> <45D4E7E4.7030006@egenix.com> <45D59378.60203@egenix.com> Message-ID: On 2/16/07, M.-A. Lemburg wrote: > On 2007-02-16 00:51, Brett Cannon wrote: > > Why? What's wrong with a relative import? > > Whenever possible we should use absolute imports. Relative imports > are really only necessary when you want to make packages relocatable > which is not the case for the encodings package. I support this. -- --Guido van Rossum (home page: http://www.python.org/~guido/) From brett at python.org Fri Feb 16 20:23:27 2007 From: brett at python.org (Brett Cannon) Date: Fri, 16 Feb 2007 11:23:27 -0800 Subject: [Python-checkins] r53800 - in python/trunk: Lib/encodings/__init__.py Misc/NEWS In-Reply-To: <45D59378.60203@egenix.com> References: <20070215225440.A72841E4003@bag.python.org> <45D4E7E4.7030006@egenix.com> <45D59378.60203@egenix.com> Message-ID: On 2/16/07, M.-A. Lemburg wrote: > On 2007-02-16 00:51, Brett Cannon wrote: > > On 2/15/07, M.-A. Lemburg wrote: > >> On 2007-02-15 23:54, brett.cannon wrote: > >>> Author: brett.cannon > >>> Date: Thu Feb 15 23:54:39 2007 > >>> New Revision: 53800 > >>> > >>> Modified: > >>> python/trunk/Lib/encodings/__init__.py > >>> python/trunk/Misc/NEWS > >>> Log: > >>> Update the encoding package's search function to use absolute imports when > >>> calling __import__. This helps make the expected search locations for encoding > >>> modules be more explicit. > >> Your change does not make the import absolute - to the contrary: we > >> now have a relative import. > >> > > > > Right, but I just associate it with the absolute import PEP and the > > term. Probably could have called it a "new-style import" or > > something. > > > >> Please change that back to the original scheme which is indeed an > >> absolute import. > > > > Why? What's wrong with a relative import? > > Whenever possible we should use absolute imports. Relative imports > are really only necessary when you want to make packages relocatable > which is not the case for the encodings package. > True, but my motivation was to enforce importing from the 'encodings' package to prevent people from importing modules with side-effects that are not in the package. But absolute imports do the same thing, so I am running regrtest and then will check in an absolute import once that is done. -Brett From buildbot at python.org Fri Feb 16 20:31:02 2007 From: buildbot at python.org (buildbot at python.org) Date: Fri, 16 Feb 2007 19:31:02 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 2.5 Message-ID: <20070216193102.B8DF41E400B@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%2520solaris10%2520gcc%25202.5/builds/226 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Heriberto': Blaise Build Source Stamp: [branch Abram] Jonah Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Fri Feb 16 20:31:36 2007 From: buildbot at python.org (buildbot at python.org) Date: Fri, 16 Feb 2007 19:31:36 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.5 Message-ID: <20070216193136.DEEB11E400B@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520gentoo%25202.5/builds/233 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Jaylon': Rigoberto Build Source Stamp: [branch Colten] Stuart Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From mal at egenix.com Fri Feb 16 20:31:41 2007 From: mal at egenix.com (M.-A. Lemburg) Date: Fri, 16 Feb 2007 20:31:41 +0100 Subject: [Python-checkins] r53800 - in python/trunk: Lib/encodings/__init__.py Misc/NEWS In-Reply-To: References: <20070215225440.A72841E4003@bag.python.org> <45D4E7E4.7030006@egenix.com> <45D59378.60203@egenix.com> Message-ID: <45D6069D.3060307@egenix.com> On 2007-02-16 20:23, Brett Cannon wrote: > On 2/16/07, M.-A. Lemburg wrote: >> On 2007-02-16 00:51, Brett Cannon wrote: >> > On 2/15/07, M.-A. Lemburg wrote: >> >> On 2007-02-15 23:54, brett.cannon wrote: >> >>> Author: brett.cannon >> >>> Date: Thu Feb 15 23:54:39 2007 >> >>> New Revision: 53800 >> >>> >> >>> Modified: >> >>> python/trunk/Lib/encodings/__init__.py >> >>> python/trunk/Misc/NEWS >> >>> Log: >> >>> Update the encoding package's search function to use absolute >> imports when >> >>> calling __import__. This helps make the expected search locations >> for encoding >> >>> modules be more explicit. >> >> Your change does not make the import absolute - to the contrary: we >> >> now have a relative import. >> >> >> > >> > Right, but I just associate it with the absolute import PEP and the >> > term. Probably could have called it a "new-style import" or >> > something. >> > >> >> Please change that back to the original scheme which is indeed an >> >> absolute import. >> > >> > Why? What's wrong with a relative import? >> >> Whenever possible we should use absolute imports. Relative imports >> are really only necessary when you want to make packages relocatable >> which is not the case for the encodings package. >> > > True, but my motivation was to enforce importing from the 'encodings' > package to prevent people from importing modules with side-effects > that are not in the package. That was the motivation to add the "'encodings.' +" in front of the module name :-) Note that before we made that change, the fact that you could import codecs from the PYTHONPATH was actually an (undocumented) feature and used by a few people to be able to easily add their own codec packages to the global namespace. The right way to do this is to register your own search function, of course, which is why we decided to break this feature in favor of preventing DOS attacks like u"abc".encode('test.testall'). > But absolute imports do the same thing, so I am running regrtest and > then will check in an absolute import once that is done. Ok. Thanks, -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Feb 16 2007) >>> Python/Zope Consulting and Support ... http://www.egenix.com/ >>> mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ >>> mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/ ________________________________________________________________________ ::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,FreeBSD for free ! :::: From python-checkins at python.org Fri Feb 16 20:33:01 2007 From: python-checkins at python.org (brett.cannon) Date: Fri, 16 Feb 2007 20:33:01 +0100 (CET) Subject: [Python-checkins] r53801 - python/trunk/Lib/encodings/__init__.py Message-ID: <20070216193301.B25561E400B@bag.python.org> Author: brett.cannon Date: Fri Feb 16 20:33:01 2007 New Revision: 53801 Modified: python/trunk/Lib/encodings/__init__.py Log: Make the __import__ call in encodings.__init__ absolute with a level 0 call. Modified: python/trunk/Lib/encodings/__init__.py ============================================================================== --- python/trunk/Lib/encodings/__init__.py (original) +++ python/trunk/Lib/encodings/__init__.py Fri Feb 16 20:33:01 2007 @@ -93,10 +93,10 @@ if not modname or '.' in modname: continue try: - # Import equivalent to `` from .modname import *``. - # '*' is used so that __import__ returns the desired module and not - # 'encodings' itself. - mod = __import__(modname, globals(), locals(), ['*'], 1) + # Import is absolute to prevent the possibly malicious import of a + # module with side-effects that is not in the 'encodings' package. + mod = __import__('encodings.' + modname, fromlist=_import_tail, + level=0) except ImportError: pass else: From python-checkins at python.org Fri Feb 16 20:52:34 2007 From: python-checkins at python.org (brett.cannon) Date: Fri, 16 Feb 2007 20:52:34 +0100 (CET) Subject: [Python-checkins] r53802 - sandbox/trunk/import_in_py/importlib.py Message-ID: <20070216195234.0C9F71E400B@bag.python.org> Author: brett.cannon Date: Fri Feb 16 20:52:33 2007 New Revision: 53802 Modified: sandbox/trunk/import_in_py/importlib.py Log: Add a comment about whether using __path__ from globals is worth considering. Modified: sandbox/trunk/import_in_py/importlib.py ============================================================================== --- sandbox/trunk/import_in_py/importlib.py (original) +++ sandbox/trunk/import_in_py/importlib.py Fri Feb 16 20:52:33 2007 @@ -762,6 +762,13 @@ current_name = ".".join(current_name_parts) if parent_module: try: + # XXX Better to use __path__ as found in 'globals' argument + # in __call__? Possibly different if module in sys.modules + # resolves to a different one from where the import call + # was made. Not sure if this worth worrying about, though, + # since relative imports could easily negate use of + # __path__ and sys.modules is totally reasonable to + # consider the canonical modules. path_list = parent_module.__path__ except AttributeError: pass @@ -807,8 +814,8 @@ def _return_module(self, absolute_name, relative_name, fromlist): """Return the proper module based on what module was requested (and its - absolute module name), who is - requesting it, and whether any speicific attributes were specified. + absolute module name), who is requesting it, and whether any speicific + attributes were specified. The semantics of this method revolve around 'fromlist'. When it is empty, the module up to the first dot is to be returned. When the From python-checkins at python.org Fri Feb 16 23:36:25 2007 From: python-checkins at python.org (vinay.sajip) Date: Fri, 16 Feb 2007 23:36:25 +0100 (CET) Subject: [Python-checkins] r53809 - python/trunk/Lib/logging/__init__.py Message-ID: <20070216223625.11C321E4029@bag.python.org> Author: vinay.sajip Date: Fri Feb 16 23:36:24 2007 New Revision: 53809 Modified: python/trunk/Lib/logging/__init__.py Log: Minor fix for currentframe (SF #1652788). Modified: python/trunk/Lib/logging/__init__.py ============================================================================== --- python/trunk/Lib/logging/__init__.py (original) +++ python/trunk/Lib/logging/__init__.py Fri Feb 16 23:36:24 2007 @@ -1,4 +1,4 @@ -# Copyright 2001-2005 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2007 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -21,7 +21,7 @@ Should work under Python versions >= 1.5.2, except that source line information is not available unless 'sys._getframe()' is. -Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2007 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ @@ -41,8 +41,8 @@ __author__ = "Vinay Sajip " __status__ = "production" -__version__ = "0.5.0.1" -__date__ = "09 January 2007" +__version__ = "0.5.0.2" +__date__ = "16 February 2007" #--------------------------------------------------------------------------- # Miscellaneous module data @@ -68,7 +68,7 @@ except: return sys.exc_traceback.tb_frame.f_back -if hasattr(sys, '_getframe'): currentframe = sys._getframe +if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3) # done filching # _srcfile is only used in conjunction with sys._getframe(). From buildbot at python.org Sat Feb 17 00:23:54 2007 From: buildbot at python.org (buildbot at python.org) Date: Fri, 16 Feb 2007 23:23:54 +0000 Subject: [Python-checkins] buildbot warnings in ppc Debian unstable trunk Message-ID: <20070216232354.CB59E1E400B@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%2520Debian%2520unstable%2520trunk/builds/79 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: vinay.sajip Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_bsddb3 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sat Feb 17 00:26:37 2007 From: buildbot at python.org (buildbot at python.org) Date: Fri, 16 Feb 2007 23:26:37 +0000 Subject: [Python-checkins] buildbot warnings in PPC64 Debian trunk Message-ID: <20070216232637.AE6061E4014@bag.python.org> The Buildbot has detected a new failure of PPC64 Debian trunk. Full details are available at: http://www.python.org/dev/buildbot/all/PPC64%2520Debian%2520trunk/builds/78 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: vinay.sajip Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_bsddb3 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sat Feb 17 00:30:29 2007 From: buildbot at python.org (buildbot at python.org) Date: Fri, 16 Feb 2007 23:30:29 +0000 Subject: [Python-checkins] buildbot warnings in alpha Tru64 5.1 trunk Message-ID: <20070216233029.89B6D1E400B@bag.python.org> The Buildbot has detected a new failure of alpha Tru64 5.1 trunk. Full details are available at: http://www.python.org/dev/buildbot/all/alpha%2520Tru64%25205.1%2520trunk/builds/1414 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: vinay.sajip Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_socket sincerely, -The Buildbot From python-checkins at python.org Sat Feb 17 02:37:51 2007 From: python-checkins at python.org (vinay.sajip) Date: Sat, 17 Feb 2007 02:37:51 +0100 (CET) Subject: [Python-checkins] r53811 - python/branches/release25-maint/Lib/logging/__init__.py Message-ID: <20070217013751.05A8F1E4014@bag.python.org> Author: vinay.sajip Date: Sat Feb 17 02:37:50 2007 New Revision: 53811 Modified: python/branches/release25-maint/Lib/logging/__init__.py Log: Minor fix for currentframe (SF #1652788). Modified: python/branches/release25-maint/Lib/logging/__init__.py ============================================================================== --- python/branches/release25-maint/Lib/logging/__init__.py (original) +++ python/branches/release25-maint/Lib/logging/__init__.py Sat Feb 17 02:37:50 2007 @@ -1,4 +1,4 @@ -# Copyright 2001-2005 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2007 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -21,7 +21,7 @@ Should work under Python versions >= 1.5.2, except that source line information is not available unless 'sys._getframe()' is. -Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2007 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ @@ -41,8 +41,8 @@ __author__ = "Vinay Sajip " __status__ = "production" -__version__ = "0.4.9.9" -__date__ = "06 February 2006" +__version__ = "0.5.0.2" +__date__ = "16 February 2007" #--------------------------------------------------------------------------- # Miscellaneous module data @@ -68,7 +68,7 @@ except: return sys.exc_traceback.tb_frame.f_back -if hasattr(sys, '_getframe'): currentframe = sys._getframe +if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3) # done filching # _srcfile is only used in conjunction with sys._getframe(). From python-checkins at python.org Sat Feb 17 02:39:18 2007 From: python-checkins at python.org (vinay.sajip) Date: Sat, 17 Feb 2007 02:39:18 +0100 (CET) Subject: [Python-checkins] r53812 - python/branches/release24-maint/Lib/logging/__init__.py Message-ID: <20070217013918.070651E400B@bag.python.org> Author: vinay.sajip Date: Sat Feb 17 02:39:17 2007 New Revision: 53812 Modified: python/branches/release24-maint/Lib/logging/__init__.py Log: Minor fix for currentframe (SF #1652788). Modified: python/branches/release24-maint/Lib/logging/__init__.py ============================================================================== --- python/branches/release24-maint/Lib/logging/__init__.py (original) +++ python/branches/release24-maint/Lib/logging/__init__.py Sat Feb 17 02:39:17 2007 @@ -1,4 +1,4 @@ -# Copyright 2001-2005 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2007 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -21,7 +21,7 @@ Should work under Python versions >= 1.5.2, except that source line information is not available unless 'sys._getframe()' is. -Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2007 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ @@ -68,7 +68,7 @@ except: return sys.exc_traceback.tb_frame.f_back -if hasattr(sys, '_getframe'): currentframe = sys._getframe +if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3) # done filching # _srcfile is only used in conjunction with sys._getframe(). From buildbot at python.org Sat Feb 17 03:01:36 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 17 Feb 2007 02:01:36 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 2.5 Message-ID: <20070217020136.9B2851E400B@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%2520gentoo%25202.5/builds/236 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Colton': Jan Build Source Stamp: [branch Houston] Gael Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Sat Feb 17 03:04:17 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 17 Feb 2007 02:04:17 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.5 Message-ID: <20070217020418.159521E4014@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520gentoo%25202.5/builds/235 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Mauricio': Terrence Build Source Stamp: [branch Robert] Estevan Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Sat Feb 17 03:21:52 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 17 Feb 2007 02:21:52 +0000 Subject: [Python-checkins] buildbot failure in g4 osx.4 2.5 Message-ID: <20070217022153.0F7F71E400B@bag.python.org> The Buildbot has detected a new failure of g4 osx.4 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/g4%2520osx.4%25202.5/builds/221 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Desmond': Keenan Build Source Stamp: [branch Dandre] Stacey Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Sat Feb 17 03:23:57 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 17 Feb 2007 02:23:57 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 2.5 Message-ID: <20070217022357.5CAF91E400B@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%2520solaris10%2520gcc%25202.5/builds/228 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Titus': Griffin Build Source Stamp: [branch Addison] Branden Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Sat Feb 17 03:29:46 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 17 Feb 2007 02:29:46 +0000 Subject: [Python-checkins] buildbot failure in x86 XP 2.5 Message-ID: <20070217022946.DD0371E400B@bag.python.org> The Buildbot has detected a new failure of x86 XP 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520XP%25202.5/builds/120 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Rhett': Cedric Build Source Stamp: [branch Jett] Karl Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Sat Feb 17 14:29:00 2007 From: buildbot at python.org (buildbot at python.org) Date: Sat, 17 Feb 2007 13:29:00 +0000 Subject: [Python-checkins] buildbot failure in x86 cygwin 2.5 Message-ID: <20070217132901.2AC701E4014@bag.python.org> The Buildbot has detected a new failure of x86 cygwin 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520cygwin%25202.5/builds/11 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: georg.brandl,vinay.sajip BUILD FAILED: failed failed slave lost sincerely, -The Buildbot From python-checkins at python.org Sat Feb 17 18:53:46 2007 From: python-checkins at python.org (phillip.eby) Date: Sat, 17 Feb 2007 18:53:46 +0100 (CET) Subject: [Python-checkins] r53813 - sandbox/trunk/setuptools/setuptools/command/easy_install.py Message-ID: <20070217175346.6A8831E400C@bag.python.org> Author: phillip.eby Date: Sat Feb 17 18:53:45 2007 New Revision: 53813 Modified: sandbox/trunk/setuptools/setuptools/command/easy_install.py Log: Fix error if script contains null byte. Modified: sandbox/trunk/setuptools/setuptools/command/easy_install.py ============================================================================== --- sandbox/trunk/setuptools/setuptools/command/easy_install.py (original) +++ sandbox/trunk/setuptools/setuptools/command/easy_install.py Sat Feb 17 18:53:45 2007 @@ -1460,7 +1460,7 @@ "Is this string a valid Python script?" try: compile(text, filename, 'exec') - except SyntaxError: + except (SyntaxError, TypeError): return False else: return True From python-checkins at python.org Sat Feb 17 18:55:44 2007 From: python-checkins at python.org (phillip.eby) Date: Sat, 17 Feb 2007 18:55:44 +0100 (CET) Subject: [Python-checkins] r53814 - sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py Message-ID: <20070217175544.3D25D1E4028@bag.python.org> Author: phillip.eby Date: Sat Feb 17 18:55:43 2007 New Revision: 53814 Modified: sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py Log: Fix error if script contains null byte. (backport from trunk) Modified: sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py ============================================================================== --- sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py (original) +++ sandbox/branches/setuptools-0.6/setuptools/command/easy_install.py Sat Feb 17 18:55:43 2007 @@ -1460,7 +1460,7 @@ "Is this string a valid Python script?" try: compile(text, filename, 'exec') - except SyntaxError: + except (SyntaxError, TypeError): return False else: return True From python-checkins at python.org Sat Feb 17 19:42:39 2007 From: python-checkins at python.org (georg.brandl) Date: Sat, 17 Feb 2007 19:42:39 +0100 (CET) Subject: [Python-checkins] r53815 - peps/trunk/pep-0000.txt peps/trunk/pep-0226.txt peps/trunk/pep-0328.txt peps/trunk/pep-3102.txt peps/trunk/pep-3105.txt peps/trunk/pep-3106.txt peps/trunk/pep-3107.txt peps/trunk/pep-3109.txt peps/trunk/pep-3110.txt Message-ID: <20070217184239.7CCE11E400C@bag.python.org> Author: georg.brandl Date: Sat Feb 17 19:42:37 2007 New Revision: 53815 Modified: peps/trunk/pep-0000.txt peps/trunk/pep-0226.txt peps/trunk/pep-0328.txt peps/trunk/pep-3102.txt peps/trunk/pep-3105.txt peps/trunk/pep-3106.txt peps/trunk/pep-3107.txt peps/trunk/pep-3109.txt peps/trunk/pep-3110.txt Log: Mark diverse Py3000 PEPs as accepted, mark PEPs 328 and 3105 as Final. Modified: peps/trunk/pep-0000.txt ============================================================================== --- peps/trunk/pep-0000.txt (original) +++ peps/trunk/pep-0000.txt Sat Feb 17 19:42:37 2007 @@ -54,14 +54,20 @@ I 42 Feature Requests Hylton I 101 Doing Python Releases 101 Warsaw, GvR I 102 Doing Python Micro Releases Baxter, Warsaw, GvR + IF 160 Python 1.6 Release Schedule Drake + IF 200 Python 2.0 Release Schedule Hylton + IF 226 Python 2.1 Release Schedule Hylton IF 247 API for Cryptographic Hash Functions Kuchling IF 248 Python Database API Specification v1.0 Lemburg IF 249 Python Database API Specification v2.0 Lemburg + IF 251 Python 2.2 Release Schedule Warsaw, GvR I 257 Docstring Conventions Goodger, GvR IF 272 API for Block Encryption Algorithms v1.0 Kuchling + IF 283 Python 2.3 Release Schedule GvR I 290 Code Migration and Modernization Hettinger I 291 Backward Compatibility for Standard Library Norwitz I 306 How to Change Python's Grammar Hudson + IF 320 Python 2.4 Release Schedule Warsaw, et al I 333 Python Web Server Gateway Interface v1.0 Eby I 339 Design of the CPython Compiler Cannon IF 356 Python 2.5 Release Schedule Norwitz, et al @@ -71,7 +77,11 @@ Accepted PEPs (accepted; may not be implemented yet) - SA 328 Imports: Multi-Line and Absolute/Relative Aahz + SA 3102 Keyword-Only Arguments Talin + SA 3106 Revamping dict.keys(), .values() and .items() GvR + SA 3107 Function Annotations Winter, Lownds + SA 3109 Raising Exceptions in Python 3000 Winter + SA 3110 Catching Exceptions in Python 3000 Winter Open PEPs (under consideration) @@ -101,21 +111,13 @@ S 363 Syntax For Dynamic Attribute Access North S 754 IEEE 754 Floating Point Special Values Warnes S 3101 Advanced String Formatting Talin - S 3102 Keyword-Only Arguments Talin S 3103 A Switch/Case Statement GvR S 3104 Access to Names in Outer Scopes Yee - S 3105 Make print a function Brandl - S 3106 Revamping dict.keys(), .values() and .items() GvR - S 3107 Function Annotations Winter, Lownds I 3108 Standard Library Reorganization Cannon - S 3109 Raising Exceptions in Python 3000 Winter - S 3110 Catching Exceptions in Python 3000 Winter Finished PEPs (done, implemented in Subversion) SF 100 Python Unicode Integration Lemburg - IF 160 Python 1.6 Release Schedule Drake - IF 200 Python 2.0 Release Schedule Hylton SF 201 Lockstep Iteration Warsaw SF 202 List Comprehensions Warsaw SF 203 Augmented Assignments Wouters @@ -127,7 +129,6 @@ SF 218 Adding a Built-In Set Object Type Wilson, Hettinger SF 221 Import As Wouters SF 223 Change the Meaning of \x Escapes Peters - I 226 Python 2.1 Release Schedule Hylton S 227 Statically Nested Scopes Hylton SF 229 Using Distutils to Build Python Kuchling SF 230 Warning Framework GvR @@ -138,7 +139,6 @@ SF 238 Changing the Division Operator Zadka, GvR SF 241 Metadata for Python Software Packages Kuchling SF 250 Using site-packages on Windows Moore - IF 251 Python 2.2 Release Schedule Warsaw, GvR SF 252 Making Types Look More Like Classes GvR SF 253 Subtyping Built-in Types GvR SF 255 Simple Generators Schemenauer, et al @@ -151,7 +151,6 @@ SF 278 Universal Newline Support Jansen SF 279 The enumerate() built-in function Hettinger SF 282 A Logging System Sajip, Mick - IF 283 Python 2.3 Release Schedule GvR SF 285 Adding a bool type GvR SF 289 Generator Expressions Hettinger SF 292 Simpler String Substitutions Warsaw @@ -164,10 +163,10 @@ SF 311 Simplified GIL Acquisition for Extensions Hammond SF 314 Metadata for Python Software Packages v1.1 Kuchling, Jones SF 318 Decorators for Functions and Methods Smith, et al - IF 320 Python 2.4 Release Schedule Warsaw, et al SF 322 Reverse Iteration Hettinger SF 324 subprocess - New process module Astrand SF 327 Decimal Data Type Batista + SF 328 Imports: Multi-Line and Absolute/Relative Aahz SF 338 Executing Modules as Scripts Coghlan SF 341 Unifying try-except and try-finally Brandl SF 342 Coroutines via Enhanced Generators GvR, Eby @@ -175,6 +174,7 @@ SF 352 Required Superclass for Exceptions GvR, Cannon SF 353 Using ssize_t as the index type von Loewis SF 357 Allowing Any Object to be Used for Slicing Oliphant + SF 3105 Make print a function Brandl Empty PEPs (or containing only an abstract) @@ -299,7 +299,7 @@ SF 223 Change the Meaning of \x Escapes Peters SR 224 Attribute Docstrings Lemburg SD 225 Elementwise/Objectwise Operators Zhu, Lielens - I 226 Python 2.1 Release Schedule Hylton + IF 226 Python 2.1 Release Schedule Hylton S 227 Statically Nested Scopes Hylton S 228 Reworking Python's Numeric Model Zadka, GvR SF 229 Using Distutils to Build Python Kuchling @@ -400,7 +400,7 @@ SR 325 Resource-Release Support for Generators Pedroni SR 326 A Case for Top and Bottom Values Carlson, Reedy SF 327 Decimal Data Type Batista - SA 328 Imports: Multi-Line and Absolute/Relative Aahz + SF 328 Imports: Multi-Line and Absolute/Relative Aahz SR 329 Treating Builtins as Constants in the Standard Library Hettinger SR 330 Python Bytecode Verification Pelletier S 331 Locale-Independent Float/String Conversions Reis @@ -444,15 +444,15 @@ I 3099 Things that will Not Change in Python 3000 Brandl I 3100 Python 3.0 Plans Kuchling, Cannon S 3101 Advanced String Formatting Talin - S 3102 Keyword-Only Arguments Talin + SA 3102 Keyword-Only Arguments Talin S 3103 A Switch/Case Statement GvR S 3104 Access to Names in Outer Scopes Yee - S 3105 Make print a function Brandl - S 3106 Revamping dict.keys(), .values() and .items() GvR - S 3107 Function Annotations Winter, Lownds + SF 3105 Make print a function Brandl + SA 3106 Revamping dict.keys(), .values() and .items() GvR + SA 3107 Function Annotations Winter, Lownds I 3108 Standard Library Reorganization Cannon - S 3109 Raising Exceptions in Python 3000 Winter - S 3110 Catching Exceptions in Python 3000 Winter + SA 3109 Raising Exceptions in Python 3000 Winter + SA 3110 Catching Exceptions in Python 3000 Winter Key Modified: peps/trunk/pep-0226.txt ============================================================================== --- peps/trunk/pep-0226.txt (original) +++ peps/trunk/pep-0226.txt Sat Feb 17 19:42:37 2007 @@ -3,7 +3,7 @@ Version: $Revision$ Last-Modified: $Date$ Author: Jeremy Hylton -Status: Incomplete +Status: Final Type: Informational Created: 16-Oct-2000 Python-Version: 2.1 Modified: peps/trunk/pep-0328.txt ============================================================================== --- peps/trunk/pep-0328.txt (original) +++ peps/trunk/pep-0328.txt Sat Feb 17 19:42:37 2007 @@ -3,7 +3,7 @@ Version: $Revision$ Last-Modified: $Date$ Author: Aahz -Status: Accepted +Status: Final Type: Standards Track Python-Version: 2.4, 2,5, 2.6, 2.7 Content-Type: text/x-rst @@ -268,7 +268,7 @@ Relative Imports and __name__ -=============================== +============================= Relative imports use a module's __name__ attribute to determine that module's position in the package hierarchy. If the module's name does Modified: peps/trunk/pep-3102.txt ============================================================================== --- peps/trunk/pep-3102.txt (original) +++ peps/trunk/pep-3102.txt Sat Feb 17 19:42:37 2007 @@ -3,7 +3,7 @@ Version: $Revision$ Last-Modified: $Date$ Author: Talin -Status: Draft +Status: Accepted Type: Standards Content-Type: text/plain Created: 22-Apr-2006 Modified: peps/trunk/pep-3105.txt ============================================================================== --- peps/trunk/pep-3105.txt (original) +++ peps/trunk/pep-3105.txt Sat Feb 17 19:42:37 2007 @@ -3,7 +3,7 @@ Version: $Revision$ Last-Modified: $Date$ Author: Georg Brandl -Status: Draft +Status: Final Type: Standards Content-Type: text/x-rst Created: 19-Nov-2006 @@ -102,6 +102,15 @@ mentioned tool). +Implementation +============== + +The proposed changes were implemented in the Python 3000 branch in the +Subversion revisions 53685 to 53704. Most of the legacy code in the +library has been converted too, but it is an ongoing effort to catch +every print statement that may be left in the distribution. + + References ========== Modified: peps/trunk/pep-3106.txt ============================================================================== --- peps/trunk/pep-3106.txt (original) +++ peps/trunk/pep-3106.txt Sat Feb 17 19:42:37 2007 @@ -3,7 +3,7 @@ Version: $Revision$ Last-Modified: $Date$ Author: Guido van Rossum -Status: Draft +Status: Accepted Type: Standards Content-Type: text/x-rst Created: 19-Dec-2006 Modified: peps/trunk/pep-3107.txt ============================================================================== --- peps/trunk/pep-3107.txt (original) +++ peps/trunk/pep-3107.txt Sat Feb 17 19:42:37 2007 @@ -4,7 +4,7 @@ Last-Modified: $Date$ Author: Collin Winter , Tony Lownds -Status: Draft +Status: Accepted Type: Standards Track Requires: 362 Content-Type: text/x-rst Modified: peps/trunk/pep-3109.txt ============================================================================== --- peps/trunk/pep-3109.txt (original) +++ peps/trunk/pep-3109.txt Sat Feb 17 19:42:37 2007 @@ -3,7 +3,7 @@ Version: $Revision$ Last-Modified: $Date$ Author: Collin Winter -Status: Draft +Status: Accepted Type: Standards Track Content-Type: text/x-rst Created: 19-Jan-2006 Modified: peps/trunk/pep-3110.txt ============================================================================== --- peps/trunk/pep-3110.txt (original) +++ peps/trunk/pep-3110.txt Sat Feb 17 19:42:37 2007 @@ -3,7 +3,7 @@ Version: $Revision$ Last-Modified: $Date$ Author: Collin Winter -Status: Draft +Status: Accepted Type: Standards Track Content-Type: text/x-rst Created: 16-Jan-2006 From python-checkins at python.org Sun Feb 18 09:50:39 2007 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 18 Feb 2007 09:50:39 +0100 (CET) Subject: [Python-checkins] r53816 - in python/branches/release25-maint: Misc/NEWS Modules/datetimemodule.c Message-ID: <20070218085039.D2EB51E4006@bag.python.org> Author: martin.v.loewis Date: Sun Feb 18 09:50:38 2007 New Revision: 53816 Modified: python/branches/release25-maint/Misc/NEWS python/branches/release25-maint/Modules/datetimemodule.c Log: Revert r53672, just fix signature of time_isoformat instead. Modified: python/branches/release25-maint/Misc/NEWS ============================================================================== --- python/branches/release25-maint/Misc/NEWS (original) +++ python/branches/release25-maint/Misc/NEWS Sun Feb 18 09:50:38 2007 @@ -111,7 +111,7 @@ - Patch #1657276: Make NETLINK_DNRTMSG conditional. -- Bug #1653736: Complain about keyword arguments to time.isoformat. +- Bug #1653736: Fix signature of time_isoformat. - operator.count() now raises an OverflowError when the count reaches sys.maxint. Modified: python/branches/release25-maint/Modules/datetimemodule.c ============================================================================== --- python/branches/release25-maint/Modules/datetimemodule.c (original) +++ python/branches/release25-maint/Modules/datetimemodule.c Sun Feb 18 09:50:38 2007 @@ -3166,8 +3166,11 @@ return PyObject_CallMethod((PyObject *)self, "isoformat", "()"); } +/* Even though this silently ignores all arguments, it cannot + be fixed to reject them in release25-maint */ static PyObject * -time_isoformat(PyDateTime_Time *self, PyObject *unused) +time_isoformat(PyDateTime_Time *self, PyObject *unused_args, + PyObject *unused_keywords) { char buf[100]; PyObject *result; @@ -3411,7 +3414,7 @@ static PyMethodDef time_methods[] = { - {"isoformat", (PyCFunction)time_isoformat, METH_NOARGS, + {"isoformat", (PyCFunction)time_isoformat, METH_KEYWORDS, PyDoc_STR("Return string in ISO 8601 format, HH:MM:SS[.mmmmmm]" "[+HH:MM].")}, From python-checkins at python.org Sun Feb 18 09:54:33 2007 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 18 Feb 2007 09:54:33 +0100 (CET) Subject: [Python-checkins] r53817 - python/branches/release25-maint/Lib/test/test_datetime.py Message-ID: <20070218085433.694F41E4006@bag.python.org> Author: martin.v.loewis Date: Sun Feb 18 09:54:32 2007 New Revision: 53817 Modified: python/branches/release25-maint/Lib/test/test_datetime.py Log: Revert r53672. Modified: python/branches/release25-maint/Lib/test/test_datetime.py ============================================================================== --- python/branches/release25-maint/Lib/test/test_datetime.py (original) +++ python/branches/release25-maint/Lib/test/test_datetime.py Sun Feb 18 09:54:32 2007 @@ -1740,11 +1740,6 @@ self.assertEqual(t.isoformat(), "00:00:00.100000") self.assertEqual(t.isoformat(), str(t)) - def test_1653736(self): - # verify it doesn't accept extra keyword arguments - t = self.theclass(second=1) - self.assertRaises(TypeError, t.isoformat, foo=3) - def test_strftime(self): t = self.theclass(1, 2, 3, 4) self.assertEqual(t.strftime('%H %M %S'), "01 02 03") From buildbot at python.org Sun Feb 18 10:23:11 2007 From: buildbot at python.org (buildbot at python.org) Date: Sun, 18 Feb 2007 09:23:11 +0000 Subject: [Python-checkins] buildbot warnings in amd64 gentoo 2.5 Message-ID: <20070218092311.B81991E4006@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%2520gentoo%25202.5/builds/238 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_socket_ssl make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sun Feb 18 10:31:32 2007 From: buildbot at python.org (buildbot at python.org) Date: Sun, 18 Feb 2007 09:31:32 +0000 Subject: [Python-checkins] buildbot warnings in x86 gentoo 2.5 Message-ID: <20070218093132.A633B1E4006@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520gentoo%25202.5/builds/237 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch branches/release25-maint] HEAD Blamelist: martin.v.loewis Build had warnings: warnings test Excerpt from the test logfile: Traceback (most recent call last): File "/home/buildslave/python-trunk/2.5.norwitz-x86/build/Lib/threading.py", line 460, in __bootstrap self.run() File "/home/buildslave/python-trunk/2.5.norwitz-x86/build/Lib/threading.py", line 440, in run self.__target(*self.__args, **self.__kwargs) File "/home/buildslave/python-trunk/2.5.norwitz-x86/build/Lib/bsddb/test/test_thread.py", line 281, in readerThread rec = dbutils.DeadlockWrap(c.next, max_retries=10) File "/home/buildslave/python-trunk/2.5.norwitz-x86/build/Lib/bsddb/dbutils.py", line 62, in DeadlockWrap return function(*_args, **_kwargs) DBLockDeadlockError: (-30996, 'DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock') 1 test failed: test_socket_ssl make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Feb 19 03:03:23 2007 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 19 Feb 2007 03:03:23 +0100 (CET) Subject: [Python-checkins] r53818 - in python/trunk: Include/dictobject.h Lib/test/test_set.py Objects/dictobject.c Objects/setobject.c Message-ID: <20070219020323.8E0311E4006@bag.python.org> Author: raymond.hettinger Date: Mon Feb 19 03:03:19 2007 New Revision: 53818 Modified: python/trunk/Include/dictobject.h python/trunk/Lib/test/test_set.py python/trunk/Objects/dictobject.c python/trunk/Objects/setobject.c Log: Extend work on revision 52962: Eliminate redundant calls to PyObject_Hash(). Modified: python/trunk/Include/dictobject.h ============================================================================== --- python/trunk/Include/dictobject.h (original) +++ python/trunk/Include/dictobject.h Mon Feb 19 03:03:19 2007 @@ -100,12 +100,15 @@ PyAPI_FUNC(void) PyDict_Clear(PyObject *mp); PyAPI_FUNC(int) PyDict_Next( PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value); +PyAPI_FUNC(int) _PyDict_Next( + PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, long *hash); PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp); PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp); PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp); PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp); PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp); PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key); +PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, long hash); /* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */ PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other); Modified: python/trunk/Lib/test/test_set.py ============================================================================== --- python/trunk/Lib/test/test_set.py (original) +++ python/trunk/Lib/test/test_set.py Mon Feb 19 03:03:19 2007 @@ -26,6 +26,14 @@ def __repr__(self): return repr(self.value) +class HashCountingInt(int): + 'int-like object that counts the number of times __hash__ is called' + def __init__(self, *args): + self.hash_count = 0 + def __hash__(self): + self.hash_count += 1 + return int.__hash__(self) + class TestJointOps(unittest.TestCase): # Tests common to both set and frozenset @@ -270,6 +278,18 @@ fo.close() os.remove(test_support.TESTFN) + def test_do_not_rehash_dict_keys(self): + n = 10 + d = dict.fromkeys(map(HashCountingInt, xrange(n))) + self.assertEqual(sum(elem.hash_count for elem in d), n) + s = self.thetype(d) + self.assertEqual(sum(elem.hash_count for elem in d), n) + s.difference(d) + self.assertEqual(sum(elem.hash_count for elem in d), n) + if hasattr(s, 'symmetric_difference_update'): + s.symmetric_difference_update(d) + self.assertEqual(sum(elem.hash_count for elem in d), n) + class TestSet(TestJointOps): thetype = set Modified: python/trunk/Objects/dictobject.c ============================================================================== --- python/trunk/Objects/dictobject.c (original) +++ python/trunk/Objects/dictobject.c Mon Feb 19 03:03:19 2007 @@ -803,6 +803,34 @@ return 1; } +/* Internal version of PyDict_Next that returns a hash value in addition to the key and value.*/ +int +_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, long *phash) +{ + register Py_ssize_t i; + register Py_ssize_t mask; + register dictentry *ep; + + if (!PyDict_Check(op)) + return 0; + i = *ppos; + if (i < 0) + return 0; + ep = ((dictobject *)op)->ma_table; + mask = ((dictobject *)op)->ma_mask; + while (i <= mask && ep[i].me_value == NULL) + i++; + *ppos = i+1; + if (i > mask) + return 0; + *phash = (long)(ep[i].me_hash); + if (pkey) + *pkey = ep[i].me_key; + if (pvalue) + *pvalue = ep[i].me_value; + return 1; +} + /* Methods */ static void @@ -1987,6 +2015,17 @@ return ep == NULL ? -1 : (ep->me_value != NULL); } +/* Internal version of PyDict_Contains used when the hash value is already known */ +int +_PyDict_Contains(PyObject *op, PyObject *key, long hash) +{ + dictobject *mp = (dictobject *)op; + dictentry *ep; + + ep = (mp->ma_lookup)(mp, key, hash); + return ep == NULL ? -1 : (ep->me_value != NULL); +} + /* Hack to implement "key in dict" */ static PySequenceMethods dict_as_sequence = { 0, /* sq_length */ Modified: python/trunk/Objects/setobject.c ============================================================================== --- python/trunk/Objects/setobject.c (original) +++ python/trunk/Objects/setobject.c Mon Feb 19 03:03:19 2007 @@ -918,8 +918,14 @@ if (PyDict_CheckExact(other)) { PyObject *value; Py_ssize_t pos = 0; - while (PyDict_Next(other, &pos, &key, &value)) { - if (set_add_key(so, key) == -1) + long hash; + + while (_PyDict_Next(other, &pos, &key, &value, &hash)) { + setentry an_entry; + + an_entry.hash = hash; + an_entry.key = key; + if (set_add_entry(so, &an_entry) == -1) return -1; } return 0; @@ -1382,7 +1388,7 @@ setentry entrycopy; entrycopy.hash = entry->hash; entrycopy.key = entry->key; - if (!PyDict_Contains(other, entry->key)) { + if (!_PyDict_Contains(other, entry->key, entry->hash)) { if (set_add_entry((PySetObject *)result, &entrycopy) == -1) { Py_DECREF(result); return NULL; @@ -1453,12 +1459,10 @@ if (PyDict_CheckExact(other)) { PyObject *value; int rv; - while (PyDict_Next(other, &pos, &key, &value)) { + long hash; + while (_PyDict_Next(other, &pos, &key, &value, &hash)) { setentry an_entry; - long hash = PyObject_Hash(key); - if (hash == -1) - return NULL; an_entry.hash = hash; an_entry.key = key; rv = set_discard_entry(so, &an_entry); From python-checkins at python.org Mon Feb 19 04:04:46 2007 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 19 Feb 2007 04:04:46 +0100 (CET) Subject: [Python-checkins] r53819 - in python/branches/release25-maint: Include/dictobject.h Lib/test/test_set.py Objects/dictobject.c Objects/setobject.c Message-ID: <20070219030446.E2A361E4006@bag.python.org> Author: raymond.hettinger Date: Mon Feb 19 04:04:45 2007 New Revision: 53819 Modified: python/branches/release25-maint/Include/dictobject.h python/branches/release25-maint/Lib/test/test_set.py python/branches/release25-maint/Objects/dictobject.c python/branches/release25-maint/Objects/setobject.c Log: Extend work on revision 52962: Eliminate redundant calls to PyObject_Hash(). Modified: python/branches/release25-maint/Include/dictobject.h ============================================================================== --- python/branches/release25-maint/Include/dictobject.h (original) +++ python/branches/release25-maint/Include/dictobject.h Mon Feb 19 04:04:45 2007 @@ -100,12 +100,15 @@ PyAPI_FUNC(void) PyDict_Clear(PyObject *mp); PyAPI_FUNC(int) PyDict_Next( PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value); +PyAPI_FUNC(int) _PyDict_Next( + PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, long *hash); PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp); PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp); PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp); PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp); PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp); PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key); +PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, long hash); /* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */ PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other); Modified: python/branches/release25-maint/Lib/test/test_set.py ============================================================================== --- python/branches/release25-maint/Lib/test/test_set.py (original) +++ python/branches/release25-maint/Lib/test/test_set.py Mon Feb 19 04:04:45 2007 @@ -26,6 +26,14 @@ def __repr__(self): return repr(self.value) +class HashCountingInt(int): + 'int-like object that counts the number of times __hash__ is called' + def __init__(self, *args): + self.hash_count = 0 + def __hash__(self): + self.hash_count += 1 + return int.__hash__(self) + class TestJointOps(unittest.TestCase): # Tests common to both set and frozenset @@ -270,6 +278,18 @@ fo.close() os.remove(test_support.TESTFN) + def test_do_not_rehash_dict_keys(self): + n = 10 + d = dict.fromkeys(map(HashCountingInt, xrange(n))) + self.assertEqual(sum(elem.hash_count for elem in d), n) + s = self.thetype(d) + self.assertEqual(sum(elem.hash_count for elem in d), n) + s.difference(d) + self.assertEqual(sum(elem.hash_count for elem in d), n) + if hasattr(s, 'symmetric_difference_update'): + s.symmetric_difference_update(d) + self.assertEqual(sum(elem.hash_count for elem in d), n) + class TestSet(TestJointOps): thetype = set Modified: python/branches/release25-maint/Objects/dictobject.c ============================================================================== --- python/branches/release25-maint/Objects/dictobject.c (original) +++ python/branches/release25-maint/Objects/dictobject.c Mon Feb 19 04:04:45 2007 @@ -803,6 +803,34 @@ return 1; } +/* Internal version of PyDict_Next that returns a hash value in addition to the key and value.*/ +int +_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, long *phash) +{ + register Py_ssize_t i; + register Py_ssize_t mask; + register dictentry *ep; + + if (!PyDict_Check(op)) + return 0; + i = *ppos; + if (i < 0) + return 0; + ep = ((dictobject *)op)->ma_table; + mask = ((dictobject *)op)->ma_mask; + while (i <= mask && ep[i].me_value == NULL) + i++; + *ppos = i+1; + if (i > mask) + return 0; + *phash = (long)(ep[i].me_hash); + if (pkey) + *pkey = ep[i].me_key; + if (pvalue) + *pvalue = ep[i].me_value; + return 1; +} + /* Methods */ static void @@ -1987,6 +2015,17 @@ return ep == NULL ? -1 : (ep->me_value != NULL); } +/* Internal version of PyDict_Contains used when the hash value is already known */ +int +_PyDict_Contains(PyObject *op, PyObject *key, long hash) +{ + dictobject *mp = (dictobject *)op; + dictentry *ep; + + ep = (mp->ma_lookup)(mp, key, hash); + return ep == NULL ? -1 : (ep->me_value != NULL); +} + /* Hack to implement "key in dict" */ static PySequenceMethods dict_as_sequence = { 0, /* sq_length */ Modified: python/branches/release25-maint/Objects/setobject.c ============================================================================== --- python/branches/release25-maint/Objects/setobject.c (original) +++ python/branches/release25-maint/Objects/setobject.c Mon Feb 19 04:04:45 2007 @@ -918,8 +918,14 @@ if (PyDict_CheckExact(other)) { PyObject *value; Py_ssize_t pos = 0; - while (PyDict_Next(other, &pos, &key, &value)) { - if (set_add_key(so, key) == -1) + long hash; + + while (_PyDict_Next(other, &pos, &key, &value, &hash)) { + setentry an_entry; + + an_entry.hash = hash; + an_entry.key = key; + if (set_add_entry(so, &an_entry) == -1) return -1; } return 0; @@ -1382,7 +1388,7 @@ setentry entrycopy; entrycopy.hash = entry->hash; entrycopy.key = entry->key; - if (!PyDict_Contains(other, entry->key)) { + if (!_PyDict_Contains(other, entry->key, entry->hash)) { if (set_add_entry((PySetObject *)result, &entrycopy) == -1) { Py_DECREF(result); return NULL; @@ -1453,12 +1459,10 @@ if (PyDict_CheckExact(other)) { PyObject *value; int rv; - while (PyDict_Next(other, &pos, &key, &value)) { + long hash; + while (_PyDict_Next(other, &pos, &key, &value, &hash)) { setentry an_entry; - long hash = PyObject_Hash(key); - if (hash == -1) - return NULL; an_entry.hash = hash; an_entry.key = key; rv = set_discard_entry(so, &an_entry); From python-checkins at python.org Mon Feb 19 05:08:48 2007 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 19 Feb 2007 05:08:48 +0100 (CET) Subject: [Python-checkins] r53820 - in python/trunk: Doc/lib/libheapq.tex Lib/heapq.py Lib/test/test_heapq.py Misc/NEWS Message-ID: <20070219040848.0FFCE1E4006@bag.python.org> Author: raymond.hettinger Date: Mon Feb 19 05:08:43 2007 New Revision: 53820 Modified: python/trunk/Doc/lib/libheapq.tex python/trunk/Lib/heapq.py python/trunk/Lib/test/test_heapq.py python/trunk/Misc/NEWS Log: Add merge() function to heapq. Modified: python/trunk/Doc/lib/libheapq.tex ============================================================================== --- python/trunk/Doc/lib/libheapq.tex (original) +++ python/trunk/Doc/lib/libheapq.tex Mon Feb 19 05:08:43 2007 @@ -88,7 +88,18 @@ >>> \end{verbatim} -The module also offers two general purpose functions based on heaps. +The module also offers three general purpose functions based on heaps. + +\begin{funcdesc}{merge}{*iterables} +Merge multiple sorted inputs into a single sorted output (for example, merge +timestamped entries from multiple log files). Returns an iterator over +over the sorted values. + +Similar to \code{sorted(itertools.chain(*iterables))} but returns an iterable, +does not pull the data into memory all at once, and reduces the number of +comparisons by assuming that each of the input streams is already sorted. +\versionadded{2.6} +\end{funcdesc} \begin{funcdesc}{nlargest}{n, iterable\optional{, key}} Return a list with the \var{n} largest elements from the dataset defined @@ -110,7 +121,7 @@ \versionchanged[Added the optional \var{key} argument]{2.5} \end{funcdesc} -Both functions perform best for smaller values of \var{n}. For larger +The latter two functions perform best for smaller values of \var{n}. For larger values, it is more efficient to use the \function{sorted()} function. Also, when \code{n==1}, it is more efficient to use the builtin \function{min()} and \function{max()} functions. Modified: python/trunk/Lib/heapq.py ============================================================================== --- python/trunk/Lib/heapq.py (original) +++ python/trunk/Lib/heapq.py Mon Feb 19 05:08:43 2007 @@ -126,8 +126,8 @@ From all times, sorting has always been a Great Art! :-) """ -__all__ = ['heappush', 'heappop', 'heapify', 'heapreplace', 'nlargest', - 'nsmallest'] +__all__ = ['heappush', 'heappop', 'heapify', 'heapreplace', 'merge', + 'nlargest', 'nsmallest'] from itertools import islice, repeat, count, imap, izip, tee from operator import itemgetter, neg @@ -308,6 +308,41 @@ except ImportError: pass +def merge(*iterables): + '''Merge multiple sorted inputs into a single sorted output. + + Similar to sorted(itertools.chain(*iterables)) but returns an iterable, + does not pull the data into memory all at once, and reduces the number + of comparisons by assuming that each of the input streams is already sorted. + + >>> list(merge([1,3,5,7], [0,2,4,8], [5,10,15,20], [], [25])) + [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25] + + ''' + _heappop, siftup, _StopIteration = heappop, _siftup, StopIteration + + h = [] + h_append = h.append + for it in map(iter, iterables): + try: + next = it.next + h_append([next(), next]) + except _StopIteration: + pass + heapify(h) + + while 1: + try: + while 1: + v, next = s = h[0] # raises IndexError when h is empty + yield v + s[0] = next() # raises StopIteration when exhausted + siftup(h, 0) # restore heap condition + except _StopIteration: + _heappop(h) # remove empty iterator + except IndexError: + return + # Extend the implementations of nsmallest and nlargest to use a key= argument _nsmallest = nsmallest def nsmallest(n, iterable, key=None): @@ -341,3 +376,6 @@ while heap: sort.append(heappop(heap)) print sort + + import doctest + doctest.testmod() Modified: python/trunk/Lib/test/test_heapq.py ============================================================================== --- python/trunk/Lib/test/test_heapq.py (original) +++ python/trunk/Lib/test/test_heapq.py Mon Feb 19 05:08:43 2007 @@ -1,6 +1,6 @@ """Unittests for heapq.""" -from heapq import heappush, heappop, heapify, heapreplace, nlargest, nsmallest +from heapq import heappush, heappop, heapify, heapreplace, merge, nlargest, nsmallest import random import unittest from test import test_support @@ -103,6 +103,14 @@ heap_sorted = [heappop(heap) for i in range(size)] self.assertEqual(heap_sorted, sorted(data)) + def test_merge(self): + inputs = [] + for i in xrange(random.randrange(5)): + row = sorted(random.randrange(1000) for j in range(random.randrange(10))) + inputs.append(row) + self.assertEqual(sorted(chain(*inputs)), list(merge(*inputs))) + self.assertEqual(list(merge()), []) + def test_nsmallest(self): data = [(random.randrange(2000), i) for i in range(1000)] for f in (None, lambda x: x[0] * 547 % 2000): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Feb 19 05:08:43 2007 @@ -128,6 +128,8 @@ Library ------- +- Added heapq.merge() for merging sorted input streams. + - Have the encoding package's search function dynamically import using absolute import semantics. From python-checkins at python.org Mon Feb 19 06:28:34 2007 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 19 Feb 2007 06:28:34 +0100 (CET) Subject: [Python-checkins] r53821 - python/trunk/Lib/heapq.py Message-ID: <20070219052834.418491E4006@bag.python.org> Author: raymond.hettinger Date: Mon Feb 19 06:28:28 2007 New Revision: 53821 Modified: python/trunk/Lib/heapq.py Log: Add tie-breaker count to preserve sort stability. Modified: python/trunk/Lib/heapq.py ============================================================================== --- python/trunk/Lib/heapq.py (original) +++ python/trunk/Lib/heapq.py Mon Feb 19 06:28:28 2007 @@ -323,10 +323,10 @@ h = [] h_append = h.append - for it in map(iter, iterables): + for itnum, it in enumerate(map(iter, iterables)): try: next = it.next - h_append([next(), next]) + h_append([next(), itnum, next]) except _StopIteration: pass heapify(h) @@ -334,12 +334,12 @@ while 1: try: while 1: - v, next = s = h[0] # raises IndexError when h is empty + v, itnum, next = s = h[0] # raises IndexError when h is empty yield v - s[0] = next() # raises StopIteration when exhausted - siftup(h, 0) # restore heap condition + s[0] = next() # raises StopIteration when exhausted + siftup(h, 0) # restore heap condition except _StopIteration: - _heappop(h) # remove empty iterator + _heappop(h) # remove empty iterator except IndexError: return From buildbot at python.org Mon Feb 19 07:40:25 2007 From: buildbot at python.org (buildbot at python.org) Date: Mon, 19 Feb 2007 06:40:25 +0000 Subject: [Python-checkins] buildbot warnings in x86 Ubuntu edgy (icc) trunk Message-ID: <20070219064025.EA6921E400C@bag.python.org> The Buildbot has detected a new failure of x86 Ubuntu edgy (icc) trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520Ubuntu%2520edgy%2520%2528icc%2529%2520trunk/builds/1197 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_timeout sincerely, -The Buildbot From python-checkins at python.org Mon Feb 19 07:59:32 2007 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 19 Feb 2007 07:59:32 +0100 (CET) Subject: [Python-checkins] r53822 - python/trunk/Lib/heapq.py Message-ID: <20070219065932.BAEB31E4006@bag.python.org> Author: raymond.hettinger Date: Mon Feb 19 07:59:32 2007 New Revision: 53822 Modified: python/trunk/Lib/heapq.py Log: Use C heapreplace() instead of slower _siftup() in pure python. Modified: python/trunk/Lib/heapq.py ============================================================================== --- python/trunk/Lib/heapq.py (original) +++ python/trunk/Lib/heapq.py Mon Feb 19 07:59:32 2007 @@ -319,7 +319,7 @@ [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25] ''' - _heappop, siftup, _StopIteration = heappop, _siftup, StopIteration + _heappop, _heapreplace, _StopIteration = heappop, heapreplace, StopIteration h = [] h_append = h.append @@ -337,7 +337,7 @@ v, itnum, next = s = h[0] # raises IndexError when h is empty yield v s[0] = next() # raises StopIteration when exhausted - siftup(h, 0) # restore heap condition + _heapreplace(h, s) # restore heap condition except _StopIteration: _heappop(h) # remove empty iterator except IndexError: From python-checkins at python.org Mon Feb 19 08:30:21 2007 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 19 Feb 2007 08:30:21 +0100 (CET) Subject: [Python-checkins] r53823 - python/trunk/Lib/test/test_heapq.py Message-ID: <20070219073021.ED1071E4006@bag.python.org> Author: raymond.hettinger Date: Mon Feb 19 08:30:21 2007 New Revision: 53823 Modified: python/trunk/Lib/test/test_heapq.py Log: Add test for merge stability Modified: python/trunk/Lib/test/test_heapq.py ============================================================================== --- python/trunk/Lib/test/test_heapq.py (original) +++ python/trunk/Lib/test/test_heapq.py Mon Feb 19 08:30:21 2007 @@ -111,6 +111,21 @@ self.assertEqual(sorted(chain(*inputs)), list(merge(*inputs))) self.assertEqual(list(merge()), []) + def test_merge_stability(self): + class Int(int): + pass + inputs = [[], [], [], []] + for i in range(20000): + stream = random.randrange(4) + x = random.randrange(500) + obj = Int(x) + obj.pair = (x, stream) + inputs[stream].append(obj) + for stream in inputs: + stream.sort() + result = [i.pair for i in merge(*inputs)] + self.assertEqual(result, sorted(result)) + def test_nsmallest(self): data = [(random.randrange(2000), i) for i in range(1000)] for f in (None, lambda x: x[0] * 547 % 2000): From buildbot at python.org Mon Feb 19 09:11:15 2007 From: buildbot at python.org (buildbot at python.org) Date: Mon, 19 Feb 2007 08:11:15 +0000 Subject: [Python-checkins] buildbot warnings in ppc Debian unstable trunk Message-ID: <20070219081115.7EC1D1E401B@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%2520Debian%2520unstable%2520trunk/builds/84 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_timeout make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Mon Feb 19 09:14:33 2007 From: buildbot at python.org (buildbot at python.org) Date: Mon, 19 Feb 2007 08:14:33 +0000 Subject: [Python-checkins] buildbot warnings in PPC64 Debian trunk Message-ID: <20070219081433.F39551E4006@bag.python.org> The Buildbot has detected a new failure of PPC64 Debian trunk. Full details are available at: http://www.python.org/dev/buildbot/all/PPC64%2520Debian%2520trunk/builds/83 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_timeout make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Feb 19 10:14:10 2007 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 19 Feb 2007 10:14:10 +0100 (CET) Subject: [Python-checkins] r53824 - python/trunk/Doc/lib/libcollections.tex Message-ID: <20070219091410.002D61E4006@bag.python.org> Author: raymond.hettinger Date: Mon Feb 19 10:14:10 2007 New Revision: 53824 Modified: python/trunk/Doc/lib/libcollections.tex Log: Provide an example of defaultdict with non-zero constant factory function. Modified: python/trunk/Doc/lib/libcollections.tex ============================================================================== --- python/trunk/Doc/lib/libcollections.tex (original) +++ python/trunk/Doc/lib/libcollections.tex Mon Feb 19 10:14:10 2007 @@ -311,16 +311,20 @@ When a letter is first encountered, it is missing from the mapping, so the \member{default_factory} function calls \function{int()} to supply a default count of zero. The increment operation then builds up the count for each -letter. This technique makes counting simpler and faster than an equivalent -technique using \method{dict.get()}: +letter. -\begin{verbatim} ->>> d = {} ->>> for k in s: - d[k] = d.get(k, 0) + 1 +The function \function{int()} which always returns zero is just a special +case of constant functions. A faster and more flexible way to create +constant functions is to use \function{itertools.repeat()} which can supply +any constant value (not just zero): ->>> d.items() -[('i', 4), ('p', 2), ('s', 4), ('m', 1)] +\begin{verbatim} +>>> def constant_factory(value): +... return itertools.repeat(value).next +>>> d = defaultdict(constant_factory('')) +>>> d.update(name='John', action='ran') +>>> '%(name)s %(action)s to %(object)s' % d +'John ran to ' \end{verbatim} Setting the \member{default_factory} to \class{set} makes the From python-checkins at python.org Mon Feb 19 10:54:49 2007 From: python-checkins at python.org (lars.gustaebel) Date: Mon, 19 Feb 2007 10:54:49 +0100 (CET) Subject: [Python-checkins] r53825 - python/trunk/Misc/NEWS Message-ID: <20070219095449.C2B971E4006@bag.python.org> Author: lars.gustaebel Date: Mon Feb 19 10:54:47 2007 New Revision: 53825 Modified: python/trunk/Misc/NEWS Log: Moved misplaced news item. Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Feb 19 10:54:47 2007 @@ -26,9 +26,6 @@ - patch #1630975: Fix crash when replacing sys.stdout in sitecustomize.py -- Patch #1507247: tarfile.py: use current umask for intermediate - directories. - - Bug #1637022: Prefix AST symbols with _Py_. - Prevent seg fault on shutdown which could occur if an object @@ -167,6 +164,9 @@ - Patch #1643874: memory leak in ctypes fixed. +- Patch #1507247: tarfile.py: use current umask for intermediate + directories. + - Patch #1627441: close sockets properly in urllib2. - Bug #494589: make ntpath.expandvars behave according to its docstring. From python-checkins at python.org Mon Feb 19 11:55:33 2007 From: python-checkins at python.org (martin.v.loewis) Date: Mon, 19 Feb 2007 11:55:33 +0100 (CET) Subject: [Python-checkins] r53826 - in python/trunk: Doc/lib/libos.tex Doc/lib/libshutil.tex Lib/shutil.py Lib/stat.py Lib/test/test_posix.py Misc/ACKS Misc/NEWS Modules/posixmodule.c configure configure.in pyconfig.h.in Message-ID: <20070219105533.EB7D41E4006@bag.python.org> Author: martin.v.loewis Date: Mon Feb 19 11:55:19 2007 New Revision: 53826 Modified: python/trunk/Doc/lib/libos.tex python/trunk/Doc/lib/libshutil.tex python/trunk/Lib/shutil.py python/trunk/Lib/stat.py python/trunk/Lib/test/test_posix.py python/trunk/Misc/ACKS python/trunk/Misc/NEWS python/trunk/Modules/posixmodule.c python/trunk/configure python/trunk/configure.in python/trunk/pyconfig.h.in Log: Patch #1490190: posixmodule now includes os.chflags() and os.lchflags() functions on platforms where the underlying system calls are available. Modified: python/trunk/Doc/lib/libos.tex ============================================================================== --- python/trunk/Doc/lib/libos.tex (original) +++ python/trunk/Doc/lib/libos.tex Mon Feb 19 11:55:19 2007 @@ -758,6 +758,26 @@ \versionadded{2.3} \end{funcdesc} +\begin{funcdesc}{chflags}{path, flags} +Set the flags of \var{path} to the numeric \var{flags}. +\var{flags} may take a combination (bitwise OR) of the following values +(as defined in the \module{stat} module): +\begin{itemize} + \item \code{UF_NODUMP} + \item \code{UF_IMMUTABLE} + \item \code{UF_APPEND} + \item \code{UF_OPAQUE} + \item \code{UF_NOUNLINK} + \item \code{SF_ARCHIVED} + \item \code{SF_IMMUTABLE} + \item \code{SF_APPEND} + \item \code{SF_NOUNLINK} + \item \code{SF_SNAPSHOT} +\end{itemize} +Availability: Macintosh, \UNIX. +\versionadded{2.6} +\end{funcdesc} + \begin{funcdesc}{chroot}{path} Change the root directory of the current process to \var{path}. Availability: Macintosh, \UNIX. @@ -804,6 +824,13 @@ Availability: Macintosh, \UNIX. \end{funcdesc} +\begin{funcdesc}{lchflags}{path, flags} +Set the flags of \var{path} to the numeric \var{flags}, like +\function{chflags()}, but do not follow symbolic links. +Availability: \UNIX. +\versionadded{2.6} +\end{funcdesc} + \begin{funcdesc}{lchown}{path, uid, gid} Change the owner and group id of \var{path} to the numeric \var{uid} and gid. This function will not follow symbolic links. Modified: python/trunk/Doc/lib/libshutil.tex ============================================================================== --- python/trunk/Doc/lib/libshutil.tex (original) +++ python/trunk/Doc/lib/libshutil.tex Mon Feb 19 11:55:19 2007 @@ -44,8 +44,8 @@ \end{funcdesc} \begin{funcdesc}{copystat}{src, dst} - Copy the permission bits, last access time, and last modification - time from \var{src} to \var{dst}. The file contents, owner, and + Copy the permission bits, last access time, last modification time, + and flags from \var{src} to \var{dst}. The file contents, owner, and group are unaffected. \var{src} and \var{dst} are path names given as strings. \end{funcdesc} Modified: python/trunk/Lib/shutil.py ============================================================================== --- python/trunk/Lib/shutil.py (original) +++ python/trunk/Lib/shutil.py Mon Feb 19 11:55:19 2007 @@ -60,13 +60,15 @@ os.chmod(dst, mode) def copystat(src, dst): - """Copy all stat info (mode bits, atime and mtime) from src to dst""" + """Copy all stat info (mode bits, atime, mtime, flags) from src to dst""" st = os.stat(src) mode = stat.S_IMODE(st.st_mode) if hasattr(os, 'utime'): os.utime(dst, (st.st_atime, st.st_mtime)) if hasattr(os, 'chmod'): os.chmod(dst, mode) + if hasattr(os, 'chflags') and hasattr(st, 'st_flags'): + os.chflags(dst, st.st_flags) def copy(src, dst): Modified: python/trunk/Lib/stat.py ============================================================================== --- python/trunk/Lib/stat.py (original) +++ python/trunk/Lib/stat.py Mon Feb 19 11:55:19 2007 @@ -84,3 +84,16 @@ S_IROTH = 00004 S_IWOTH = 00002 S_IXOTH = 00001 + +# Names for file flags + +UF_NODUMP = 0x00000001 +UF_IMMUTABLE = 0x00000002 +UF_APPEND = 0x00000004 +UF_OPAQUE = 0x00000008 +UF_NOUNLINK = 0x00000010 +SF_ARCHIVED = 0x00010000 +SF_IMMUTABLE = 0x00020000 +SF_APPEND = 0x00040000 +SF_NOUNLINK = 0x00100000 +SF_SNAPSHOT = 0x00200000 Modified: python/trunk/Lib/test/test_posix.py ============================================================================== --- python/trunk/Lib/test/test_posix.py (original) +++ python/trunk/Lib/test/test_posix.py Mon Feb 19 11:55:19 2007 @@ -192,6 +192,18 @@ posix.utime(test_support.TESTFN, (int(now), int(now))) posix.utime(test_support.TESTFN, (now, now)) + def test_chflags(self): + if hasattr(posix, 'chflags'): + st = os.stat(test_support.TESTFN) + if hasattr(st, 'st_flags'): + posix.chflags(test_support.TESTFN, st.st_flags) + + def test_lchflags(self): + if hasattr(posix, 'lchflags'): + st = os.stat(test_support.TESTFN) + if hasattr(st, 'st_flags'): + posix.lchflags(test_support.TESTFN, st.st_flags) + def test_main(): test_support.run_unittest(PosixTester) Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Mon Feb 19 11:55:19 2007 @@ -377,6 +377,7 @@ Kip Lehman Joerg Lehmann Marc-Andre Lemburg +Mark Levinson William Lewis Robert van Liere Martin Ligr Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Feb 19 11:55:19 2007 @@ -371,6 +371,9 @@ Extension Modules ----------------- +- Patch #1490190: posixmodule now includes os.chflags() and os.lchflags() + functions on platforms where the underlying system calls are available. + - Patch #1494140: Add documentation for the new struct.Struct object. - Patch #1432399: Support the HCI protocol for bluetooth sockets Modified: python/trunk/Modules/posixmodule.c ============================================================================== --- python/trunk/Modules/posixmodule.c (original) +++ python/trunk/Modules/posixmodule.c Mon Feb 19 11:55:19 2007 @@ -1692,6 +1692,57 @@ } +#ifdef HAVE_CHFLAGS +PyDoc_STRVAR(posix_chflags__doc__, +"chflags(path, flags)\n\n\ +Set file flags."); + +static PyObject * +posix_chflags(PyObject *self, PyObject *args) +{ + char *path; + unsigned long flags; + int res; + if (!PyArg_ParseTuple(args, "etk:chflags", + Py_FileSystemDefaultEncoding, &path, &flags)) + return NULL; + Py_BEGIN_ALLOW_THREADS + res = chflags(path, flags); + Py_END_ALLOW_THREADS + if (res < 0) + return posix_error_with_allocated_filename(path); + PyMem_Free(path); + Py_INCREF(Py_None); + return Py_None; +} +#endif /* HAVE_CHFLAGS */ + +#ifdef HAVE_LCHFLAGS +PyDoc_STRVAR(posix_lchflags__doc__, +"lchflags(path, flags)\n\n\ +Set file flags.\n\ +This function will not follow symbolic links."); + +static PyObject * +posix_lchflags(PyObject *self, PyObject *args) +{ + char *path; + unsigned long flags; + int res; + if (!PyArg_ParseTuple(args, "etk:lchflags", + Py_FileSystemDefaultEncoding, &path, &flags)) + return NULL; + Py_BEGIN_ALLOW_THREADS + res = lchflags(path, flags); + Py_END_ALLOW_THREADS + if (res < 0) + return posix_error_with_allocated_filename(path); + PyMem_Free(path); + Py_INCREF(Py_None); + return Py_None; +} +#endif /* HAVE_LCHFLAGS */ + #ifdef HAVE_CHROOT PyDoc_STRVAR(posix_chroot__doc__, "chroot(path)\n\n\ @@ -8081,10 +8132,16 @@ {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__}, #endif {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__}, +#ifdef HAVE_CHFLAGS + {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__}, +#endif /* HAVE_CHFLAGS */ {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__}, #ifdef HAVE_CHOWN {"chown", posix_chown, METH_VARARGS, posix_chown__doc__}, #endif /* HAVE_CHOWN */ +#ifdef HAVE_LCHFLAGS + {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__}, +#endif /* HAVE_LCHFLAGS */ #ifdef HAVE_LCHOWN {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__}, #endif /* HAVE_LCHOWN */ Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Mon Feb 19 11:55:19 2007 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 52843 . +# From configure.in Revision: 53508 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59 for python 2.6. # @@ -14718,11 +14718,13 @@ -for ac_func in alarm bind_textdomain_codeset chown clock confstr ctermid \ - execv fork fpathconf ftime ftruncate \ + + +for ac_func in alarm bind_textdomain_codeset chflags chown clock confstr \ + ctermid execv fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getpwent getspnam getspent getsid getwd \ - kill killpg lchown lstat mkfifo mknod mktime \ + kill killpg lchflags lchown lstat mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ select setegid seteuid setgid \ Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Mon Feb 19 11:55:19 2007 @@ -2282,11 +2282,11 @@ AC_MSG_RESULT(MACHDEP_OBJS) # checks for library functions -AC_CHECK_FUNCS(alarm bind_textdomain_codeset chown clock confstr ctermid \ - execv fork fpathconf ftime ftruncate \ +AC_CHECK_FUNCS(alarm bind_textdomain_codeset chflags chown clock confstr \ + ctermid execv fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getpwent getspnam getspent getsid getwd \ - kill killpg lchown lstat mkfifo mknod mktime \ + kill killpg lchflags lchown lstat mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ select setegid seteuid setgid \ Modified: python/trunk/pyconfig.h.in ============================================================================== --- python/trunk/pyconfig.h.in (original) +++ python/trunk/pyconfig.h.in Mon Feb 19 11:55:19 2007 @@ -67,6 +67,9 @@ /* Define this if you have the type _Bool. */ #undef HAVE_C99_BOOL +/* Define to 1 if you have the `chflags' function. */ +#undef HAVE_CHFLAGS + /* Define to 1 if you have the `chown' function. */ #undef HAVE_CHOWN @@ -290,6 +293,9 @@ Solaris and Linux, the necessary defines are already defined.) */ #undef HAVE_LARGEFILE_SUPPORT +/* Define to 1 if you have the `lchflags' function. */ +#undef HAVE_LCHFLAGS + /* Define to 1 if you have the `lchown' function. */ #undef HAVE_LCHOWN From buildbot at python.org Mon Feb 19 12:16:05 2007 From: buildbot at python.org (buildbot at python.org) Date: Mon, 19 Feb 2007 11:16:05 +0000 Subject: [Python-checkins] buildbot warnings in alpha Tru64 5.1 trunk Message-ID: <20070219111605.7F85B1E4019@bag.python.org> The Buildbot has detected a new failure of alpha Tru64 5.1 trunk. Full details are available at: http://www.python.org/dev/buildbot/all/alpha%2520Tru64%25205.1%2520trunk/builds/1420 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: lars.gustaebel,martin.v.loewis,raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Mon Feb 19 19:15:08 2007 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 19 Feb 2007 19:15:08 +0100 (CET) Subject: [Python-checkins] r53827 - in python/trunk: Doc/lib/libheapq.tex Lib/heapq.py Message-ID: <20070219181508.52DC01E4007@bag.python.org> Author: raymond.hettinger Date: Mon Feb 19 19:15:04 2007 New Revision: 53827 Modified: python/trunk/Doc/lib/libheapq.tex python/trunk/Lib/heapq.py Log: Fixup docstrings for merge(). Modified: python/trunk/Doc/lib/libheapq.tex ============================================================================== --- python/trunk/Doc/lib/libheapq.tex (original) +++ python/trunk/Doc/lib/libheapq.tex Mon Feb 19 19:15:04 2007 @@ -96,8 +96,8 @@ over the sorted values. Similar to \code{sorted(itertools.chain(*iterables))} but returns an iterable, -does not pull the data into memory all at once, and reduces the number of -comparisons by assuming that each of the input streams is already sorted. +does not pull the data into memory all at once, and assumes that each of the +input streams is already sorted (smallest to largest). \versionadded{2.6} \end{funcdesc} Modified: python/trunk/Lib/heapq.py ============================================================================== --- python/trunk/Lib/heapq.py (original) +++ python/trunk/Lib/heapq.py Mon Feb 19 19:15:04 2007 @@ -312,8 +312,8 @@ '''Merge multiple sorted inputs into a single sorted output. Similar to sorted(itertools.chain(*iterables)) but returns an iterable, - does not pull the data into memory all at once, and reduces the number - of comparisons by assuming that each of the input streams is already sorted. + does not pull the data into memory all at once, and assumes that each of + the input streams is already sorted (smallest to largest). >>> list(merge([1,3,5,7], [0,2,4,8], [5,10,15,20], [], [25])) [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25] From buildbot at python.org Mon Feb 19 20:18:10 2007 From: buildbot at python.org (buildbot at python.org) Date: Mon, 19 Feb 2007 19:18:10 +0000 Subject: [Python-checkins] buildbot warnings in x86 OpenBSD trunk Message-ID: <20070219191810.7648D1E4009@bag.python.org> The Buildbot has detected a new failure of x86 OpenBSD trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520OpenBSD%2520trunk/builds/1570 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: raymond.hettinger Build had warnings: warnings test Excerpt from the test logfile: 1 test failed: test_socket_ssl sincerely, -The Buildbot From python-checkins at python.org Mon Feb 19 20:26:22 2007 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 19 Feb 2007 20:26:22 +0100 (CET) Subject: [Python-checkins] r53828 - python/branches/release25-maint/Doc/lib/libcollections.tex Message-ID: <20070219192622.D9C211E4009@bag.python.org> Author: raymond.hettinger Date: Mon Feb 19 20:26:16 2007 New Revision: 53828 Modified: python/branches/release25-maint/Doc/lib/libcollections.tex Log: Provide an example of defaultdict with non-zero constant factory function. Modified: python/branches/release25-maint/Doc/lib/libcollections.tex ============================================================================== --- python/branches/release25-maint/Doc/lib/libcollections.tex (original) +++ python/branches/release25-maint/Doc/lib/libcollections.tex Mon Feb 19 20:26:16 2007 @@ -311,16 +311,20 @@ When a letter is first encountered, it is missing from the mapping, so the \member{default_factory} function calls \function{int()} to supply a default count of zero. The increment operation then builds up the count for each -letter. This technique makes counting simpler and faster than an equivalent -technique using \method{dict.get()}: +letter. -\begin{verbatim} ->>> d = {} ->>> for k in s: - d[k] = d.get(k, 0) + 1 +The function \function{int()} which always returns zero is just a special +case of constant functions. A faster and more flexible way to create +constant functions is to use \function{itertools.repeat()} which can supply +any constant value (not just zero): ->>> d.items() -[('i', 4), ('p', 2), ('s', 4), ('m', 1)] +\begin{verbatim} +>>> def constant_factory(value): +... return itertools.repeat(value).next +>>> d = defaultdict(constant_factory('')) +>>> d.update(name='John', action='ran') +>>> '%(name)s %(action)s to %(object)s' % d +'John ran to ' \end{verbatim} Setting the \member{default_factory} to \class{set} makes the From python-checkins at python.org Mon Feb 19 21:44:06 2007 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 19 Feb 2007 21:44:06 +0100 (CET) Subject: [Python-checkins] r53829 - python/trunk/Objects/setobject.c Message-ID: <20070219204406.08A3D1E4019@bag.python.org> Author: raymond.hettinger Date: Mon Feb 19 21:44:04 2007 New Revision: 53829 Modified: python/trunk/Objects/setobject.c Log: Fixup set/dict interoperability. Modified: python/trunk/Objects/setobject.c ============================================================================== --- python/trunk/Objects/setobject.c (original) +++ python/trunk/Objects/setobject.c Mon Feb 19 21:44:04 2007 @@ -919,7 +919,18 @@ PyObject *value; Py_ssize_t pos = 0; long hash; + Py_ssize_t dictsize = PyDict_Size(other); + /* Do one big resize at the start, rather than + * incrementally resizing as we insert new keys. Expect + * that there will be no (or few) overlapping keys. + */ + if (dictsize == -1) + return -1; + if ((so->fill + dictsize)*3 >= (so->mask+1)*2) { + if (set_table_resize(so, (so->used + dictsize)*2) != 0) + return -1; + } while (_PyDict_Next(other, &pos, &key, &value, &hash)) { setentry an_entry; From python-checkins at python.org Mon Feb 19 21:45:47 2007 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 19 Feb 2007 21:45:47 +0100 (CET) Subject: [Python-checkins] r53830 - python/branches/release25-maint/Objects/setobject.c Message-ID: <20070219204547.DB2A91E400B@bag.python.org> Author: raymond.hettinger Date: Mon Feb 19 21:45:46 2007 New Revision: 53830 Modified: python/branches/release25-maint/Objects/setobject.c Log: Fixup set/dict interoperability. Modified: python/branches/release25-maint/Objects/setobject.c ============================================================================== --- python/branches/release25-maint/Objects/setobject.c (original) +++ python/branches/release25-maint/Objects/setobject.c Mon Feb 19 21:45:46 2007 @@ -919,7 +919,18 @@ PyObject *value; Py_ssize_t pos = 0; long hash; + Py_ssize_t dictsize = PyDict_Size(other); + /* Do one big resize at the start, rather than + * incrementally resizing as we insert new keys. Expect + * that there will be no (or few) overlapping keys. + */ + if (dictsize == -1) + return -1; + if ((so->fill + dictsize)*3 >= (so->mask+1)*2) { + if (set_table_resize(so, (so->used + dictsize)*2) != 0) + return -1; + } while (_PyDict_Next(other, &pos, &key, &value, &hash)) { setentry an_entry; From python-checkins at python.org Tue Feb 20 04:30:59 2007 From: python-checkins at python.org (david.goodger) Date: Tue, 20 Feb 2007 04:30:59 +0100 (CET) Subject: [Python-checkins] r53831 - peps/trunk/pep-0363.txt Message-ID: <20070220033059.D3EE11E4009@bag.python.org> Author: david.goodger Date: Tue Feb 20 04:30:58 2007 New Revision: 53831 Modified: peps/trunk/pep-0363.txt Log: update from the author Modified: peps/trunk/pep-0363.txt ============================================================================== --- peps/trunk/pep-0363.txt (original) +++ peps/trunk/pep-0363.txt Tue Feb 20 04:30:58 2007 @@ -2,12 +2,12 @@ Title: Syntax For Dynamic Attribute Access Version: $Revision$ Last-Modified: $Date$ -Author: Ben North -Status: Draft +Author: Ben North +Status: Rejected Type: Standards Track Content-Type: text/plain Created: 29-Jan-2007 -Post-History: +Post-History: 12-Feb-2007 Abstract @@ -28,13 +28,6 @@ z = getattr(getattr(y, 'foo_%d' % n), 'bar_%s' % s) -Note - - I wrote this patch mostly to advance my own understanding of and - experiment with the python language, but I've written it up in the - style of a PEP in case it might be a useful idea. - - Rationale Dictionary access and indexing both have a friendly invocation @@ -64,18 +57,17 @@ x = getattr(y, 'foo_%d' % n, 0) This PEP describes a new syntax for dynamic attribute access --- - "x.(expr)" --- with examples given in the Abstract above. The new - syntax also allows the provision of a default value in the "get" - case, as in: + "x.(expr)" --- with examples given in the Abstract above. + + (The new syntax could also allow the provision of a default value in + the "get" case, as in: x = y.('foo_%d' % n, None) - This 2-argument form of dynamic attribute access is not permitted as - the target of an (augmented or normal) assignment. Also, this part - of the new syntax was not as well received [6] in initial - discussions on python-ideas, and I agree that it does not fit so - cleanly. I'm happy to prepare a revised PEP/patch without the - 2-argument form if the consensus is that this would be preferred. + This 2-argument form of dynamic attribute access would not be + permitted as the target of an (augmented or normal) assignment. The + "Discussion" section below includes opinions specifically on the + 2-argument extension.) Finally, the new syntax can be used with the "del" statement, as in @@ -144,80 +136,18 @@ be a performance penalty of around 1% in the pystones score with the patched version. One suggestion is that this is because the longer main loop in ceval.c hurts the cache behaviour, but this has not - been confirmed. (Maybe a tool like valgrind [2] could help here?) + been confirmed. On the other hand, measurements suggest a speed-up of around 40--45% for dynamic attribute access. -Discussion To Date - - Initial posting of this PEP in draft form was to python-ideas on - 20070209 [4], and the response was generally positive: - - I've thought of the same syntax. I think you should submit this - to the PEP editor and argue on Python-dev for its inclusion in - Python 2.6 -- there's no benefit that I see of waiting until - 3.0. --- Guido van Rossum [5] - - Wow! I have to say this is a compelling idea. The syntax is a - bit foreign looking, but [...] I feel like I could learn to like - it anyway. --- Greg Falcon [6] - - I look forward to seeing this in Python 2.6. --- Josiah - Carlson, further down the thread [8] - - with Greg Falcon expressing the reservations about the 2-argument - form already noted above, and Josiah Carlson raising a query about - performance: - - My only concern with your propsed change is your draft - implementation. [...] Specifically, your changes [...] may - negatively affect general Python performance. --- Josiah - Carlson [7] - - Some initial measurements (see above) suggest the performance - penalty is small, and Josiah Carlson said of such cost that it - "isn't really substantial". [8] - - -Questions To Be Resolved - - * Whether to allow the 2-argument form for default arguments. - - * Whether the performance impact is real; whether it is acceptable; - whether alternative implementations might improve this aspect. - - -Alternative Syntax For The New Feature - - Other syntaxes could be used, for example braces are currently - invalid in a "trailer", so could be used here, giving - - x{'foo_%d' % n} += 1 - - My personal preference is for the - - x.('foo_%d' % n) += 1 - - syntax though: the presence of the dot shows there is attribute - access going on; the parentheses have an analogous meaning to the - mathematical "work this out first" meaning. This is also the - syntax used in the language Matlab [1] for dynamic "field" access - (where "field" is the Matlab term analogous to Python's - "attribute"). - - Discussions on python-ideas (see above) made no comment on the brace - alternative, and the .() notation was well-enough received, so the - brace alternative should be considered rejected, I think. - - Error Cases Only strings are permitted as attribute names, so for instance the following error is produced: - >>> x.(99) = 8 + >>> x.(99) = 8 Traceback (most recent call last): File "", line 1, in TypeError: attribute name must be string, not 'int' @@ -233,29 +163,78 @@ compile.c, and three new opcodes (load/store/del) with accompanying changes to opcode.h and ceval.c. The patch consists of c.180 additional lines in the core code, and c.100 additional - lines of tests. It is available as sourceforge patch #1657573 [3]. - - -References + lines of tests. It is available as sourceforge patch #1657573 [1]. - [1] Using Dynamic Field Names :: Data Types (MATLAB Programming) - http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_prog/f2-41859.html - [2] Valgrind: "suite of tools for debugging and profiling Linux programs" - http://www.valgrind.org/ +Mailing Lists Discussion - [3] Sourceforge patch #1657573 - http://sourceforge.net/tracker/index.php?func=detail&aid=1657573&group_id=5470&atid=305470 + Initial posting of this PEP in draft form was to python-ideas on + 20070209 [2], and the response was generally positive. The PEP was + then posted to python-dev on 20070212 [3], and an interesting + discussion ensued. A brief summary: + + Initially, there was reasonable (but not unanimous) support for the + idea, although the precise choice of syntax had a more mixed + reception. Several people thought the "." would be too easily + overlooked, with the result that the syntax could be confused with a + method/function call. A few alternative syntaxes were suggested: + + obj.(foo) + obj.[foo] + obj.{foo} + obj{foo} + obj.*foo + obj->foo + obj<-foo + obj@[foo] + obj.[[foo]] + + with "obj.[foo]" emerging as the preferred one. In this initial + discussion, the two-argument form was universally disliked, so it + was to be taken out of the PEP. + + Discussion then took a step back to whether this particular feature + provided enough benefit to justify new syntax. As well as requiring + coders to become familiar with the new syntax, there would also be + the problem of backward compatibility --- code using the new syntax + would not run on older pythons. + + Instead of new syntax, a new "wrapper class" was proposed, with the + following specification / conceptual implementation suggested by + Martin von Loewis: + + class attrs: + def __init__(self, obj): + self.obj = obj + def __getitem__(self, name): + return getattr(self.obj, name) + def __setitem__(self, name, value): + return setattr(self.obj, name, value) + def __delitem__(self, name): + return delattr(self, name) + def __contains__(self, name): + return hasattr(self, name) + + This was considered a cleaner and more elegant solution to the + original problem. (Another suggestion was a mixin class providing + dictionary-style access to an object's attributes.) + + The decision was made that the present PEP did not meet the burden + of proof for the introduction of new syntax, a view which had been + put forward by some from the beginning of the discussion. The + wrapper class idea was left open as a possibility for a future PEP. - [4] http://mail.python.org/pipermail/python-ideas/2007-February/000210.html - [5] http://mail.python.org/pipermail/python-ideas/2007-February/000211.html +References - [6] http://mail.python.org/pipermail/python-ideas/2007-February/000212.html + [1] Sourceforge patch #1657573 + http://sourceforge.net/tracker/index.php?func=detail&aid=1657573&group_id=5470&atid=305470 - [7] http://mail.python.org/pipermail/python-ideas/2007-February/000213.html + [2] http://mail.python.org/pipermail/python-ideas/2007-February/000210.html + and following posts - [8] http://mail.python.org/pipermail/python-ideas/2007-February/000227.html + [3] http://mail.python.org/pipermail/python-dev/2007-February/070939.html + and following posts Copyright From python-checkins at python.org Tue Feb 20 04:33:03 2007 From: python-checkins at python.org (david.goodger) Date: Tue, 20 Feb 2007 04:33:03 +0100 (CET) Subject: [Python-checkins] r53832 - peps/trunk/pep-0000.txt Message-ID: <20070220033303.596141E4009@bag.python.org> Author: david.goodger Date: Tue Feb 20 04:32:58 2007 New Revision: 53832 Modified: peps/trunk/pep-0000.txt Log: mark PEP 363 rejected Modified: peps/trunk/pep-0000.txt ============================================================================== --- peps/trunk/pep-0000.txt (original) +++ peps/trunk/pep-0000.txt Tue Feb 20 04:32:58 2007 @@ -108,7 +108,6 @@ S 355 Path - Object oriented filesystem paths Lindqvist S 358 The "bytes" Object Schemenauer S 362 Function Signature Object Cannon, Seo - S 363 Syntax For Dynamic Attribute Access North S 754 IEEE 754 Floating Point Special Values Warnes S 3101 Advanced String Formatting Talin S 3103 A Switch/Case Statement GvR @@ -245,6 +244,7 @@ SD 349 Allow str() to return unicode strings Schemenauer SR 351 The freeze protocol Warsaw SW 359 The "make" Statement Bethard + SR 363 Syntax For Dynamic Attribute Access North SR 666 Reject Foolish Indentation Creighton @@ -435,7 +435,7 @@ I 360 Externally Maintained Packages Cannon I 361 Python 2.6 Release Schedule Norwitz, et al S 362 Function Signature Object Cannon, Seo - S 363 Syntax For Dynamic Attribute Access North + SR 363 Syntax For Dynamic Attribute Access North SR 666 Reject Foolish Indentation Creighton S 754 IEEE 754 Floating Point Special Values Warnes P 3000 Python 3000 GvR From nnorwitz at gmail.com Tue Feb 20 13:42:05 2007 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 20 Feb 2007 18:12:05 +0530 Subject: [Python-checkins] r53815 - peps/trunk/pep-0000.txt peps/trunk/pep-0226.txt peps/trunk/pep-0328.txt peps/trunk/pep-3102.txt peps/trunk/pep-3105.txt peps/trunk/pep-3106.txt peps/trunk/pep-3107.txt peps/trunk/pep-3109.txt peps/trunk/pep-3110.txt In-Reply-To: <20070217184239.7CCE11E400C@bag.python.org> References: <20070217184239.7CCE11E400C@bag.python.org> Message-ID: On 2/18/07, georg.brandl wrote: > Modified: peps/trunk/pep-0328.txt > ============================================================================== > --- peps/trunk/pep-0328.txt (original) > +++ peps/trunk/pep-0328.txt Sat Feb 17 19:42:37 2007 > @@ -3,7 +3,7 @@ > Version: $Revision$ > Last-Modified: $Date$ > Author: Aahz > -Status: Accepted > +Status: Final > Type: Standards Track > Python-Version: 2.4, 2,5, 2.6, 2.7 > Content-Type: text/x-rst Should 328 be final given that there are more things that need to be done in 2.6 (was this change made to the 2.6 code?) and 2.7? n From buildbot at python.org Tue Feb 20 14:05:22 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 20 Feb 2007 13:05:22 +0000 Subject: [Python-checkins] buildbot failure in g4 osx.4 2.5 Message-ID: <20070220130523.637F21E4019@bag.python.org> The Buildbot has detected a new failure of g4 osx.4 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/g4%2520osx.4%25202.5/builds/226 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Preston': Corey Build Source Stamp: [branch Elijah] Kalvin Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Tue Feb 20 14:06:26 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 20 Feb 2007 13:06:26 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 2.5 Message-ID: <20070220130627.909F41E401C@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%2520solaris10%2520gcc%25202.5/builds/233 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Bill': Avery Build Source Stamp: [branch Phillip] Victor Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Tue Feb 20 14:11:28 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 20 Feb 2007 13:11:28 +0000 Subject: [Python-checkins] buildbot failure in x86 XP 2.5 Message-ID: <20070220131128.6ED4B1E4010@bag.python.org> The Buildbot has detected a new failure of x86 XP 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520XP%25202.5/builds/125 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Calvin': Damien Build Source Stamp: [branch Carl] Rashad Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Tue Feb 20 14:13:01 2007 From: buildbot at python.org (buildbot at python.org) Date: Tue, 20 Feb 2007 13:13:01 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 2.5 Message-ID: <20070220131302.75F031E400D@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%2520gentoo%25202.5/builds/241 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Omar': Kamron Build Source Stamp: [branch Jameson] Raymond Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From g.brandl at gmx.net Tue Feb 20 14:18:52 2007 From: g.brandl at gmx.net (Georg Brandl) Date: Tue, 20 Feb 2007 14:18:52 +0100 Subject: [Python-checkins] r53815 - peps/trunk/pep-0000.txt peps/trunk/pep-0226.txt peps/trunk/pep-0328.txt peps/trunk/pep-3102.txt peps/trunk/pep-3105.txt peps/trunk/pep-3106.txt peps/trunk/pep-3107.txt peps/trunk/pep-3109.txt peps/trunk/pep-3110.txt In-Reply-To: References: <20070217184239.7CCE11E400C@bag.python.org> Message-ID: Neal Norwitz schrieb: > On 2/18/07, georg.brandl wrote: >> Modified: peps/trunk/pep-0328.txt >> ============================================================================== >> --- peps/trunk/pep-0328.txt (original) >> +++ peps/trunk/pep-0328.txt Sat Feb 17 19:42:37 2007 >> @@ -3,7 +3,7 @@ >> Version: $Revision$ >> Last-Modified: $Date$ >> Author: Aahz >> -Status: Accepted >> +Status: Final >> Type: Standards Track >> Python-Version: 2.4, 2,5, 2.6, 2.7 >> Content-Type: text/x-rst > > Should 328 be final given that there are more things that need to be > done in 2.6 (was this change made to the 2.6 code?) and 2.7? I thought that now that the roadmap is set out and will be followed, the PEP can be marked as final. I'll revert that if "Final" is not appropriate herefore. Georg From python-checkins at python.org Tue Feb 20 14:57:07 2007 From: python-checkins at python.org (nick.coghlan) Date: Tue, 20 Feb 2007 14:57:07 +0100 (CET) Subject: [Python-checkins] r53833 - peps/trunk/pep-0000.txt peps/trunk/pep-3111.txt Message-ID: <20070220135707.D2FE61E400E@bag.python.org> Author: nick.coghlan Date: Tue Feb 20 14:57:06 2007 New Revision: 53833 Added: peps/trunk/pep-3111.txt (contents, props changed) Modified: peps/trunk/pep-0000.txt Log: Formally record December's acceptance of the raw_input() -> input() renaming. Modified: peps/trunk/pep-0000.txt ============================================================================== --- peps/trunk/pep-0000.txt (original) +++ peps/trunk/pep-0000.txt Tue Feb 20 14:57:06 2007 @@ -82,6 +82,7 @@ SA 3107 Function Annotations Winter, Lownds SA 3109 Raising Exceptions in Python 3000 Winter SA 3110 Catching Exceptions in Python 3000 Winter + SA 3111 Simple input built-in in Python 3000 Roberge Open PEPs (under consideration) @@ -453,6 +454,7 @@ I 3108 Standard Library Reorganization Cannon SA 3109 Raising Exceptions in Python 3000 Winter SA 3110 Catching Exceptions in Python 3000 Winter + SA 3111 Simple input built-in in Python 3000 Roberge Key @@ -544,6 +546,7 @@ Reifschneider, Sean jafo-pep at tummy.com Reis, Christian R. kiko at async.com.br Riehl, Jonathan jriehl at spaceship.com + Roberge, Andr? andre.roberge at gmail.com van Rossum, Guido (GvR) guido at python.org van Rossum, Just (JvR) just at letterror.com Sajip, Vinay vinay_sajip at red-dove.com Added: peps/trunk/pep-3111.txt ============================================================================== --- (empty file) +++ peps/trunk/pep-3111.txt Tue Feb 20 14:57:06 2007 @@ -0,0 +1,162 @@ +PEP: 3111 +Title: Simple input built-in in Python 3000 +Version: $Revision$ +Last-Modified: $Date$ +Author: Andr? Roberge +Status: Draft +Type: Standards Track +Content-Type: text/x-rst +Created: 13-Sep-2006 +Python-Version: 3.0 +Post-History: 22-Dec-2006 + + +Abstract +======== + +Input and output are core features of computer programs. Currently, +Python provides a simple means of output through the print keyword +and two simple means of interactive input through the input() +and raw_input() built-in functions. + +Python 3.0 will introduce various incompatible changes with previous +Python versions[1]. Among the proposed changes, print will become a built-in +function, print(), while input() and raw_input() would be removed completely +from the built-in namespace, requiring importing some module to provide +even the most basic input capability. + +This PEP proposes that Python 3.0 retains some simple interactive user +input capability, equivalent to raw_input(), within the built-in namespace. + +It was accepted by the BDFL in December 2006 [5]. + + +Motivation +========== + +With its easy readability and its support for many programming styles +(e.g. procedural, object-oriented, etc.) among others, Python is perhaps +the best computer language to use in introductory programming classes. +Simple programs often need to provide information to the user (output) +and to obtain information from the user (interactive input). +Any computer language intended to be used in an educational setting should +provide straightforward methods for both output and interactive input. + +The current proposals for Python 3.0 [1] include a simple output pathway +via a built-in function named print(), but a more complicated method for +input [e.g. via sys.stdin.readline()], one that requires importing an external +module. Current versions of Python (pre-3.0) include raw_input() as a +built-in function. With the availability of such a function, programs that +require simple input/output can be written from day one, without requiring +discussions of importing modules, streams, etc. + + +Rationale +========= + +Current built-in functions, like input() and raw_input(), are found to be +extremely useful in traditional teaching settings. (For more details, +see [2] and the discussion that followed.) +While the BDFL has clearly stated [3] that input() was not to be kept in +Python 3000, he has also stated that he was not against revising the +decision of killing raw_input(). + +raw_input() provides a simple mean to ask a question and obtain a response +from a user. The proposed plans for Python 3.0 would require the replacement +of the single statement:: + + name = raw_input("What is your name?") + +by the more complicated:: + + import sys + print("What is your name?") + same = sys.stdin.readline() + +However, from the point of view of many Python beginners and educators, the +use of sys.stdin.readline() presents the following problems: + +1. Compared to the name "raw_input", the name "sys.stdin.readline()" +is clunky and inelegant. + +2. The names "sys" and "stdin" have no meaning for most beginners, +who are mainly interested in *what* the function does, and not *where* +in the package structure it is located. The lack of meaning also makes +it difficult to remember: +is it "sys.stdin.readline()", or " stdin.sys.readline()"? +To a programming novice, there is not any obvious reason to prefer +one over the other. In contrast, functions simple and direct names like +print, input, and raw_input, and open are easier to remember. + +3. The use of "." notation is unmotivated and confusing to many beginners. +For example, it may lead some beginners to think "." is a standard +character that could be used in any identifier. + +4. There is an asymmetry with the print function: why is print not called +sys.stdout.print()? + + +Specification +============= + +The existing ``raw_input()`` function will be renamed to ``input()``. + +The Python 2 to 3 conversion tool will replace calls to ``input()`` with +``eval(input())`` and ``raw_input()`` with ``input()``. + + +Naming Discussion +================= + +With ``input()`` effectively removed from the language, the name ``raw_input()`` +makes much less sense and alternatives should be considered. The +various possibilities mentioned in various forums include:: + + ask() + ask_user() + get_string() + input() # initially rejected by BDFL, later accepted + prompt() + read() + user_input() + get_response() + +While it was initially rejected by the BDFL, it has been suggested that the most +direct solution would be to rename "raw_input" to "input" in Python 3000. +The main objection is that Python 2.x already has a function named "input", +and, even though it is not going to be included in Python 3000, +having a built-in function with the same name but different semantics may +confuse programmers migrating from 2.x to 3000. Certainly, this is no problem +for beginners, and the scope of the problem is unclear for more experienced +programmers, since raw_input(), while popular with many, is not in +universal use. In this instance, the good it does for beginners could be +seen to outweigh the harm it does to experienced programmers - +although it could cause confusion for people reading older books or tutorials. + +The rationale for accepting the renaming can be found here [4]. + + +References +========== + +.. [1] PEP 3100, Miscellaneous Python 3.0 Plans, Kuchling, Cannon + http://www.python.org/dev/peps/pep-3100/ + +.. [2] The fate of raw_input() in Python 3000 + http://mail.python.org/pipermail/edu-sig/2006-September/006967.html + +.. [3] Educational aspects of Python 3000 + http://mail.python.org/pipermail/python-3000/2006-September/003589.html + +.. [4] Rationale for going with the straight renaming + http://mail.python.org/pipermail/python-3000/2006-December/005249.html + +.. [5] BDFL acceptance of the PEP + http://mail.python.org/pipermail/python-3000/2006-December/005257.html + +Copyright +========= + +This document has been placed in the public domain. + + From python-checkins at python.org Tue Feb 20 23:45:41 2007 From: python-checkins at python.org (phillip.eby) Date: Tue, 20 Feb 2007 23:45:41 +0100 (CET) Subject: [Python-checkins] r53834 - sandbox/trunk/setuptools/setuptools/command/install.py Message-ID: <20070220224541.B3EB11E4002@bag.python.org> Author: phillip.eby Date: Tue Feb 20 23:45:40 2007 New Revision: 53834 Modified: sandbox/trunk/setuptools/setuptools/command/install.py Log: Respect possible entry point override of 'easy_install' command. Modified: sandbox/trunk/setuptools/setuptools/command/install.py ============================================================================== --- sandbox/trunk/setuptools/setuptools/command/install.py (original) +++ sandbox/trunk/setuptools/setuptools/command/install.py Tue Feb 20 23:45:40 2007 @@ -82,7 +82,7 @@ def do_egg_install(self): - from setuptools.command.easy_install import easy_install + easy_install = self.distribution.get_command_class('easy_install') cmd = easy_install( self.distribution, args="x", root=self.root, record=self.record, From python-checkins at python.org Tue Feb 20 23:50:44 2007 From: python-checkins at python.org (phillip.eby) Date: Tue, 20 Feb 2007 23:50:44 +0100 (CET) Subject: [Python-checkins] r53835 - sandbox/branches/setuptools-0.6/setuptools/command/install.py Message-ID: <20070220225044.4388D1E4002@bag.python.org> Author: phillip.eby Date: Tue Feb 20 23:50:42 2007 New Revision: 53835 Modified: sandbox/branches/setuptools-0.6/setuptools/command/install.py Log: Respect possible entry point override of 'easy_install' command. (backport from trunk) Modified: sandbox/branches/setuptools-0.6/setuptools/command/install.py ============================================================================== --- sandbox/branches/setuptools-0.6/setuptools/command/install.py (original) +++ sandbox/branches/setuptools-0.6/setuptools/command/install.py Tue Feb 20 23:50:42 2007 @@ -82,7 +82,7 @@ def do_egg_install(self): - from setuptools.command.easy_install import easy_install + easy_install = self.distribution.get_command_class('easy_install') cmd = easy_install( self.distribution, args="x", root=self.root, record=self.record, From python-checkins at python.org Wed Feb 21 00:32:42 2007 From: python-checkins at python.org (guido.van.rossum) Date: Wed, 21 Feb 2007 00:32:42 +0100 (CET) Subject: [Python-checkins] r53836 - peps/trunk/pep-0000.txt peps/trunk/pep-3106.txt Message-ID: <20070220233242.4C2241E4002@bag.python.org> Author: guido.van.rossum Date: Wed Feb 21 00:32:28 2007 New Revision: 53836 Modified: peps/trunk/pep-0000.txt peps/trunk/pep-3106.txt Log: Sorry, PEP 3106 is not yet accepted. Also removed mutating operations and added some clarifications. Modified: peps/trunk/pep-0000.txt ============================================================================== --- peps/trunk/pep-0000.txt (original) +++ peps/trunk/pep-0000.txt Wed Feb 21 00:32:28 2007 @@ -78,7 +78,7 @@ Accepted PEPs (accepted; may not be implemented yet) SA 3102 Keyword-Only Arguments Talin - SA 3106 Revamping dict.keys(), .values() and .items() GvR + S 3106 Revamping dict.keys(), .values() and .items() GvR SA 3107 Function Annotations Winter, Lownds SA 3109 Raising Exceptions in Python 3000 Winter SA 3110 Catching Exceptions in Python 3000 Winter @@ -449,7 +449,7 @@ S 3103 A Switch/Case Statement GvR S 3104 Access to Names in Outer Scopes Yee SF 3105 Make print a function Brandl - SA 3106 Revamping dict.keys(), .values() and .items() GvR + S 3106 Revamping dict.keys(), .values() and .items() GvR SA 3107 Function Annotations Winter, Lownds I 3108 Standard Library Reorganization Cannon SA 3109 Raising Exceptions in Python 3000 Winter Modified: peps/trunk/pep-3106.txt ============================================================================== --- peps/trunk/pep-3106.txt (original) +++ peps/trunk/pep-3106.txt Wed Feb 21 00:32:28 2007 @@ -3,7 +3,7 @@ Version: $Revision$ Last-Modified: $Date$ Author: Guido van Rossum -Status: Accepted +Status: Draft Type: Standards Content-Type: text/x-rst Created: 19-Dec-2006 @@ -14,11 +14,10 @@ ======== This PEP proposes to change the .keys(), .values() and .items() -methods of the built-in dict type to return a set-like or -multiset-like (== bag-like) object whose contents are derived of the -underlying dictionary rather than a list which is a copy of the keys, -etc.; and to remove the .iterkeys(), .itervalues() and .iteritems() -methods. +methods of the built-in dict type to return a set-like or unordered +container object whose contents are derived of the underlying +dictionary rather than a list which is a copy of the keys, etc.; and +to remove the .iterkeys(), .itervalues() and .iteritems() methods. The approach is inspired by that taken in the Java Collections Framework [1]_. @@ -72,25 +71,16 @@ have to write the iter() call because it is implied by a for-loop. The objects returned by the .keys() and .items() methods behave like -sets with limited mutability; they allow removing elements, but not -adding them. Removing an item from these sets removes it from the -underlying dict. The object returned by the values() method behaves -like a multiset (Java calls this a Collection). It does not allow -removing elements, because a value might occur multiple times and the -implementation wouldn't know which key to remove from the underlying -dict. (The Java Collections Framework has a way around this by -removing from an iterator, but I see no practical use case for that -functionality.) +sets. The object returned by the values() method behaves like a much +simpler unordered collection; anything more would require too much +implementation effort for the rare use case. Because of the set behavior, it will be possible to check whether two dicts have the same keys by simply testing:: if a.keys() == b.keys(): ... -and similarly for values. (Two multisets are deemed equal if they -have the same elements with the same cardinalities, e.g. the multiset -{1, 2, 2} is equal to the multiset {2, 1, 2} but differs from the -multiset {1, 2}.) +and similarly for .items(). These operations are thread-safe only to the extent that using them in a thread-unsafe way may cause an exception but will not cause @@ -145,26 +135,12 @@ for key in self.__d: yield key - def remove(self, key): - del self.__d[key] - - def discard(self, key): - if key in self: - self.remove(key) - - def pop(self): - return self.__d.popitem()[0] - - def clear(self): - self.__d.clear() - # The following operations should be implemented to be # compatible with sets; this can be done by exploiting # the above primitive operations: # # <, <=, ==, !=, >=, > (returning a bool) # &, |, ^, - (returning a new, real set object) - # &=, -= (updating in place and returning self; but not |=, ^=) # # as well as their method counterparts (.union(), etc.). # @@ -191,23 +167,6 @@ for key in self.__d: yield key, self.__d[key] - def remove(self, (key, value)): - if (key, value) not in self: - raise KeyError((key, value)) - del self.__d[key] - - def discard(self, item): - # Defined in terms of 'in' and .remove() so overriding - # those will update discard appropriately. - if item in self: - self.remove(item) - - def pop(self): - return self.__d.popitem() - - def clear(self): - self.__d.clear() - # As well as the set operations mentioned for d_keys above. # However the specifications suggested there will not work if # the values aren't hashable. Fortunately, the operations can @@ -288,11 +247,8 @@ # XXX Sometimes this could be optimized, but these are the # semantics: we can't depend on the values to be hashable # or comparable. - o = list(other) for x in self: - try: - o.remove(x) - except ValueError: + if not o in other: return False return True @@ -302,13 +258,21 @@ result = not result return result -Note that we don't implement .copy() -- the presence of a .copy() +Notes: + +The view objects are not directly mutable, but don't implement +__hash__(); their value can change if the underlying dict is mutated. + +The only requirements on the underlying dict are that it implements +__getitem__(), __contains__(), __iter__(), and __len__(0. + +We don't implement .copy() -- the presence of a .copy() method suggests that the copy has the same type as the original, but that's not feasible without copying the underlying dict. If you want a copy of a specific type, like list or set, you can just pass one of the above to the list() or set() constructor. -Also note that the specification implies that the order in which items +The specification implies that the order in which items are returned by .keys(), .values() and .items() is the same (just as it was in Python 2.x), because the order is all derived from the dict iterator (which is presumably arbitrary but stable as long as a dict @@ -325,7 +289,7 @@ speak for itself. I've left out the implementation of various set operations. These -could still present surprises. +could still present small surprises. It would be okay if multiple calls to d.keys() (etc.) returned the same object, since the object's only state is the dict to which it @@ -334,11 +298,6 @@ live forever once created? Strawman: probably not worth the extra slots in every dict. -Should d_values have mutating methods (pop(), clear())? Strawman: no. - -Should d_values implement set operations (as defined for multisets). -Strawman: no. - Should d_keys, d_values and d_items have a public instance variable or method through which one can retrieve the underlying dict? Strawman: yes (but what should it be called?). From buildbot at python.org Wed Feb 21 02:06:00 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 21 Feb 2007 01:06:00 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.5 Message-ID: <20070221010600.B9B081E4002@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520gentoo%25202.5/builds/240 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Cornelius': Maximilian Build Source Stamp: [branch Bryon] Sabastian Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Wed Feb 21 02:09:11 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 21 Feb 2007 01:09:11 +0000 Subject: [Python-checkins] buildbot failure in x86 OpenBSD 2.5 Message-ID: <20070221010912.6A58A1E4002@bag.python.org> The Buildbot has detected a new failure of x86 OpenBSD 2.5. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520OpenBSD%25202.5/builds/215 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: The web-page 'force build' button was pressed by 'Ulysses': Maximo Build Source Stamp: [branch Seth] Mark Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From python-checkins at python.org Wed Feb 21 06:20:42 2007 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 21 Feb 2007 06:20:42 +0100 (CET) Subject: [Python-checkins] r53837 - in python/trunk: Doc/lib/libitertools.tex Lib/test/test_itertools.py Misc/NEWS Modules/itertoolsmodule.c Message-ID: <20070221052042.CFDD01E4002@bag.python.org> Author: raymond.hettinger Date: Wed Feb 21 06:20:38 2007 New Revision: 53837 Modified: python/trunk/Doc/lib/libitertools.tex python/trunk/Lib/test/test_itertools.py python/trunk/Misc/NEWS python/trunk/Modules/itertoolsmodule.c Log: Add itertools.izip_longest(). Modified: python/trunk/Doc/lib/libitertools.tex ============================================================================== --- python/trunk/Doc/lib/libitertools.tex (original) +++ python/trunk/Doc/lib/libitertools.tex Wed Feb 21 06:20:38 2007 @@ -302,6 +302,33 @@ don't care about trailing, unmatched values from the longer iterables. \end{funcdesc} +\begin{funcdesc}{izip_longest}{*iterables\optional{, fillvalue}} + Make an iterator that aggregates elements from each of the iterables. + If the iterables are of uneven length, missing values are filled-in + with \var{fillvalue}. Iteration continues until the longest iterable + is exhausted. Equivalent to: + + \begin{verbatim} + def izip_longest(*args, **kwds): + fillvalue = kwds.get('fillvalue') + def sentinel(counter = ([fillvalue]*(len(args)-1)).pop): + yield counter() # yields the fillvalue, or raises IndexError + fillers = repeat(fillvalue) + iters = [chain(it, sentinel(), fillers) for it in args] + try: + for tup in izip(*iters): + yield tup + except IndexError: + pass + \end{verbatim} + + If one of the iterables is potentially infinite, then the + \function{izip_longest()} function should be wrapped with something + that limits the number of calls (for example \function{islice()} or + \function{take()}). + \versionadded{2.6} +\end{funcdesc} + \begin{funcdesc}{repeat}{object\optional{, times}} Make an iterator that returns \var{object} over and over again. Runs indefinitely unless the \var{times} argument is specified. Modified: python/trunk/Lib/test/test_itertools.py ============================================================================== --- python/trunk/Lib/test/test_itertools.py (original) +++ python/trunk/Lib/test/test_itertools.py Wed Feb 21 06:20:38 2007 @@ -198,6 +198,51 @@ ids = map(id, list(izip('abc', 'def'))) self.assertEqual(len(dict.fromkeys(ids)), len(ids)) + def test_iziplongest(self): + for args in [ + ['abc', range(6)], + [range(6), 'abc'], + [range(1000), range(2000,2100), range(3000,3050)], + [range(1000), range(0), range(3000,3050), range(1200), range(1500)], + [range(1000), range(0), range(3000,3050), range(1200), range(1500), range(0)], + ]: + target = map(None, *args) + self.assertEqual(list(izip_longest(*args)), target) + self.assertEqual(list(izip_longest(*args, **{})), target) + target = [tuple((e is None and 'X' or e) for e in t) for t in target] # Replace None fills with 'X' + self.assertEqual(list(izip_longest(*args, **dict(fillvalue='X'))), target) + + self.assertEqual(take(3,izip_longest('abcdef', count())), zip('abcdef', range(3))) # take 3 from infinite input + + self.assertEqual(list(izip_longest()), zip()) + self.assertEqual(list(izip_longest([])), zip([])) + self.assertEqual(list(izip_longest('abcdef')), zip('abcdef')) + + self.assertEqual(list(izip_longest('abc', 'defg', **{})), map(None, 'abc', 'defg')) # empty keyword dict + self.assertRaises(TypeError, izip_longest, 3) + self.assertRaises(TypeError, izip_longest, range(3), 3) + + for stmt in [ + "izip_longest('abc', fv=1)", + "izip_longest('abc', fillvalue=1, bogus_keyword=None)", + ]: + try: + eval(stmt, globals(), locals()) + except TypeError: + pass + else: + self.fail('Did not raise Type in: ' + stmt) + + # Check tuple re-use (implementation detail) + self.assertEqual([tuple(list(pair)) for pair in izip_longest('abc', 'def')], + zip('abc', 'def')) + self.assertEqual([pair for pair in izip_longest('abc', 'def')], + zip('abc', 'def')) + ids = map(id, izip_longest('abc', 'def')) + self.assertEqual(min(ids), max(ids)) + ids = map(id, list(izip_longest('abc', 'def'))) + self.assertEqual(len(dict.fromkeys(ids)), len(ids)) + def test_repeat(self): self.assertEqual(zip(xrange(3),repeat('a')), [(0, 'a'), (1, 'a'), (2, 'a')]) @@ -611,6 +656,15 @@ self.assertRaises(TypeError, list, izip(N(s))) self.assertRaises(ZeroDivisionError, list, izip(E(s))) + def test_iziplongest(self): + for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)): + for g in (G, I, Ig, S, L, R): + self.assertEqual(list(izip_longest(g(s))), zip(g(s))) + self.assertEqual(list(izip_longest(g(s), g(s))), zip(g(s), g(s))) + self.assertRaises(TypeError, izip_longest, X(s)) + self.assertRaises(TypeError, list, izip_longest(N(s))) + self.assertRaises(ZeroDivisionError, list, izip_longest(E(s))) + def test_imap(self): for s in (range(10), range(0), range(100), (7,11), xrange(20,50,5)): for g in (G, I, Ig, S, L, R): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Feb 21 06:20:38 2007 @@ -127,6 +127,8 @@ - Added heapq.merge() for merging sorted input streams. +- Added itertools.izip_longest(). + - Have the encoding package's search function dynamically import using absolute import semantics. Modified: python/trunk/Modules/itertoolsmodule.c ============================================================================== --- python/trunk/Modules/itertoolsmodule.c (original) +++ python/trunk/Modules/itertoolsmodule.c Wed Feb 21 06:20:38 2007 @@ -2472,6 +2472,238 @@ PyObject_GC_Del, /* tp_free */ }; +/* iziplongest object ************************************************************/ + +#include "Python.h" + +typedef struct { + PyObject_HEAD + Py_ssize_t tuplesize; + Py_ssize_t numactive; + PyObject *ittuple; /* tuple of iterators */ + PyObject *result; + PyObject *fillvalue; + PyObject *filler; /* repeat(fillvalue) */ +} iziplongestobject; + +static PyTypeObject iziplongest_type; + +static PyObject * +izip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + iziplongestobject *lz; + Py_ssize_t i; + PyObject *ittuple; /* tuple of iterators */ + PyObject *result; + PyObject *fillvalue = Py_None; + PyObject *filler; + Py_ssize_t tuplesize = PySequence_Length(args); + + if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_Size(kwds) > 0) { + fillvalue = PyDict_GetItemString(kwds, "fillvalue"); + if (fillvalue == NULL || PyDict_Size(kwds) > 1) { + PyErr_SetString(PyExc_TypeError, + "izip_longest() got an unexpected keyword argument"); + return NULL; + } + } + + /* args must be a tuple */ + assert(PyTuple_Check(args)); + + /* obtain iterators */ + ittuple = PyTuple_New(tuplesize); + if (ittuple == NULL) + return NULL; + for (i=0; i < tuplesize; ++i) { + PyObject *item = PyTuple_GET_ITEM(args, i); + PyObject *it = PyObject_GetIter(item); + if (it == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) + PyErr_Format(PyExc_TypeError, + "izip_longest argument #%zd must support iteration", + i+1); + Py_DECREF(ittuple); + return NULL; + } + PyTuple_SET_ITEM(ittuple, i, it); + } + + filler = PyObject_CallFunctionObjArgs((PyObject *)(&repeat_type), fillvalue, NULL); + if (filler == NULL) { + Py_DECREF(ittuple); + return NULL; + } + + /* create a result holder */ + result = PyTuple_New(tuplesize); + if (result == NULL) { + Py_DECREF(ittuple); + Py_DECREF(filler); + return NULL; + } + for (i=0 ; i < tuplesize ; i++) { + Py_INCREF(Py_None); + PyTuple_SET_ITEM(result, i, Py_None); + } + + /* create iziplongestobject structure */ + lz = (iziplongestobject *)type->tp_alloc(type, 0); + if (lz == NULL) { + Py_DECREF(ittuple); + Py_DECREF(filler); + Py_DECREF(result); + return NULL; + } + lz->ittuple = ittuple; + lz->tuplesize = tuplesize; + lz->numactive = tuplesize; + lz->result = result; + Py_INCREF(fillvalue); + lz->fillvalue = fillvalue; + Py_INCREF(filler); + lz->filler = filler; /* XXX */ + return (PyObject *)lz; +} + +static void +izip_longest_dealloc(iziplongestobject *lz) +{ + PyObject_GC_UnTrack(lz); + Py_XDECREF(lz->ittuple); + Py_XDECREF(lz->result); + Py_XDECREF(lz->fillvalue); + Py_XDECREF(lz->filler); + lz->ob_type->tp_free(lz); +} + +static int +izip_longest_traverse(iziplongestobject *lz, visitproc visit, void *arg) +{ + Py_VISIT(lz->ittuple); + Py_VISIT(lz->result); + Py_VISIT(lz->fillvalue); + Py_VISIT(lz->filler); + return 0; +} + +static PyObject * +izip_longest_next(iziplongestobject *lz) +{ + Py_ssize_t i; + Py_ssize_t tuplesize = lz->tuplesize; + PyObject *result = lz->result; + PyObject *it; + PyObject *item; + PyObject *olditem; + + if (tuplesize == 0) + return NULL; + if (result->ob_refcnt == 1) { + Py_INCREF(result); + 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) { + if (lz->numactive <= 1) { + Py_DECREF(result); + return NULL; + } else { + Py_INCREF(lz->filler); + PyTuple_SET_ITEM(lz->ittuple, i, lz->filler); + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + Py_DECREF(it); + lz->numactive -= 1; + } + } + olditem = PyTuple_GET_ITEM(result, i); + PyTuple_SET_ITEM(result, i, item); + Py_DECREF(olditem); + } + } else { + result = PyTuple_New(tuplesize); + if (result == NULL) + return NULL; + 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) { + if (lz->numactive <= 1) { + Py_DECREF(result); + return NULL; + } else { + Py_INCREF(lz->filler); + PyTuple_SET_ITEM(lz->ittuple, i, lz->filler); + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + Py_DECREF(it); + lz->numactive -= 1; + } + } + PyTuple_SET_ITEM(result, i, item); + } + } + return result; +} + +PyDoc_STRVAR(izip_longest_doc, +"izip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> izip_longest object\n\ +\n\ +Return an izip_longest object whose .next() method returns a tuple where\n\ +the i-th element comes from the i-th iterable argument. The .next()\n\ +method continues until the longest iterable in the argument sequence\n\ +is exhausted and then it raises StopIteration. When the shorter iterables\n\ +are exhausted, the fillvalue is substituted in their place. The fillvalue\n\ +defaults to None or can be specified by a keyword argument.\n\ +"); + +static PyTypeObject iziplongest_type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "itertools.izip_longest", /* tp_name */ + sizeof(iziplongestobject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)izip_longest_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + izip_longest_doc, /* tp_doc */ + (traverseproc)izip_longest_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)izip_longest_next, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + izip_longest_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; /* module level code ********************************************************/ @@ -2485,6 +2717,7 @@ \n\ Iterators terminating on the shortest input sequence:\n\ izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\ +izip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ... \n\ ifilter(pred, seq) --> elements of seq where pred(elem) is True\n\ ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n\ islice(seq, [start,] stop [, step]) --> elements from\n\ @@ -2522,6 +2755,7 @@ &ifilterfalse_type, &count_type, &izip_type, + &iziplongest_type, &repeat_type, &groupby_type, NULL From buildbot at python.org Wed Feb 21 06:38:23 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 21 Feb 2007 05:38:23 +0000 Subject: [Python-checkins] buildbot warnings in x86 XP trunk Message-ID: <20070221053823.376671E4002@bag.python.org> The Buildbot has detected a new failure of x86 XP trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520XP%2520trunk/builds/208 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: raymond.hettinger Build had warnings: warnings failed slave lost sincerely, -The Buildbot From nnorwitz at gmail.com Wed Feb 21 11:15:15 2007 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 21 Feb 2007 05:15:15 -0500 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20070221101515.GA6553@python.psfb.org> test_cmd_line leaked [0, 17, 0] references test_itertools leaked [188, 188, 188] references From g.brandl at gmx.net Wed Feb 21 11:33:23 2007 From: g.brandl at gmx.net (Georg Brandl) Date: Wed, 21 Feb 2007 11:33:23 +0100 Subject: [Python-checkins] r53837 - in python/trunk: Doc/lib/libitertools.tex Lib/test/test_itertools.py Misc/NEWS Modules/itertoolsmodule.c In-Reply-To: <20070221052042.CFDD01E4002@bag.python.org> References: <20070221052042.CFDD01E4002@bag.python.org> Message-ID: raymond.hettinger schrieb: > Author: raymond.hettinger > Date: Wed Feb 21 06:20:38 2007 > New Revision: 53837 > > Modified: > python/trunk/Doc/lib/libitertools.tex > python/trunk/Lib/test/test_itertools.py > python/trunk/Misc/NEWS > python/trunk/Modules/itertoolsmodule.c > Log: > Add itertools.izip_longest(). > +static PyObject * > +izip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) > +{ > + iziplongestobject *lz; > + Py_ssize_t i; > + PyObject *ittuple; /* tuple of iterators */ > + PyObject *result; > + PyObject *fillvalue = Py_None; > + PyObject *filler; > + Py_ssize_t tuplesize = PySequence_Length(args); > + > + if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_Size(kwds) > 0) { > + fillvalue = PyDict_GetItemString(kwds, "fillvalue"); > + if (fillvalue == NULL || PyDict_Size(kwds) > 1) { > + PyErr_SetString(PyExc_TypeError, > + "izip_longest() got an unexpected keyword argument"); > + return NULL; > + } > + } > + > + /* args must be a tuple */ > + assert(PyTuple_Check(args)); > + > + /* obtain iterators */ > + ittuple = PyTuple_New(tuplesize); > + if (ittuple == NULL) > + return NULL; > + for (i=0; i < tuplesize; ++i) { > + PyObject *item = PyTuple_GET_ITEM(args, i); > + PyObject *it = PyObject_GetIter(item); > + if (it == NULL) { > + if (PyErr_ExceptionMatches(PyExc_TypeError)) > + PyErr_Format(PyExc_TypeError, > + "izip_longest argument #%zd must support iteration", > + i+1); > + Py_DECREF(ittuple); > + return NULL; > + } > + PyTuple_SET_ITEM(ittuple, i, it); > + } > + > + filler = PyObject_CallFunctionObjArgs((PyObject *)(&repeat_type), fillvalue, NULL); > + if (filler == NULL) { > + Py_DECREF(ittuple); > + return NULL; > + } > + > + /* create a result holder */ > + result = PyTuple_New(tuplesize); > + if (result == NULL) { > + Py_DECREF(ittuple); > + Py_DECREF(filler); > + return NULL; > + } > + for (i=0 ; i < tuplesize ; i++) { > + Py_INCREF(Py_None); > + PyTuple_SET_ITEM(result, i, Py_None); > + } > + > + /* create iziplongestobject structure */ > + lz = (iziplongestobject *)type->tp_alloc(type, 0); > + if (lz == NULL) { > + Py_DECREF(ittuple); > + Py_DECREF(filler); > + Py_DECREF(result); > + return NULL; > + } > + lz->ittuple = ittuple; > + lz->tuplesize = tuplesize; > + lz->numactive = tuplesize; > + lz->result = result; > + Py_INCREF(fillvalue); > + lz->fillvalue = fillvalue; > + Py_INCREF(filler); filler doesn't need to be INCREF'd here, this causes the refleaks seen in Neal's automated test run. Georg From python-checkins at python.org Wed Feb 21 18:22:10 2007 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 21 Feb 2007 18:22:10 +0100 (CET) Subject: [Python-checkins] r53838 - python/trunk/Modules/itertoolsmodule.c Message-ID: <20070221172210.6266B1E4002@bag.python.org> Author: raymond.hettinger Date: Wed Feb 21 18:22:05 2007 New Revision: 53838 Modified: python/trunk/Modules/itertoolsmodule.c Log: Remove filler struct item and fix leak. Modified: python/trunk/Modules/itertoolsmodule.c ============================================================================== --- python/trunk/Modules/itertoolsmodule.c (original) +++ python/trunk/Modules/itertoolsmodule.c Wed Feb 21 18:22:05 2007 @@ -2483,7 +2483,6 @@ PyObject *ittuple; /* tuple of iterators */ PyObject *result; PyObject *fillvalue; - PyObject *filler; /* repeat(fillvalue) */ } iziplongestobject; static PyTypeObject iziplongest_type; @@ -2496,7 +2495,6 @@ PyObject *ittuple; /* tuple of iterators */ PyObject *result; PyObject *fillvalue = Py_None; - PyObject *filler; Py_ssize_t tuplesize = PySequence_Length(args); if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_Size(kwds) > 0) { @@ -2529,17 +2527,10 @@ PyTuple_SET_ITEM(ittuple, i, it); } - filler = PyObject_CallFunctionObjArgs((PyObject *)(&repeat_type), fillvalue, NULL); - if (filler == NULL) { - Py_DECREF(ittuple); - return NULL; - } - /* create a result holder */ result = PyTuple_New(tuplesize); if (result == NULL) { Py_DECREF(ittuple); - Py_DECREF(filler); return NULL; } for (i=0 ; i < tuplesize ; i++) { @@ -2551,7 +2542,6 @@ lz = (iziplongestobject *)type->tp_alloc(type, 0); if (lz == NULL) { Py_DECREF(ittuple); - Py_DECREF(filler); Py_DECREF(result); return NULL; } @@ -2561,8 +2551,6 @@ lz->result = result; Py_INCREF(fillvalue); lz->fillvalue = fillvalue; - Py_INCREF(filler); - lz->filler = filler; /* XXX */ return (PyObject *)lz; } @@ -2573,7 +2561,6 @@ Py_XDECREF(lz->ittuple); Py_XDECREF(lz->result); Py_XDECREF(lz->fillvalue); - Py_XDECREF(lz->filler); lz->ob_type->tp_free(lz); } @@ -2583,7 +2570,6 @@ Py_VISIT(lz->ittuple); Py_VISIT(lz->result); Py_VISIT(lz->fillvalue); - Py_VISIT(lz->filler); return 0; } @@ -2599,25 +2585,31 @@ if (tuplesize == 0) return NULL; + if (lz->numactive == 0) + return NULL; if (result->ob_refcnt == 1) { Py_INCREF(result); 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) { - if (lz->numactive <= 1) { - Py_DECREF(result); - return NULL; - } else { - Py_INCREF(lz->filler); - PyTuple_SET_ITEM(lz->ittuple, i, lz->filler); - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; - Py_DECREF(it); - lz->numactive -= 1; - } - } + if (it == NULL) { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + } else { + assert(PyIter_Check(it)); + item = (*it->ob_type->tp_iternext)(it); + if (item == NULL) { + lz->numactive -= 1; + if (lz->numactive == 0) { + Py_DECREF(result); + return NULL; + } else { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + PyTuple_SET_ITEM(lz->ittuple, i, NULL); + Py_DECREF(it); + } + } + } olditem = PyTuple_GET_ITEM(result, i); PyTuple_SET_ITEM(result, i, item); Py_DECREF(olditem); @@ -2628,21 +2620,25 @@ return NULL; 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) { - if (lz->numactive <= 1) { - Py_DECREF(result); - return NULL; - } else { - Py_INCREF(lz->filler); - PyTuple_SET_ITEM(lz->ittuple, i, lz->filler); - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; - Py_DECREF(it); - lz->numactive -= 1; - } - } + if (it == NULL) { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + } else { + assert(PyIter_Check(it)); + item = (*it->ob_type->tp_iternext)(it); + if (item == NULL) { + lz->numactive -= 1; + if (lz->numactive == 0) { + Py_DECREF(result); + return NULL; + } else { + Py_INCREF(lz->fillvalue); + item = lz->fillvalue; + PyTuple_SET_ITEM(lz->ittuple, i, NULL); + Py_DECREF(it); + } + } + } PyTuple_SET_ITEM(result, i, item); } } From buildbot at python.org Wed Feb 21 19:38:52 2007 From: buildbot at python.org (buildbot at python.org) Date: Wed, 21 Feb 2007 18:38:52 +0000 Subject: [Python-checkins] buildbot warnings in x86 Ubuntu edgy (icc) trunk Message-ID: <20070221183857.0960D1E4002@bag.python.org> The Buildbot has detected a new failure of x86 Ubuntu edgy (icc) trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%2520Ubuntu%2520edgy%2520%2528icc%2529%2520trunk/builds/1204 Buildbot URL: http://www.python.org/dev/buildbot/all/ Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: raymond.hettinger Build had warnings: warnings failed slave lost sincerely, -The Buildbot From python-checkins at python.org Wed Feb 21 22:40:27 2007 From: python-checkins at python.org (erik.forsberg) Date: Wed, 21 Feb 2007 22:40:27 +0100 (CET) Subject: [Python-checkins] r53842 - in tracker: importer/sfxmlhandlers.py instances/python-dev/initial_data.py Message-ID: <20070221214027.808941E4002@bag.python.org> Author: erik.forsberg Date: Wed Feb 21 22:40:25 2007 New Revision: 53842 Modified: tracker/importer/sfxmlhandlers.py tracker/instances/python-dev/initial_data.py Log: Add 'patch' to list of initially created keywords. Set 'patch' keyword on issues that were of artifact_type 'Patches' on sf. Modified: tracker/importer/sfxmlhandlers.py ============================================================================== --- tracker/importer/sfxmlhandlers.py (original) +++ tracker/importer/sfxmlhandlers.py Wed Feb 21 22:40:25 2007 @@ -403,6 +403,8 @@ def handle(self, fields, roundupdata): if "Feature Requests" == fields[self.source].text: roundupdata[self.target] = self.db.issue_type.lookup("rfe") + elif "Patches" == fields[self.source].text: + roundupdata['keywords'].append(self.db.keyword.lookup("patch")) class GroupHandler(SFXMLHandler): def handle(self, fields, roundupdata): @@ -414,7 +416,7 @@ roundupdata['type'] = self.db.issue_type.lookup("rfe") return elif "Python 3000" == group: - roundupdata['keywords'] = [self.db.keyword.lookup('py3k')] + roundupdata['keywords'].append(self.db.keyword.lookup('py3k')) try: version = self.db.version.lookup(group) roundupdata[self.target] = version Modified: tracker/instances/python-dev/initial_data.py ============================================================================== --- tracker/instances/python-dev/initial_data.py (original) +++ tracker/instances/python-dev/initial_data.py Wed Feb 21 22:40:25 2007 @@ -78,6 +78,7 @@ keyword = db.getclass("keyword") keyword.create(name="py3k", description="Python 3000 bugs") +keyword.create(name="patch", description="Contains patch") # # create the two default users From python-checkins at python.org Thu Feb 22 00:48:00 2007 From: python-checkins at python.org (brett.cannon) Date: Thu, 22 Feb 2007 00:48:00 +0100 (CET) Subject: [Python-checkins] r53846 - sandbox/pep362 Message-ID: <20070221234800.2CD071E4002@bag.python.org> Author: brett.cannon Date: Thu Feb 22 00:47:55 2007 New Revision: 53846 Added: sandbox/pep362/ Log: Create a place in the sandbox for work on PEP 362 (Function Signature object). From python-checkins at python.org Thu Feb 22 00:49:06 2007 From: python-checkins at python.org (brett.cannon) Date: Thu, 22 Feb 2007 00:49:06 +0100 (CET) Subject: [Python-checkins] r53847 - sandbox/trunk/pep362 Message-ID: <20070221234906.C29641E4002@bag.python.org> Author: brett.cannon Date: Thu Feb 22 00:48:53 2007 New Revision: 53847 Added: sandbox/trunk/pep362/ Log: Create a place in the sandbox for work on PEP 362 (Function Signature object). From python-checkins at python.org Thu Feb 22 00:54:21 2007 From: python-checkins at python.org (brett.cannon) Date: Thu, 22 Feb 2007 00:54:21 +0100 (CET) Subject: [Python-checkins] r53848 - sandbox/trunk/pep362/pep362.py sandbox/trunk/pep362/test_pep362.py Message-ID: <20070221235421.234401E4002@bag.python.org> Author: brett.cannon Date: Thu Feb 22 00:54:17 2007 New Revision: 53848 Added: sandbox/trunk/pep362/pep362.py (contents, props changed) sandbox/trunk/pep362/test_pep362.py (contents, props changed) Log: Initial commit of PEP 362 implementation. Torn directly out of local branch of trunk where code was integrated into the 'inspect' module (and test_inspect), so will need to fix imports and tests before any of this is usable. Added: sandbox/trunk/pep362/pep362.py ============================================================================== --- (empty file) +++ sandbox/trunk/pep362/pep362.py Thu Feb 22 00:54:17 2007 @@ -0,0 +1,174 @@ +class BindError(TypeError): + """Represent a failure of inspect.Signature.bind() being able to to + determine if a binding of arguments to parameters is possible.""" + pass + +class Signature(object): + + """Object to represent the signature of a function/method.""" + + def __init__(self, func): + """Initialize from a function or method object.""" + if hasattr(func, 'im_func'): + func = func.im_func + self.name = func.__name__ + + argspec = getargspec(func) + + self.var_args = argspec[1] if (argspec[1] is not None) else '' + self.var_kw_args = argspec[2] if (argspec[2] is not None) else '' + + arg_count = len(argspec[0]) + defaults_start = (arg_count - len(argspec[3]) + if argspec[3] else arg_count) + parameters = [] + for index, arg_name in enumerate(argspec[0]): + if isinstance(arg_name, list): + arg_name = self.__list2tuple(arg_name) + + if index >= defaults_start: + parameters.append(Parameter(arg_name, index, True, + argspec[3][index - defaults_start])) + else: + parameters.append(Parameter(arg_name, index, False)) + + self.parameters = tuple(parameters) + + @classmethod + def __list2tuple(cls, list_): + if not isinstance(list_, list): + return list_ + else: + return tuple(cls.__list2tuple(x) for x in list_) + + def __str__(self): + """String representation of a signature as one might write it in source + code.""" + result = "%s(" % self.name + result += ", ".join(str(param) for param in self.parameters) + if self.var_args: + if self.parameters: + result +=", " + result += "*%s" % self.var_args + if self.var_kw_args: + if self.parameters or self.var_args: + result += ", " + result += "**%s" % self.var_kw_args + result += ")" + return result + + @classmethod + def __tuple_bind_ok(cls, tuple_, arg): + """Verify that 'arg' will unpack properly to be used with 'tuple_'.""" + try: + if len(tuple_) != len(arg): + return False + except TypeError: + raise BindError("cannot determine the length of the argument") + if (hasattr(arg, '__iter__') and hasattr(arg, 'next') and + callable(arg.__iter__) and callable(arg.next)): + raise IndexError("do not want to mutate an iterator") + for tuple_item, arg_item in zip(tuple_, arg): + if isinstance(tuple_item, tuple): + if not cls.__tuple_bind_ok(tuple_item, arg_item): + return False + return True + + @classmethod + def __positional_bind(cls, parameter, arg, bindings): + """Bind 'argument' to 'parameter' in 'bindings' if it is a legitimate + binding. + + A binding can be illegitimate if the parameter is a tuple and the + argument will either unpack improperly or it cannot be determined if it + will without possibly mutating the object (e.g., if it is an + iterator). + + """ + if isinstance(parameter, tuple): + if not cls.__tuple_bind_ok(parameter, arg): + raise TypeError("cannot unpack argument for %s" % parameter) + bindings[parameter] = arg + + def bind(self, *args, **kwargs): + """Return a dictionary mapping function arguments to their parameter + variables, if possible. + + If the only way to determine the proper binding when tuple parameters + are present is to posssibly mutate an iterator then the method gives up + and raises a BindError. This is to prevent something like a generator + which is about to be used for an actual function call from being + exhausted by this method.""" + bindings = {} + arg_names_seq = [param.name for param in self.parameters] + arg_names_set = set(arg_names_seq) + arg_names_cnt = len(arg_names_set) + required_args = set(param.name for param in self.parameters + if not param.has_default) + required_args_cnt = len(required_args) + # *args. + if self.var_args: + bindings[self.var_args] = args[arg_names_cnt:] + args = args[:arg_names_cnt] + if len(args) > arg_names_cnt: + raise TypeError("too many positional arguments provided") + for arg_name, value in zip(arg_names_seq, args): + self.__positional_bind(arg_name, value, bindings) + # Keyword arguments. + var_kw_args = {} + for key, value in kwargs.items(): + if key not in arg_names_set: + if not self.var_kw_args: + raise TypeError("unexpected keyword argument: %r" % key) + else: + var_kw_args[key] = value + else: + if key in bindings: + raise TypeError("got multiple values for argument %r" % + key) + else: + bindings[key] = value + del kwargs[key] + if kwargs: + raise TypeError("too many keyword arguments provided") + # **kwargs. + if self.var_kw_args: + bindings[self.var_kw_args] = var_kw_args + # Default values. + for param in self.parameters: + if param.has_default: + if param.name not in bindings: + bindings[param.name] = param.default_value + + # Make sure all required arguments are bound to. + for bound in bindings.iterkeys(): + try: + required_args.remove(bound) + except KeyError: + pass + else: + if required_args: + raise TypeError("too few arguments provided") + return bindings + + +def getsignature(func): + """Return a Signature object for the function or method. + + If possible, return the existing value stored in __signature__. If that + attribute does not exist, then try to store the Signature object at that + attribute if possible (but is not required). + + """ + if hasattr(func, 'im_func'): + func = func.im_func + sig = Signature(func) + if not hasattr(func, '__signature__'): + try: + func.__signature__ = sig + except AttributeError: + pass + else: + sig = func.__signature__ + + return sig Added: sandbox/trunk/pep362/test_pep362.py ============================================================================== --- (empty file) +++ sandbox/trunk/pep362/test_pep362.py Thu Feb 22 00:54:17 2007 @@ -0,0 +1,255 @@ +class ParameterObjectTests(unittest.TestCase): + + """Test the Parameter object.""" + + def test_name(self): + # Test that 'name' attribute works. + # Must test both using a string and a tuple of strings. + name = "test" + param = inspect.Parameter(name, 0, False) + self.failUnlessEqual(param.name, name) + name = ('a', ('b',)) + param = inspect.Parameter(name, 0, False) + self.failUnlessEqual(param.name, name) + + def test_position(self): + # Test the 'position' attribute. + pos = 42 + param = inspect.Parameter("_", pos, False) + self.failUnlessEqual(param.position, pos) + + def test_has_default(self): + # Test the 'has_default' attribute. + # Testing that 'default_value' is not set is handled in the testing of + # that attribute. + param = inspect.Parameter('_', 0, True, None) + self.failUnlessEqual(param.has_default, True) + param = inspect.Parameter('_', 0, False) + self.failUnlessEqual(param.has_default, False) + self.failUnlessRaises(TypeError, inspect.Parameter, + ('_', 0, False, 'extra arg')) + self.failUnlessRaises(TypeError, inspect.Parameter, + ('_', 0, True)) + self.failUnlessRaises(TypeError, inspect.Parameter, + ('_', 0, True, 'default', 'extra')) + + def test_default_value(self): + # Test the 'default_value' attribute. + # Make sure that if has_default is set to False that default_value is + # not defined. + param = inspect.Parameter('_', 0, False) + self.failUnless(not hasattr(param, 'default_value')) + default = 42 + param = inspect.Parameter('_', 0, True, default) + self.failUnlessEqual(param.default_value, default) + + def test_str(self): + # Test __str__(). + name = "X" + param = inspect.Parameter(name, 0, False) + self.failUnlessEqual(name, str(param)) + default_value = 42 + param = inspect.Parameter(name, 0, True, default_value) + self.failUnlessEqual("%s=%s" % (name, default_value), str(param)) + + def test_repr(self): + # Test __repr__(). + name = "X" + pos = 0 + param = inspect.Parameter(name, pos, False) + self.failUnlessEqual("Parameter(%r, %r, False)" % (name, pos), + repr(param)) + default_value = 42 + param = inspect.Parameter(name, pos, True, default_value) + self.failUnlessEqual("Parameter(%r, %r, True, %r)" % + (name, pos, default_value), + repr(param)) + + +class SignatureObjectTests(unittest.TestCase): + + def test_no_args(self): + # Test a function with no arguments. + sig = inspect.Signature(mod.no_args) + self.failUnlessEqual('no_args', sig.name) + self.failUnless(not sig.var_args) + self.failUnless(not sig.var_kw_args) + self.failUnlessEqual(0, len(sig.parameters)) + + def test_var_args(self): + # Test the var_args attribute. + sig = inspect.Signature(mod.var_args) + self.failUnlessEqual('args', sig.var_args) + self.failUnlessEqual(0, len(sig.parameters)) + sig = inspect.Signature(mod.no_args) + self.failUnlessEqual('', sig.var_args) + + def test_var_kw_args(self): + # Test the var_kw_args attribute. + sig = inspect.Signature(mod.var_kw_args) + self.failUnlessEqual('var_kw_args', sig.name) + self.failUnlessEqual('kwargs', sig.var_kw_args) + self.failUnlessEqual(0, len(sig.parameters)) + sig = inspect.Signature(mod.no_args) + self.failUnlessEqual('', sig.var_kw_args) + + def test_parameter_positional(self): + sig = inspect.Signature(mod.no_default_args) + self.failUnlessEqual('no_default_args', sig.name) + param = sig.parameters[0] + self.failUnlessEqual('a', param.name) + self.failUnlessEqual(0, param.position) + self.failUnless(not param.has_default) + self.failUnless(not hasattr(param, 'default_value')) + + def test_parameter_default(self): + sig = inspect.Signature(mod.default_args) + self.failUnlessEqual('default_args', sig.name) + param = sig.parameters[0] + self.failUnlessEqual('a', param.name) + self.failUnlessEqual(0, param.position) + self.failUnless(param.has_default) + self.failUnlessEqual(42, param.default_value) + + def test_parameter_tuple(self): + sig = inspect.Signature(mod.tuple_args) + self.failUnlessEqual('tuple_args', sig.name) + param = sig.parameters[0] + self.failUnless(isinstance(param.name, tuple)) + self.failUnlessEqual(('a', ('b',)), param.name) + self.failUnlessEqual(0, param.position) + self.failUnless(not param.has_default) + self.failUnless(not hasattr(param, 'default_value')) + + def test_parameter_tuple_default(self): + sig = inspect.Signature(mod.default_tuple_args) + self.failUnlessEqual('default_tuple_args', sig.name) + param = sig.parameters[0] + self.failUnlessEqual(('a', ('b',)), param.name) + self.failUnlessEqual(0, param.position) + self.failUnless(param.has_default) + self.failUnlessEqual((1, (2,)), param.default_value) + + def test_positioning(self): + sig = inspect.Signature(mod.all_args) + param = sig.parameters[2] + self.failUnlessEqual('d', param.name) + + def test_getsignature(self): + def fresh_func(): + pass + self.failUnless(not hasattr(fresh_func, '__signature__')) + sig = inspect.getsignature(fresh_func) + self.failUnlessEqual(sig, fresh_func.__signature__) + sig2 = inspect.getsignature(fresh_func) + self.failUnlessEqual(sig, sig2) + class FreshClass(object): + def fresh_method(self): + pass + sig = inspect.getsignature(FreshClass.fresh_method) + self.failUnlessEqual(sig, FreshClass.fresh_method.im_func.__signature__) + + def test_str(self): + # Test __str__(). + sig = inspect.Signature(mod.no_args) + self.failUnlessEqual("no_args()", str(sig)) + sig = inspect.Signature(mod.var_args) + self.failUnlessEqual("var_args(*args)", str(sig)) + sig = inspect.Signature(mod.var_kw_args) + self.failUnlessEqual("var_kw_args(**kwargs)", str(sig)) + sig = inspect.Signature(mod.default_args) + self.failUnlessEqual("default_args(a=42)", str(sig)) + sig = inspect.Signature(mod.no_default_args) + self.failUnlessEqual("no_default_args(a)", str(sig)) + sig = inspect.Signature(mod.tuple_args) + self.failUnlessEqual("tuple_args((a, (b,)))", str(sig)) + sig = inspect.Signature(mod.default_tuple_args) + self.failUnlessEqual("default_tuple_args((a, (b,))=(1, (2,)))", + str(sig)) + sig = inspect.Signature(mod.all_args) + self.failUnlessEqual("all_args(a, (b, (c,)), d=0, " + "(e, (f,))=(1, (2,)), *g, **h)", + str(sig)) + +class SignatureBindTests(unittest.TestCase): + + """Test Signature.bind().""" + + def test_no_parameters(self): + sig = inspect.Signature(mod.no_args) + binding = sig.bind() + self.failUnlessEqual({}, binding) + self.failUnlessRaises(TypeError, sig.bind, 42) + self.failUnlessRaises(TypeError, sig.bind, a=0) + + def test_var_parameters(self): + sig = inspect.Signature(mod.var_args) + binding = sig.bind(0, 1, 2) + self.failUnlessEqual({'args':(0, 1, 2)}, binding) + binding = sig.bind() + self.failUnlessEqual({'args':tuple()}, binding) + self.failUnlessRaises(TypeError, sig.bind, a=0) + + def test_var_kw_parameters(self): + sig = inspect.Signature(mod.var_kw_args) + binding = sig.bind(a=0) + self.failUnlessEqual({'kwargs':{'a':0}}, binding) + binding = sig.bind() + self.failUnlessEqual({'kwargs':{}}, binding) + self.failUnlessRaises(TypeError, sig.bind, 42) + + def test_positional_parameters(self): + sig = inspect.Signature(mod.no_default_args) + binding = sig.bind(42) + self.failUnlessEqual({'a':42}, binding) + binding = sig.bind(a=42) + self.failUnlessEqual({'a':42}, binding) + self.failUnlessRaises(TypeError, sig.bind) + self.failUnlessRaises(TypeError, sig.bind, 0, 1) + self.failUnlessRaises(TypeError, sig.bind, b=0) + + def test_keyword_parameters(self): + sig = inspect.Signature(mod.default_args) + binding = sig.bind(0) + self.failUnlessEqual({'a':0}, binding) + binding = sig.bind() + self.failUnlessEqual({'a':42}, binding) + binding = sig.bind(a=0) + self.failUnlessEqual({'a':0}, binding) + self.failUnlessRaises(TypeError, sig.bind, 0, 1) + self.failUnlessRaises(TypeError, sig.bind, a=0, b=1) + self.failUnlessRaises(TypeError, sig.bind, b=1) + + def test_tuple_parameter(self): + sig = inspect.Signature(mod.tuple_args) + binding = sig.bind((1, (2,))) + self.failUnlessEqual({('a', ('b',)):(1, (2,))}, binding) + arg = (1, ((2,),)) + binding = sig.bind(arg) + self.failUnlessEqual({('a', ('b',)):arg}, binding) + self.failUnlessRaises(TypeError, sig.bind, (1,2,3)) + self.failUnlessRaises(TypeError, sig.bind, (1, 2)) + + def test_default_tuple_parameter(self): + sig = inspect.Signature(mod.default_tuple_args) + binding = sig.bind() + self.failUnlessEqual({('a', ('b',)):(1, (2,))}, binding) + arg = (0, (1,)) + binding = sig.bind(arg) + self.failUnlessEqual({('a', ('b',)):arg}, binding) + + def test_all_parameter_types(self): + sig = inspect.Signature(mod.all_args) + binding = sig.bind(0, (1, (2,)), 3, (4, (5,)), 6, i=7) + expected = {'a':0, ('b', ('c',)):(1, (2,)), 'd':3, + ('e', ('f',)):(4, (5,)), 'g':(6,), 'h':{'i':7}} + self.failUnlessEqual(expected, binding) + + def test_BindError(self): + def gen(): + yield 0 + yield (1,) + sig = inspect.Signature(mod.tuple_args) + self.failUnlessRaises(inspect.BindError, sig.bind, gen()) + + From python-checkins at python.org Thu Feb 22 00:56:52 2007 From: python-checkins at python.org (brett.cannon) Date: Thu, 22 Feb 2007 00:56:52 +0100 (CET) Subject: [Python-checkins] r53849 - sandbox/pep362 Message-ID: <20070221235652.4FEBC1E4002@bag.python.org> Author: brett.cannon Date: Thu Feb 22 00:56:50 2007 New Revision: 53849 Removed: sandbox/pep362/ Log: Remove accidental addition of a directory; should have been in the trunk of the sandbox. From python-checkins at python.org Thu Feb 22 01:03:01 2007 From: python-checkins at python.org (brett.cannon) Date: Thu, 22 Feb 2007 01:03:01 +0100 (CET) Subject: [Python-checkins] r53850 - sandbox/trunk/pep362/pep362.py Message-ID: <20070222000301.9345B1E4003@bag.python.org> Author: brett.cannon Date: Thu Feb 22 01:02:57 2007 New Revision: 53850 Modified: sandbox/trunk/pep362/pep362.py Log: Add Parameter class that was accidentally skipped in initial copy from local branch work. Modified: sandbox/trunk/pep362/pep362.py ============================================================================== --- sandbox/trunk/pep362/pep362.py (original) +++ sandbox/trunk/pep362/pep362.py Thu Feb 22 01:02:57 2007 @@ -3,6 +3,57 @@ determine if a binding of arguments to parameters is possible.""" pass + +class Parameter(object): + + """Represent a parameter in a function signature.""" + + def __init__(self, name, position, has_default, *args): + self.name = name + self.position = position + if not has_default: + self.has_default = False + else: + self.has_default = True + if len(args) != 1: + raise ValueError("Parameter requires a default value to be " + "specified when has_default has been set " + "to True") + self.default_value = args[0] + + @classmethod + def __tuple2param(self, tuple_): + if not isinstance(tuple_, tuple): + return str(tuple_) + elif len(tuple_) == 1: + return "(" + str(tuple_[0]) +",)" + else: + return ('(' + + ', '.join(self.__tuple2param(x) for x in tuple_) + + ')') + + def __str__(self): + """Return the string representation of the parameter as it would look + in a function's signature.""" + if isinstance(self.name, tuple): + result = self.__tuple2param(self.name) + else: + result = self.name + if self.has_default: + result+= "=" + str(self.default_value) + return result + + def __repr__(self): + """Return the string required to create an equivalent instance of this + parameter.""" + result = "%s(%r, %r, %r" % (self.__class__.__name__, + self.name, self.position, self.has_default) + if self.has_default: + result +=", %r" % self.default_value + result += ")" + return result + + class Signature(object): """Object to represent the signature of a function/method.""" @@ -152,7 +203,7 @@ return bindings -def getsignature(func): +def signature(func): """Return a Signature object for the function or method. If possible, return the existing value stored in __signature__. If that From python-checkins at python.org Thu Feb 22 01:15:56 2007 From: python-checkins at python.org (brett.cannon) Date: Thu, 22 Feb 2007 01:15:56 +0100 (CET) Subject: [Python-checkins] r53851 - sandbox/trunk/pep362/pep362.py sandbox/trunk/pep362/test_pep362.py Message-ID: <20070222001556.26C9D1E4015@bag.python.org> Author: brett.cannon Date: Thu Feb 22 01:15:54 2007 New Revision: 53851 Modified: sandbox/trunk/pep362/pep362.py sandbox/trunk/pep362/test_pep362.py Log: Get code back into shape so that it passes all unit tests again. Modified: sandbox/trunk/pep362/pep362.py ============================================================================== --- sandbox/trunk/pep362/pep362.py (original) +++ sandbox/trunk/pep362/pep362.py Thu Feb 22 01:15:54 2007 @@ -1,3 +1,6 @@ +import inspect + + class BindError(TypeError): """Represent a failure of inspect.Signature.bind() being able to to determine if a binding of arguments to parameters is possible.""" @@ -64,7 +67,7 @@ func = func.im_func self.name = func.__name__ - argspec = getargspec(func) + argspec = inspect.getargspec(func) self.var_args = argspec[1] if (argspec[1] is not None) else '' self.var_kw_args = argspec[2] if (argspec[2] is not None) else '' Modified: sandbox/trunk/pep362/test_pep362.py ============================================================================== --- sandbox/trunk/pep362/test_pep362.py (original) +++ sandbox/trunk/pep362/test_pep362.py Thu Feb 22 01:15:54 2007 @@ -1,3 +1,9 @@ +import pep362 + +import unittest +from test import test_support +import pep362_fodder + class ParameterObjectTests(unittest.TestCase): """Test the Parameter object.""" @@ -6,61 +12,61 @@ # Test that 'name' attribute works. # Must test both using a string and a tuple of strings. name = "test" - param = inspect.Parameter(name, 0, False) + param = pep362.Parameter(name, 0, False) self.failUnlessEqual(param.name, name) name = ('a', ('b',)) - param = inspect.Parameter(name, 0, False) + param = pep362.Parameter(name, 0, False) self.failUnlessEqual(param.name, name) def test_position(self): # Test the 'position' attribute. pos = 42 - param = inspect.Parameter("_", pos, False) + param = pep362.Parameter("_", pos, False) self.failUnlessEqual(param.position, pos) def test_has_default(self): # Test the 'has_default' attribute. # Testing that 'default_value' is not set is handled in the testing of # that attribute. - param = inspect.Parameter('_', 0, True, None) + param = pep362.Parameter('_', 0, True, None) self.failUnlessEqual(param.has_default, True) - param = inspect.Parameter('_', 0, False) + param = pep362.Parameter('_', 0, False) self.failUnlessEqual(param.has_default, False) - self.failUnlessRaises(TypeError, inspect.Parameter, + self.failUnlessRaises(TypeError, pep362.Parameter, ('_', 0, False, 'extra arg')) - self.failUnlessRaises(TypeError, inspect.Parameter, + self.failUnlessRaises(TypeError, pep362.Parameter, ('_', 0, True)) - self.failUnlessRaises(TypeError, inspect.Parameter, + self.failUnlessRaises(TypeError, pep362.Parameter, ('_', 0, True, 'default', 'extra')) def test_default_value(self): # Test the 'default_value' attribute. # Make sure that if has_default is set to False that default_value is # not defined. - param = inspect.Parameter('_', 0, False) + param = pep362.Parameter('_', 0, False) self.failUnless(not hasattr(param, 'default_value')) default = 42 - param = inspect.Parameter('_', 0, True, default) + param = pep362.Parameter('_', 0, True, default) self.failUnlessEqual(param.default_value, default) def test_str(self): # Test __str__(). name = "X" - param = inspect.Parameter(name, 0, False) + param = pep362.Parameter(name, 0, False) self.failUnlessEqual(name, str(param)) default_value = 42 - param = inspect.Parameter(name, 0, True, default_value) + param = pep362.Parameter(name, 0, True, default_value) self.failUnlessEqual("%s=%s" % (name, default_value), str(param)) def test_repr(self): # Test __repr__(). name = "X" pos = 0 - param = inspect.Parameter(name, pos, False) + param = pep362.Parameter(name, pos, False) self.failUnlessEqual("Parameter(%r, %r, False)" % (name, pos), repr(param)) default_value = 42 - param = inspect.Parameter(name, pos, True, default_value) + param = pep362.Parameter(name, pos, True, default_value) self.failUnlessEqual("Parameter(%r, %r, True, %r)" % (name, pos, default_value), repr(param)) @@ -70,7 +76,7 @@ def test_no_args(self): # Test a function with no arguments. - sig = inspect.Signature(mod.no_args) + sig = pep362.Signature(pep362_fodder.no_args) self.failUnlessEqual('no_args', sig.name) self.failUnless(not sig.var_args) self.failUnless(not sig.var_kw_args) @@ -78,23 +84,23 @@ def test_var_args(self): # Test the var_args attribute. - sig = inspect.Signature(mod.var_args) + sig = pep362.Signature(pep362_fodder.var_args) self.failUnlessEqual('args', sig.var_args) self.failUnlessEqual(0, len(sig.parameters)) - sig = inspect.Signature(mod.no_args) + sig = pep362.Signature(pep362_fodder.no_args) self.failUnlessEqual('', sig.var_args) def test_var_kw_args(self): # Test the var_kw_args attribute. - sig = inspect.Signature(mod.var_kw_args) + sig = pep362.Signature(pep362_fodder.var_kw_args) self.failUnlessEqual('var_kw_args', sig.name) self.failUnlessEqual('kwargs', sig.var_kw_args) self.failUnlessEqual(0, len(sig.parameters)) - sig = inspect.Signature(mod.no_args) + sig = pep362.Signature(pep362_fodder.no_args) self.failUnlessEqual('', sig.var_kw_args) def test_parameter_positional(self): - sig = inspect.Signature(mod.no_default_args) + sig = pep362.Signature(pep362_fodder.no_default_args) self.failUnlessEqual('no_default_args', sig.name) param = sig.parameters[0] self.failUnlessEqual('a', param.name) @@ -103,7 +109,7 @@ self.failUnless(not hasattr(param, 'default_value')) def test_parameter_default(self): - sig = inspect.Signature(mod.default_args) + sig = pep362.Signature(pep362_fodder.default_args) self.failUnlessEqual('default_args', sig.name) param = sig.parameters[0] self.failUnlessEqual('a', param.name) @@ -112,7 +118,7 @@ self.failUnlessEqual(42, param.default_value) def test_parameter_tuple(self): - sig = inspect.Signature(mod.tuple_args) + sig = pep362.Signature(pep362_fodder.tuple_args) self.failUnlessEqual('tuple_args', sig.name) param = sig.parameters[0] self.failUnless(isinstance(param.name, tuple)) @@ -122,7 +128,7 @@ self.failUnless(not hasattr(param, 'default_value')) def test_parameter_tuple_default(self): - sig = inspect.Signature(mod.default_tuple_args) + sig = pep362.Signature(pep362_fodder.default_tuple_args) self.failUnlessEqual('default_tuple_args', sig.name) param = sig.parameters[0] self.failUnlessEqual(('a', ('b',)), param.name) @@ -131,42 +137,42 @@ self.failUnlessEqual((1, (2,)), param.default_value) def test_positioning(self): - sig = inspect.Signature(mod.all_args) + sig = pep362.Signature(pep362_fodder.all_args) param = sig.parameters[2] self.failUnlessEqual('d', param.name) - def test_getsignature(self): + def test_signature(self): def fresh_func(): pass self.failUnless(not hasattr(fresh_func, '__signature__')) - sig = inspect.getsignature(fresh_func) + sig = pep362.signature(fresh_func) self.failUnlessEqual(sig, fresh_func.__signature__) - sig2 = inspect.getsignature(fresh_func) + sig2 = pep362.signature(fresh_func) self.failUnlessEqual(sig, sig2) class FreshClass(object): def fresh_method(self): pass - sig = inspect.getsignature(FreshClass.fresh_method) + sig = pep362.signature(FreshClass.fresh_method) self.failUnlessEqual(sig, FreshClass.fresh_method.im_func.__signature__) def test_str(self): # Test __str__(). - sig = inspect.Signature(mod.no_args) + sig = pep362.Signature(pep362_fodder.no_args) self.failUnlessEqual("no_args()", str(sig)) - sig = inspect.Signature(mod.var_args) + sig = pep362.Signature(pep362_fodder.var_args) self.failUnlessEqual("var_args(*args)", str(sig)) - sig = inspect.Signature(mod.var_kw_args) + sig = pep362.Signature(pep362_fodder.var_kw_args) self.failUnlessEqual("var_kw_args(**kwargs)", str(sig)) - sig = inspect.Signature(mod.default_args) + sig = pep362.Signature(pep362_fodder.default_args) self.failUnlessEqual("default_args(a=42)", str(sig)) - sig = inspect.Signature(mod.no_default_args) + sig = pep362.Signature(pep362_fodder.no_default_args) self.failUnlessEqual("no_default_args(a)", str(sig)) - sig = inspect.Signature(mod.tuple_args) + sig = pep362.Signature(pep362_fodder.tuple_args) self.failUnlessEqual("tuple_args((a, (b,)))", str(sig)) - sig = inspect.Signature(mod.default_tuple_args) + sig = pep362.Signature(pep362_fodder.default_tuple_args) self.failUnlessEqual("default_tuple_args((a, (b,))=(1, (2,)))", str(sig)) - sig = inspect.Signature(mod.all_args) + sig = pep362.Signature(pep362_fodder.all_args) self.failUnlessEqual("all_args(a, (b, (c,)), d=0, " "(e, (f,))=(1, (2,)), *g, **h)", str(sig)) @@ -176,14 +182,14 @@ """Test Signature.bind().""" def test_no_parameters(self): - sig = inspect.Signature(mod.no_args) + sig = pep362.Signature(pep362_fodder.no_args) binding = sig.bind() self.failUnlessEqual({}, binding) self.failUnlessRaises(TypeError, sig.bind, 42) self.failUnlessRaises(TypeError, sig.bind, a=0) def test_var_parameters(self): - sig = inspect.Signature(mod.var_args) + sig = pep362.Signature(pep362_fodder.var_args) binding = sig.bind(0, 1, 2) self.failUnlessEqual({'args':(0, 1, 2)}, binding) binding = sig.bind() @@ -191,7 +197,7 @@ self.failUnlessRaises(TypeError, sig.bind, a=0) def test_var_kw_parameters(self): - sig = inspect.Signature(mod.var_kw_args) + sig = pep362.Signature(pep362_fodder.var_kw_args) binding = sig.bind(a=0) self.failUnlessEqual({'kwargs':{'a':0}}, binding) binding = sig.bind() @@ -199,7 +205,7 @@ self.failUnlessRaises(TypeError, sig.bind, 42) def test_positional_parameters(self): - sig = inspect.Signature(mod.no_default_args) + sig = pep362.Signature(pep362_fodder.no_default_args) binding = sig.bind(42) self.failUnlessEqual({'a':42}, binding) binding = sig.bind(a=42) @@ -209,7 +215,7 @@ self.failUnlessRaises(TypeError, sig.bind, b=0) def test_keyword_parameters(self): - sig = inspect.Signature(mod.default_args) + sig = pep362.Signature(pep362_fodder.default_args) binding = sig.bind(0) self.failUnlessEqual({'a':0}, binding) binding = sig.bind() @@ -221,7 +227,7 @@ self.failUnlessRaises(TypeError, sig.bind, b=1) def test_tuple_parameter(self): - sig = inspect.Signature(mod.tuple_args) + sig = pep362.Signature(pep362_fodder.tuple_args) binding = sig.bind((1, (2,))) self.failUnlessEqual({('a', ('b',)):(1, (2,))}, binding) arg = (1, ((2,),)) @@ -231,7 +237,7 @@ self.failUnlessRaises(TypeError, sig.bind, (1, 2)) def test_default_tuple_parameter(self): - sig = inspect.Signature(mod.default_tuple_args) + sig = pep362.Signature(pep362_fodder.default_tuple_args) binding = sig.bind() self.failUnlessEqual({('a', ('b',)):(1, (2,))}, binding) arg = (0, (1,)) @@ -239,7 +245,7 @@ self.failUnlessEqual({('a', ('b',)):arg}, binding) def test_all_parameter_types(self): - sig = inspect.Signature(mod.all_args) + sig = pep362.Signature(pep362_fodder.all_args) binding = sig.bind(0, (1, (2,)), 3, (4, (5,)), 6, i=7) expected = {'a':0, ('b', ('c',)):(1, (2,)), 'd':3, ('e', ('f',)):(4, (5,)), 'g':(6,), 'h':{'i':7}} @@ -249,7 +255,15 @@ def gen(): yield 0 yield (1,) - sig = inspect.Signature(mod.tuple_args) - self.failUnlessRaises(inspect.BindError, sig.bind, gen()) + sig = pep362.Signature(pep362_fodder.tuple_args) + self.failUnlessRaises(pep362.BindError, sig.bind, gen()) + + +def test_main(): + test_support.run_unittest(ParameterObjectTests, + SignatureObjectTests, + ) +if __name__ == '__main__': + test_main() From cilfp at that90sporn.com Thu Feb 22 19:05:58 2007 From: cilfp at that90sporn.com (Steve Meyer) Date: Thu, 22 Feb 2007 18:05:58 +0000 Subject: [Python-checkins] tourism potato Message-ID: <45DDDB86.4030102@specialty-bulb-lamp.cn> An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/python-checkins/attachments/20070222/eaf36e7b/attachment.htm -------------- next part -------------- A non-text attachment was scrubbed... Name: thin.gif Type: image/gif Size: 17265 bytes Desc: not available Url : http://mail.python.org/pipermail/python-checkins/attachments/20070222/eaf36e7b/attachment.gif From python-checkins at python.org Fri Feb 23 00:57:47 2007 From: python-checkins at python.org (guido.van.rossum) Date: Fri, 23 Feb 2007 00:57:47 +0100 (CET) Subject: [Python-checkins] r53860 - peps/trunk/pep-0000.txt peps/trunk/pep-0358.txt Message-ID: <20070222235747.3546F1E4003@bag.python.org> Author: guido.van.rossum Date: Fri Feb 23 00:57:46 2007 New Revision: 53860 Modified: peps/trunk/pep-0000.txt peps/trunk/pep-0358.txt Log: Update the bytes object to better resemble my intentions. Modified: peps/trunk/pep-0000.txt ============================================================================== --- peps/trunk/pep-0000.txt (original) +++ peps/trunk/pep-0000.txt Fri Feb 23 00:57:46 2007 @@ -107,7 +107,7 @@ I 350 Codetags Elliott S 354 Enumerations in Python Finney S 355 Path - Object oriented filesystem paths Lindqvist - S 358 The "bytes" Object Schemenauer + S 358 The "bytes" Object Schemenauer, GvR S 362 Function Signature Object Cannon, Seo S 754 IEEE 754 Floating Point Special Values Warnes S 3101 Advanced String Formatting Talin @@ -431,7 +431,7 @@ S 355 Path - Object oriented filesystem paths Lindqvist IF 356 Python 2.5 Release Schedule Norwitz, et al SF 357 Allowing Any Object to be Used for Slicing Oliphant - S 358 The "bytes" Object Schemenauer + S 358 The "bytes" Object Schemenauer, GvR SW 359 The "make" Statement Bethard I 360 Externally Maintained Packages Cannon I 361 Python 2.6 Release Schedule Norwitz, et al Modified: peps/trunk/pep-0358.txt ============================================================================== --- peps/trunk/pep-0358.txt (original) +++ peps/trunk/pep-0358.txt Fri Feb 23 00:57:46 2007 @@ -2,12 +2,12 @@ Title: The "bytes" Object Version: $Revision$ Last-Modified: $Date$ -Author: Neil Schemenauer +Author: Neil Schemenauer , Guido van Rossum Status: Draft Type: Standards Track Content-Type: text/plain Created: 15-Feb-2006 -Python-Version: 2.5 +Python-Version: 2.6, 3.0 Post-History: @@ -20,74 +20,86 @@ Motivation - Python's current string objects are overloaded. They serve to hold - both sequences of characters and sequences of bytes. This - overloading of purpose leads to confusion and bugs. In future + Python's current string objects are overloaded. They serve to hold + both sequences of characters and sequences of bytes. This + overloading of purpose leads to confusion and bugs. In future versions of Python, string objects will be used for holding - character data. The bytes object will fulfil the role of a byte - container. Eventually the unicode built-in will be renamed to str + character data. The bytes object will fulfil the role of a byte + container. Eventually the unicode built-in will be renamed to str and the str object will be removed. Specification - A bytes object stores a mutable sequence of integers that are in the - range 0 to 255. Unlike string objects, indexing a bytes object - returns an integer. Assigning an element using a object that is not - an integer causes a TypeError exception. Assigning an element to a - value outside the range 0 to 255 causes a ValueError exception. The - __len__ method of bytes returns the number of integers stored in the - sequence (i.e. the number of bytes). + A bytes object stores a mutable sequence of integers that are in + the range 0 to 255. Unlike string objects, indexing a bytes + object returns an integer. Assigning an element using a object + that is not an integer causes a TypeError exception. Assigning an + element to a value outside the range 0 to 255 causes a ValueError + exception. The .__len__() method of bytes returns the number of + integers stored in the sequence (i.e. the number of bytes). The constructor of the bytes object has the following signature: bytes([initialiser[, [encoding]]) If no arguments are provided then an object containing zero elements - is created and returned. The initialiser argument can be a string - or a sequence of integers. The pseudo-code for the constructor is: + is created and returned. The initialiser argument can be a string, + a sequence of integers, or a single integer. The pseudo-code for the + constructor is: def bytes(initialiser=[], encoding=None): - if isinstance(initialiser, basestring): - if isinstance(initialiser, unicode): + if isinstance(initialiser, int): # In 2.6, (int, long) + initialiser = [0]*initialiser + elif isinstance(initialiser, basestring): + if isinstance(initialiser, unicode): # In 3.0, always if encoding is None: + # In 3.0, raise TypeError("explicit encoding required") encoding = sys.getdefaultencoding() initialiser = initialiser.encode(encoding) initialiser = [ord(c) for c in initialiser] - elif encoding is not None: - raise TypeError("explicit encoding invalid for non-string " - "initialiser") - create bytes object and fill with integers from initialiser + else: + if encoding is not None: + raise TypeError("explicit encoding invalid for non-string " + "initialiser") + # Create bytes object and fill with integers from initialiser + # while ensuring each integer is in range(256); initialiser + # can be any iterable return bytes object - The __repr__ method returns a string that can be evaluated to + The .__repr__() method returns a string that can be evaluated to generate a new bytes object containing the same sequence of - integers. The sequence is represented by a list of ints. For - example: + integers. The sequence is represented by a list of ints using + hexadecimal notation. For example: >>> repr(bytes[10, 20, 30]) - 'bytes([10, 20, 30])' + 'bytes([0x0a, 0x14, 0x1e])' - The object has a decode method equivalent to the decode method of - the str object. The object has a classmethod fromhex that takes a - string of characters from the set [0-9a-zA-Z ] and returns a bytes - object (similar to binascii.unhexlify). For example: + The object has a .decode() method equivalent to the .decode() + method of the str object. (This is redundant since it can also be + decoded by calling unicode(b, ) (in 2.6) or str(b, + ) (in 3.0); do we need encode/decode methods? In a + sense the spelling using a constructor is cleaner.) The object + has a classmethod .fromhex() that takes a string of characters + from the set [0-9a-zA-Z ] and returns a bytes object (similar to + binascii.unhexlify). For example: >>> bytes.fromhex('5c5350ff') bytes([92, 83, 80, 255]]) >>> bytes.fromhex('5c 53 50 ff') bytes([92, 83, 80, 255]]) - The object has a hex method that does the reverse conversion + The object has a .hex() method that does the reverse conversion (similar to binascii.hexlify): >> bytes([92, 83, 80, 255]]).hex() '5c5350ff' - The bytes object has methods similar to the list object: + The bytes object has some methods similar to list method, and + others similar to str methods: __add__ - __contains__ + __contains__ (with int arg, like list; with bytes arg, like str) __delitem__ __delslice__ __eq__ @@ -95,7 +107,6 @@ __getitem__ __getslice__ __gt__ - __hash__ __iadd__ __imul__ __iter__ @@ -107,16 +118,39 @@ __reduce__ __reduce_ex__ __repr__ + __reversed__ __rmul__ __setitem__ __setslice__ append count + decode + endswith extend + find index insert + join + partition pop remove + replace + rindex + rpartition + split + startswith + reverse + rfind + rindex + rsplit + translate + + Note the conspicuous absence of .isupper(), .upper(), and friends. + There is no __hash__ because the object is mutable. There is no + usecase for a .sort() method. + + The bytes also supports the buffer interface, supporting reading + and writing binary (but not character) data. Out of scope issues @@ -127,7 +161,9 @@ (which requires lexer and parser support in addition to everything else). Since there appears to be no immediate need for a literal representation, designing and implementing one is out of the scope - of this PEP. + of this PEP. (Hmm... A b"..." literal accepting only ASCII + values is likely to be added to 3.0; not clear about 2.6. This + needs a PEP.) * Python 3k will have a much different I/O subsystem. Deciding how that I/O subsystem will work and interact with the bytes object is @@ -140,19 +176,19 @@ Unresolved issues - * Perhaps the bytes object should be implemented as a extension - module until we are more sure of the design (similar to how the - set object was prototyped). - - * Should the bytes object implement the buffer interface? Probably, - but we need to look into the implications of that (e.g. regex - operations on byte arrays). + * Need to specify the methods more carefully. + + * Should all those list methods really be implemented? + + * A case could be made for supporting .ljust(), .rjust(), + .center() with a mandatory second argument. + + * A case could be made for supporting .split() with a mandatory + argument. - * Should the object implement __reversed__ and reverse? Should it - implement sort? + * How should pickling and marshalling work? - * Need to clarify what some of the methods do. How are comparisons - done? Hashing? Pickling and marshalling? + * I probably forgot a few things. Questions and answers @@ -174,7 +210,7 @@ Q: Why does bytes ignore the encoding argument if the initialiser is - a str? + a str? (This only applies to 2.6.) A: There is no sane meaning that the encoding can have in that case. str objects *are* byte arrays and they know nothing about the From python-checkins at python.org Fri Feb 23 01:22:40 2007 From: python-checkins at python.org (neal.norwitz) Date: Fri, 23 Feb 2007 01:22:40 +0100 (CET) Subject: [Python-checkins] r53861 - python/trunk/Lib/test/test_bsddb.py Message-ID: <20070223002240.668A31E4003@bag.python.org> Author: neal.norwitz Date: Fri Feb 23 01:22:39 2007 New Revision: 53861 Modified: python/trunk/Lib/test/test_bsddb.py Log: Fix typo in comment Modified: python/trunk/Lib/test/test_bsddb.py ============================================================================== --- python/trunk/Lib/test/test_bsddb.py (original) +++ python/trunk/Lib/test/test_bsddb.py Fri Feb 23 01:22:39 2007 @@ -205,7 +205,7 @@ # create iterator i = self.f.iteritems() nc2 = len(self.f._cursor_refs) - # use the iterator (should run to the first yeild, creating the cursor) + # use the iterator (should run to the first yield, creating the cursor) k, v = i.next() nc3 = len(self.f._cursor_refs) # destroy the iterator; this should cause the weakref callback From jimjjewett at gmail.com Fri Feb 23 03:38:08 2007 From: jimjjewett at gmail.com (Jim Jewett) Date: Thu, 22 Feb 2007 21:38:08 -0500 Subject: [Python-checkins] r53860 - peps/trunk/pep-0000.txt peps/trunk/pep-0358.txt In-Reply-To: <20070222235747.3546F1E4003@bag.python.org> References: <20070222235747.3546F1E4003@bag.python.org> Message-ID: > __setitem__ > __setslice__ > append > count > + decode > + endswith > extend > + find > index > insert > + join > + partition > remove > + replace > + rindex > + rpartition > + split > + startswith > + rfind > + rindex > + rsplit > + translate What sort of arguments do they take? Other bytes objects? (Then the literal is more important.) Unicode? With an extra decoding argument? Sequences of integers? Is startswith(500) False or a ValueException? Single integers? startswith(ord('A')) + Note the conspicuous absence of .isupper(), .upper(), and friends. This does force the use of more regular expressions, by ruling out data.upper().startswith("ERROR:") -jJ From python-checkins at python.org Fri Feb 23 05:31:19 2007 From: python-checkins at python.org (guido.van.rossum) Date: Fri, 23 Feb 2007 05:31:19 +0100 (CET) Subject: [Python-checkins] r53862 - peps/trunk/pep-0358.txt Message-ID: <20070223043119.401051E4011@bag.python.org> Author: guido.van.rossum Date: Fri Feb 23 05:31:15 2007 New Revision: 53862 Modified: peps/trunk/pep-0358.txt Log: Another update, clarifying (I hope) the method signatures and mentioning other stuff that came up over dinner. Modified: peps/trunk/pep-0358.txt ============================================================================== --- peps/trunk/pep-0358.txt (original) +++ peps/trunk/pep-0358.txt Fri Feb 23 05:31:15 2007 @@ -13,9 +13,16 @@ Abstract - This PEP outlines the introduction of a raw bytes sequence object. - Adding the bytes object is one step in the transition to Unicode - based str objects. + This PEP outlines the introduction of a raw bytes sequence type. + Adding the bytes type is one step in the transition to Unicode + based str objects which will be introduced in Python 3.0. + + The PEP describes how the bytes type should work in Python 2.6, as + well as how it should work in Python 3.0. (Occasionally there are + differences because in Python 2.6, we have two string types, str + and unicode, while in Python 3.0 we will only have one string + type, whose name will be str but whose semantics will be like the + 2.6 unicode type.) Motivation @@ -33,39 +40,48 @@ A bytes object stores a mutable sequence of integers that are in the range 0 to 255. Unlike string objects, indexing a bytes - object returns an integer. Assigning an element using a object - that is not an integer causes a TypeError exception. Assigning an - element to a value outside the range 0 to 255 causes a ValueError - exception. The .__len__() method of bytes returns the number of - integers stored in the sequence (i.e. the number of bytes). + object returns an integer. Assigning or comparin an object that + is not an integer to an element causes a TypeError exception. + Assigning an element to a value outside the range 0 to 255 causes + a ValueError exception. The .__len__() method of bytes returns + the number of integers stored in the sequence (i.e. the number of + bytes). The constructor of the bytes object has the following signature: - bytes([initialiser[, [encoding]]) + bytes([initializer[, encoding]]) - If no arguments are provided then an object containing zero elements - is created and returned. The initialiser argument can be a string, - a sequence of integers, or a single integer. The pseudo-code for the - constructor is: - - def bytes(initialiser=[], encoding=None): - if isinstance(initialiser, int): # In 2.6, (int, long) - initialiser = [0]*initialiser - elif isinstance(initialiser, basestring): - if isinstance(initialiser, unicode): # In 3.0, always + If no arguments are provided then a bytes object containing zero + elements is created and returned. The initializer argument can be + a string (in 2.6, either str or unicode), an iterable of integers, + or a single integer. The pseudo-code for the constructor + (optimized for clear semantics, not for speed) is: + + def bytes(initializer=0, encoding=None): + if isinstance(initializer, int): # In 2.6, (int, long) + initializer = [0]*initializer + elif isinstance(initializer, basestring): + if isinstance(initializer, unicode): # In 3.0, always if encoding is None: # In 3.0, raise TypeError("explicit encoding required") encoding = sys.getdefaultencoding() - initialiser = initialiser.encode(encoding) - initialiser = [ord(c) for c in initialiser] + initializer = initializer.encode(encoding) + initializer = [ord(c) for c in initializer] else: if encoding is not None: - raise TypeError("explicit encoding invalid for non-string " - "initialiser") - # Create bytes object and fill with integers from initialiser - # while ensuring each integer is in range(256); initialiser - # can be any iterable - return bytes object + raise TypeError("no encoding allowed for this initializer") + tmp = [] + for c in initializer: + if not isinstance(c, int): + raise TypeError("initializer must be iterable of ints") + if not 0 <= c < 256: + raise ValueError("initializer element out of range") + tmp.append(c) + initializer = tmp + new = + for i, c in enumerate(initializer): + new[i] = c + return new The .__repr__() method returns a string that can be evaluated to generate a new bytes object containing the same sequence of @@ -76,13 +92,10 @@ 'bytes([0x0a, 0x14, 0x1e])' The object has a .decode() method equivalent to the .decode() - method of the str object. (This is redundant since it can also be - decoded by calling unicode(b, ) (in 2.6) or str(b, - ) (in 3.0); do we need encode/decode methods? In a - sense the spelling using a constructor is cleaner.) The object - has a classmethod .fromhex() that takes a string of characters - from the set [0-9a-zA-Z ] and returns a bytes object (similar to - binascii.unhexlify). For example: + method of the str object. The object has a classmethod .fromhex() + that takes a string of characters from the set [0-9a-zA-Z ] and + returns a bytes object (similar to binascii.unhexlify). For + example: >>> bytes.fromhex('5c5350ff') bytes([92, 83, 80, 255]]) @@ -96,102 +109,118 @@ '5c5350ff' The bytes object has some methods similar to list method, and - others similar to str methods: + others similar to str methods. Here is a complete list of + methods, with their approximate signatures: - __add__ - __contains__ (with int arg, like list; with bytes arg, like str) - __delitem__ - __delslice__ - __eq__ - __ge__ - __getitem__ - __getslice__ - __gt__ - __iadd__ - __imul__ - __iter__ - __le__ - __len__ - __lt__ - __mul__ - __ne__ - __reduce__ - __reduce_ex__ - __repr__ - __reversed__ - __rmul__ - __setitem__ - __setslice__ - append - count - decode - endswith - extend - find - index - insert - join - partition - pop - remove - replace - rindex - rpartition - split - startswith - reverse - rfind - rindex - rsplit - translate + .__add__(bytes) -> bytes + .__contains__(int | bytes) -> bool + .__delitem__(int | slice) -> None + .__delslice__(int, int) -> None + .__eq__(bytes) -> bool + .__ge__(bytes) -> bool + .__getitem__(int | slice) -> int | bytes + .__getslice__(int, int) -> bytes + .__gt__(bytes) -> bool + .__iadd__(bytes) -> bytes + .__imul__(int) -> bytes + .__iter__() -> iterator + .__le__(bytes) -> bool + .__len__() -> int + .__lt__(bytes) -> bool + .__mul__(int) -> bytes + .__ne__(bytes) -> bool + .__reduce__(...) -> ... + .__reduce_ex__(...) -> ... + .__repr__() -> str + .__reversed__() -> bytes + .__rmul__(int) -> bytes + .__setitem__(int | slice, int | iterable[int]) -> None + .__setslice__(int, int, iterable[int]) -> Bote + .append(int) -> None + .count(int) -> int + .decode(str) -> str | unicode # in 3.0, only str + .endswith(bytes) -> bool + .extend(iterable[int]) -> None + .find(bytes) -> int + .index(bytes | int) -> int + .insert(int, int) -> None + .join(iterable[bytes]) -> bytes + .partition(bytes) -> (bytes, bytes, bytes) + .pop([int]) -> int + .remove(int) -> None + .replace(bytes, bytes) -> bytes + .rindex(bytes | int) -> int + .rpartition(bytes) -> (bytes, bytes, bytes) + .split(bytes) -> list[bytes] + .startswith(bytes) -> bool + .reverse() -> None + .rfind(bytes) -> int + .rindex(bytes | int) -> int + .rsplit(bytes) -> list[bytes] + .translate(bytes, [bytes]) -> bytes Note the conspicuous absence of .isupper(), .upper(), and friends. - There is no __hash__ because the object is mutable. There is no - usecase for a .sort() method. + (But see "Open Issues" below.) There is no .__hash__() because + the object is mutable. There is no use case for a .sort() method. - The bytes also supports the buffer interface, supporting reading - and writing binary (but not character) data. + The bytes type also supports the buffer interface, supporting + reading and writing binary (but not character) data. -Out of scope issues +Out of Scope Issues - * If we provide a literal syntax for bytes then it should look - distinctly different than the syntax for literal strings. Also, a - new type, even built-in, is much less drastic than a new literal - (which requires lexer and parser support in addition to everything - else). Since there appears to be no immediate need for a literal - representation, designing and implementing one is out of the scope - of this PEP. (Hmm... A b"..." literal accepting only ASCII - values is likely to be added to 3.0; not clear about 2.6. This - needs a PEP.) - - * Python 3k will have a much different I/O subsystem. Deciding how - that I/O subsystem will work and interact with the bytes object is - out of the scope of this PEP. + * Python 3k will have a much different I/O subsystem. Deciding + how that I/O subsystem will work and interact with the bytes + object is out of the scope of this PEP. The expectation however + is that binary I/O will read and write bytes, while text I/O + will read strings. Since the bytes type supports the buffer + interface, the existing binary I/O operations in Python 2.6 will + support bytes objects. - * It has been suggested that a special method named __bytes__ be - added to language to allow objects to be converted into byte + * It has been suggested that a special method named .__bytes__() + be added to language to allow objects to be converted into byte arrays. This decision is out of scope. -Unresolved issues +Open Issues - * Need to specify the methods more carefully. + * The .decode() method is redundant since a bytes object b can + also be decoded by calling unicode(b, ) (in 2.6) or + str(b, ) (in 3.0). Do we need encode/decode methods + at all? In a sense the spelling using a constructor is cleaner. + + * Need to specify the methods still more carefully. + + * Pickling and marshalling support need to be specified. * Should all those list methods really be implemented? + * There is growing support for a b"..." literal. Here's a brief + spec. Each invocation of b"..." produces a new bytes object + (this is unlike "..." but similar to [...] and {...}). Inside + the literal, only ASCII characters and non-Unicode backslas