From python-checkins at python.org Wed Jul 5 15:04:33 2006 From: python-checkins at python.org (richard.tew) Date: Wed, 5 Jul 2006 15:04:33 +0200 (CEST) Subject: [Stackless-checkins] r47240 - stackless/Python-2.4.3/dev/Stackless/platf/switch_ppc_macosx.h Message-ID: <20060705130433.E8E911E4003@bag.python.org> Author: richard.tew Date: Wed Jul 5 15:04:32 2006 New Revision: 47240 Modified: stackless/Python-2.4.3/dev/Stackless/platf/switch_ppc_macosx.h Log: Patch from Jeff Senn to fix OS X compilation problems. One prevented Stackless from being compiled because one of the registers preserved was now clobbered in the generated assembly code. The other was a warning because of the types used in slp_switch. Modified: stackless/Python-2.4.3/dev/Stackless/platf/switch_ppc_macosx.h ============================================================================== --- stackless/Python-2.4.3/dev/Stackless/platf/switch_ppc_macosx.h (original) +++ stackless/Python-2.4.3/dev/Stackless/platf/switch_ppc_macosx.h Wed Jul 5 15:04:32 2006 @@ -33,14 +33,15 @@ #define STACK_MAGIC 3 #define REGS_TO_SAVE "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", \ - "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r31", \ + "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", \ "cr2", "cr3", "cr4" static int slp_switch(void) { static int x = 0; - register int *stackref, stsizediff; + register intptr_t *stackref; + register int stsizediff; __asm__ volatile ( "; asm block 1\n" : /* no outputs */ @@ -70,7 +71,7 @@ * further self-processing support */ -/* +/* * if you want to add self-inspection tools, place them * here. See the x86_msvc for the necessary defines. * These features are highly experimental und not _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Thu Jul 13 19:49:59 2006 From: python-checkins at python.org (richard.tew) Date: Thu, 13 Jul 2006 19:49:59 +0200 (CEST) Subject: [Stackless-checkins] r50623 - in stackless/trunk: Objects/abstract.c Python/pythonrun.c Stackless/module/scheduling.c Message-ID: <20060713174959.661121E4007@bag.python.org> Author: richard.tew Date: Thu Jul 13 19:49:58 2006 New Revision: 50623 Modified: stackless/trunk/Objects/abstract.c stackless/trunk/Python/pythonrun.c stackless/trunk/Stackless/module/scheduling.c Log: Restored PyObject_Call. Had to comment out the assertion about the recursion depth in scheduling.c:schedule_tasklet_destruct, as this can no longer be assumed to be the same every time. This fixes the Python regression tests. Modified: stackless/trunk/Objects/abstract.c ============================================================================== --- stackless/trunk/Objects/abstract.c (original) +++ stackless/trunk/Objects/abstract.c Thu Jul 13 19:49:58 2006 @@ -1799,15 +1799,6 @@ if ((call = func->ob_type->tp_call) != NULL) { PyObject *result = NULL; -#ifdef STACKLESS - /* We disable this recursiveness because it breaks our - stackless expectations, this value gets passed all - the way down to where we make current the main tasklet - and then destroy it when it ends. At which point - schedule_task_destruct finds the recursion addition - and disagrees with its presence asserting. - */ -#else /* slot_tp_call() will be called and ends up calling PyObject_Call() if the object returned for __call__ has __call__ itself defined upon it. This can be an infinite @@ -1816,12 +1807,9 @@ if (Py_EnterRecursiveCall(" in __call__")) { return NULL; } -#endif result = (STACKLESS_PROMOTE(func), (*call)(func, arg, kw)); STACKLESS_ASSERT(); -#ifndef STACKLESS Py_LeaveRecursiveCall(); -#endif if (result == NULL && !PyErr_Occurred()) PyErr_SetString( PyExc_SystemError, Modified: stackless/trunk/Python/pythonrun.c ============================================================================== --- stackless/trunk/Python/pythonrun.c (original) +++ stackless/trunk/Python/pythonrun.c Thu Jul 13 19:49:58 2006 @@ -1215,12 +1215,15 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags) { + STACKLESS_GETARG(); PyObject *ret = NULL; PyArena *arena = PyArena_New(); mod_ty mod = PyParser_ASTFromString(str, "", start, flags, arena); - if (mod != NULL) + if (mod != NULL) { + STACKLESS_PROMOTE_ALL(); ret = run_mod(mod, "", globals, locals, flags, arena); + } PyArena_Free(arena); return ret; } Modified: stackless/trunk/Stackless/module/scheduling.c ============================================================================== --- stackless/trunk/Stackless/module/scheduling.c (original) +++ stackless/trunk/Stackless/module/scheduling.c Thu Jul 13 19:49:58 2006 @@ -997,8 +997,8 @@ ts->st.nesting_level = 0; } - /* update what's not yet updated */ - assert(ts->recursion_depth == 0); + /* update what's not yet updated + assert(ts->recursion_depth == 0);*/ prev->recursion_depth = 0; assert(ts->frame == NULL); prev->f.frame = NULL; _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Fri Jul 14 16:03:31 2006 From: python-checkins at python.org (richard.tew) Date: Fri, 14 Jul 2006 16:03:31 +0200 (CEST) Subject: [Stackless-checkins] r50637 - stackless/trunk/Lib/platform.py Message-ID: <20060714140331.C31F31E4004@bag.python.org> Author: richard.tew Date: Fri Jul 14 16:03:30 2006 New Revision: 50637 Modified: stackless/trunk/Lib/platform.py Log: Adjusted the sys.platform regular expression to ignore the inserted Stackless part, so that test_platform.py would pass. Modified: stackless/trunk/Lib/platform.py ============================================================================== --- stackless/trunk/Lib/platform.py (original) +++ stackless/trunk/Lib/platform.py Fri Jul 14 16:03:30 2006 @@ -1092,7 +1092,9 @@ ### Various APIs for extracting information from sys.version +# The second element is the Stackless part of the version string. _sys_version_parser = re.compile(r'([\w.+]+)\s*' + '.*' '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*' '\[([^\]]+)\]?') _sys_version_cache = None _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Wed Jul 5 00:04:09 2006 From: python-checkins at python.org (richard.tew) Date: Wed, 5 Jul 2006 00:04:09 +0200 (CEST) Subject: [Stackless-checkins] r47232 - stackless/trunk/Stackless/core/stacklesseval.c Message-ID: <20060704220409.4CE3E1E4009@bag.python.org> Author: richard.tew Date: Wed Jul 5 00:04:06 2006 New Revision: 47232 Modified: stackless/trunk/Stackless/core/stacklesseval.c Log: Ported some additional generator sending code, into the custom stackless version. It turns out this is needed, otherwise a POP_TOP operation chews up the iterator, and causes a crash when whatever comes next is iterated on. I assumed this stack changing did not require, because of the way Stackless passes around return values - that is, it was enough to pass it around through the unwind object. Modified: stackless/trunk/Stackless/core/stacklesseval.c ============================================================================== --- stackless/trunk/Stackless/core/stacklesseval.c (original) +++ stackless/trunk/Stackless/core/stacklesseval.c Wed Jul 5 00:04:06 2006 @@ -464,6 +464,7 @@ /* Push arg onto the frame's value stack */ retval = arg ? arg : Py_None; Py_INCREF(retval); + *(f->f_stacktop++) = retval; } /* XXX give the patch to python-dev */ _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Thu Jul 13 22:08:21 2006 From: python-checkins at python.org (richard.tew) Date: Thu, 13 Jul 2006 22:08:21 +0200 (CEST) Subject: [Stackless-checkins] r50624 - stackless/trunk/Stackless/pickling/prickelpit.c Message-ID: <20060713200821.9871E1E4008@bag.python.org> Author: richard.tew Date: Thu Jul 13 22:08:21 2006 New Revision: 50624 Modified: stackless/trunk/Stackless/pickling/prickelpit.c Log: Unpickling of a generator creates a temporary generator to do some initialisation which I do not understand the purpose of, however, when this generator is discarded, the frame attached to it is has GeneratorExit raised on it, leaving it ruined for the real use after the unpickling. I clear the frame reference before discarding the temporary generator. Modified: stackless/trunk/Stackless/pickling/prickelpit.c ============================================================================== --- stackless/trunk/Stackless/pickling/prickelpit.c (original) +++ stackless/trunk/Stackless/pickling/prickelpit.c Thu Jul 13 22:08:21 2006 @@ -2025,9 +2025,9 @@ if (!gi_running) { if ((f = slp_ensure_new_frame(f)) != NULL) { /* use a second one for late initialization */ - genobject *tmp; + genobject *tmpgen; /* PyGenerator_New eats an existing reference */ - if ((tmp = (genobject *) + if ((tmpgen = (genobject *) PyGenerator_New(f)) == NULL) { Py_DECREF(f); return NULL; @@ -2035,7 +2035,13 @@ Py_INCREF(f); Py_DECREF(gen->gi_frame); gen->gi_frame = f; - Py_DECREF(tmp); + /* The frame the temporary generator references + will have GeneratorExit raised on it, when the + temporary generator is torn down. So clearing + the frame from the temporary generator before + discarding it, will save the frame for later. */ + Py_CLEAR(((PyGenObject *)tmpgen)->gi_frame); + Py_DECREF(tmpgen); Py_INCREF(gen); gen->ob_type = gen->ob_type->tp_base; } _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Thu Jul 13 22:15:52 2006 From: python-checkins at python.org (richard.tew) Date: Thu, 13 Jul 2006 22:15:52 +0200 (CEST) Subject: [Stackless-checkins] r50625 - stackless/trunk/Stackless/module/scheduling.c Message-ID: <20060713201552.5AA9D1E4009@bag.python.org> Author: richard.tew Date: Thu Jul 13 22:15:52 2006 New Revision: 50625 Modified: stackless/trunk/Stackless/module/scheduling.c Log: Added the reason why the recursion depth is no longer checked in schedule_task_destruct as a comment. Modified: stackless/trunk/Stackless/module/scheduling.c ============================================================================== --- stackless/trunk/Stackless/module/scheduling.c (original) +++ stackless/trunk/Stackless/module/scheduling.c Thu Jul 13 22:15:52 2006 @@ -998,6 +998,8 @@ } /* update what's not yet updated + This has been removed because PyObject_Call now adds a + recursion level, which causes the value here to differ. assert(ts->recursion_depth == 0);*/ prev->recursion_depth = 0; assert(ts->frame == NULL); _______________________________________________ Stackless-checkins mailing list Stackless-checkins at stackless.com http://www.stackless.com/mailman/listinfo/stackless-checkins From python-checkins at python.org Fri Jul 14 14:40:10 2006 From: python-checkins at python.org (richard.tew) Date: Fri, 14 Jul 2006 14:40:10 +0200 (CEST) Subject: [Stackless-checkins] r50634 - in stackless/trunk: Doc/Makefile.deps Doc/api/concrete.tex Doc/commontex/boilerplate.tex Doc/dist/dist.tex Doc/howto/Makefile Doc/lib/lib.tex Doc/lib/libcookielib.tex Doc/lib/libctypes.tex Doc/lib/libetree.tex Doc/lib/libfuncs.tex Doc/lib/libstdtypes.tex Doc/lib/libsys.tex Doc/lib/libturtle.tex Doc/lib/libuuid.tex Doc/lib/libwarnings.tex Doc/tut/tut.tex Doc/whatsnew/whatsnew20.tex Doc/whatsnew/whatsnew23.tex Doc/whatsnew/whatsnew25.tex Include/patchlevel.h Include/pystate.h Lib/compiler/transformer.py Lib/ctypes/test/test_objects.py Lib/ctypes/test/test_parameters.py Lib/ctypes/test/test_pointers.py Lib/ctypes/test/test_structures.py Lib/ctypes/test/test_win32.py Lib/distutils/command/bdist_rpm.py Lib/distutils/command/upload.py Lib/distutils/msvccompiler.py Lib/distutils/sysconfig.py Lib/distutils/unixccompiler.py Lib/idlelib/Debugger.py Lib/idlelib/NEWS.txt Lib/idlelib/idlever.py Lib/inspect.py Lib/lib-tk/turtle.py Lib/logging/config.py Lib/logging/handle! rs.py Lib/mailbox.py Lib/msilib/__init__.py Lib/popen2.py Lib/sgmllib.py Lib/socket.py Lib/sqlite3/test/types.py Lib/sqlite3/test/userfunctions.py Lib/string.py Lib/subprocess.py Lib/tarfile.py Lib/telnetlib.py Lib/test/crashers/bogus_code_obj.py Lib/test/crashers/borrowed_ref_1.py Lib/test/crashers/borrowed_ref_2.py Lib/test/crashers/gc_inspection.py Lib/test/crashers/xml_parsers.py Lib/test/fork_wait.py Lib/test/regrtest.py Lib/test/test__locale.py Lib/test/test_ast.py Lib/test/test_builtin.py Lib/test/test_bz2.py Lib/test/test_cmd_line.py Lib/test/test_commands.py Lib/test/test_compile.py Lib/test/test_compiler.py Lib/test/test_descr.py Lib/test/test_exceptions.py Lib/test/test_fcntl.py Lib/test/test_fork1.py Lib/test/test_inspect.py Lib/test/test_logging.py Lib/test/test_mailbox.py Lib/test/test_multibytecodec.py Lib/test/test_os.py Lib/test/test_pep292.py Lib/test/test_popen.py Lib/test/test_popen2.py Lib/test/test_pyexpat.py Lib/test/test_scope.py Lib/test/test_select! .py Lib/test/test_sgmllib.py Lib/test/test_socket.py Lib/test/test_socket_ssl.py Lib/test/test_socketserver.py Lib/test/test_subprocess.py Lib/test/test_support.py Lib/test/test_sys.py Lib/test/test_wait3.py Lib/test/test_wait4.py Lib/test/test_warnings.py Lib/warnings.py Lib/xmlcore/etree/ElementTree.py Mac/BuildScript/buil Message-ID: <20060714124010.994AA1E4004@bag.python.org> Author: richard.tew Date: Fri Jul 14 14:39:40 2006 New Revision: 50634 Added: stackless/trunk/Doc/lib/libetree.tex - copied unchanged from r50568, python/trunk/Doc/lib/libetree.tex stackless/trunk/Doc/lib/libuuid.tex - copied unchanged from r50568, python/trunk/Doc/lib/libuuid.tex stackless/trunk/Lib/test/crashers/bogus_code_obj.py - copied unchanged from r50568, python/trunk/Lib/test/crashers/bogus_code_obj.py stackless/trunk/Lib/test/crashers/borrowed_ref_1.py - copied unchanged from r50568, python/trunk/Lib/test/crashers/borrowed_ref_1.py stackless/trunk/Lib/test/crashers/borrowed_ref_2.py - copied unchanged from r50568, python/trunk/Lib/test/crashers/borrowed_ref_2.py stackless/trunk/Lib/test/crashers/gc_inspection.py - copied unchanged from r50568, python/trunk/Lib/test/crashers/gc_inspection.py Removed: stackless/trunk/Lib/test/crashers/xml_parsers.py stackless/trunk/Mac/Demo/calldll/ Modified: stackless/trunk/Doc/Makefile.deps stackless/trunk/Doc/api/concrete.tex stackless/trunk/Doc/commontex/boilerplate.tex stackless/trunk/Doc/dist/dist.tex stackless/trunk/Doc/howto/Makefile stackless/trunk/Doc/lib/lib.tex stackless/trunk/Doc/lib/libcookielib.tex stackless/trunk/Doc/lib/libctypes.tex stackless/trunk/Doc/lib/libfuncs.tex stackless/trunk/Doc/lib/libstdtypes.tex stackless/trunk/Doc/lib/libsys.tex stackless/trunk/Doc/lib/libturtle.tex stackless/trunk/Doc/lib/libwarnings.tex stackless/trunk/Doc/tut/tut.tex stackless/trunk/Doc/whatsnew/whatsnew20.tex stackless/trunk/Doc/whatsnew/whatsnew23.tex stackless/trunk/Doc/whatsnew/whatsnew25.tex stackless/trunk/Include/patchlevel.h stackless/trunk/Include/pystate.h stackless/trunk/Lib/compiler/transformer.py stackless/trunk/Lib/ctypes/test/test_objects.py stackless/trunk/Lib/ctypes/test/test_parameters.py stackless/trunk/Lib/ctypes/test/test_pointers.py stackless/trunk/Lib/ctypes/test/test_structures.py stackless/trunk/Lib/ctypes/test/test_win32.py stackless/trunk/Lib/distutils/command/bdist_rpm.py stackless/trunk/Lib/distutils/command/upload.py stackless/trunk/Lib/distutils/msvccompiler.py stackless/trunk/Lib/distutils/sysconfig.py stackless/trunk/Lib/distutils/unixccompiler.py stackless/trunk/Lib/idlelib/Debugger.py stackless/trunk/Lib/idlelib/NEWS.txt stackless/trunk/Lib/idlelib/idlever.py stackless/trunk/Lib/inspect.py stackless/trunk/Lib/lib-tk/turtle.py stackless/trunk/Lib/logging/config.py stackless/trunk/Lib/logging/handlers.py stackless/trunk/Lib/mailbox.py stackless/trunk/Lib/msilib/__init__.py stackless/trunk/Lib/popen2.py stackless/trunk/Lib/sgmllib.py stackless/trunk/Lib/socket.py stackless/trunk/Lib/sqlite3/test/types.py stackless/trunk/Lib/sqlite3/test/userfunctions.py stackless/trunk/Lib/string.py stackless/trunk/Lib/subprocess.py stackless/trunk/Lib/tarfile.py stackless/trunk/Lib/telnetlib.py stackless/trunk/Lib/test/fork_wait.py stackless/trunk/Lib/test/regrtest.py stackless/trunk/Lib/test/test__locale.py stackless/trunk/Lib/test/test_ast.py stackless/trunk/Lib/test/test_builtin.py stackless/trunk/Lib/test/test_bz2.py stackless/trunk/Lib/test/test_cmd_line.py stackless/trunk/Lib/test/test_commands.py stackless/trunk/Lib/test/test_compile.py stackless/trunk/Lib/test/test_compiler.py stackless/trunk/Lib/test/test_descr.py stackless/trunk/Lib/test/test_exceptions.py stackless/trunk/Lib/test/test_fcntl.py stackless/trunk/Lib/test/test_fork1.py stackless/trunk/Lib/test/test_inspect.py stackless/trunk/Lib/test/test_logging.py stackless/trunk/Lib/test/test_mailbox.py stackless/trunk/Lib/test/test_multibytecodec.py stackless/trunk/Lib/test/test_os.py stackless/trunk/Lib/test/test_pep292.py stackless/trunk/Lib/test/test_popen.py stackless/trunk/Lib/test/test_popen2.py stackless/trunk/Lib/test/test_pyexpat.py stackless/trunk/Lib/test/test_scope.py stackless/trunk/Lib/test/test_select.py stackless/trunk/Lib/test/test_sgmllib.py stackless/trunk/Lib/test/test_socket.py stackless/trunk/Lib/test/test_socket_ssl.py stackless/trunk/Lib/test/test_socketserver.py stackless/trunk/Lib/test/test_subprocess.py stackless/trunk/Lib/test/test_support.py stackless/trunk/Lib/test/test_sys.py stackless/trunk/Lib/test/test_wait3.py stackless/trunk/Lib/test/test_wait4.py stackless/trunk/Lib/test/test_warnings.py stackless/trunk/Lib/warnings.py stackless/trunk/Lib/xmlcore/etree/ElementTree.py stackless/trunk/Mac/BuildScript/build-installer.py stackless/trunk/Mac/BuildScript/resources/Welcome.rtf stackless/trunk/Mac/BuildScript/scripts/postflight.framework stackless/trunk/Mac/Demo/applescript.html stackless/trunk/Mac/Demo/index.html stackless/trunk/Makefile.pre.in stackless/trunk/Misc/NEWS stackless/trunk/Misc/RPM/python-2.5.spec stackless/trunk/Misc/Vim/python.vim stackless/trunk/Misc/build.sh stackless/trunk/Misc/cheatsheet stackless/trunk/Misc/valgrind-python.supp stackless/trunk/Modules/_ctypes/_ctypes.c stackless/trunk/Modules/_ctypes/callbacks.c stackless/trunk/Modules/_ctypes/callproc.c stackless/trunk/Modules/_ctypes/cfield.c stackless/trunk/Modules/_ctypes/libffi/src/x86/darwin.S stackless/trunk/Modules/_ctypes/libffi/src/x86/ffi_darwin.c stackless/trunk/Modules/_ctypes/libffi_msvc/ffi.c stackless/trunk/Modules/_ctypes/libffi_msvc/fficonfig.h stackless/trunk/Modules/_ctypes/libffi_msvc/ffitarget.h stackless/trunk/Modules/_sqlite/cursor.c stackless/trunk/Modules/_sqlite/module.h stackless/trunk/Modules/_ssl.c stackless/trunk/Modules/bz2module.c stackless/trunk/Modules/cPickle.c stackless/trunk/Modules/cryptmodule.c stackless/trunk/Modules/dlmodule.c stackless/trunk/Modules/fpectlmodule.c stackless/trunk/Modules/getpath.c stackless/trunk/Modules/posixmodule.c stackless/trunk/Modules/pyexpat.c stackless/trunk/Modules/selectmodule.c stackless/trunk/Modules/socketmodule.c stackless/trunk/Modules/timemodule.c stackless/trunk/Objects/abstract.c stackless/trunk/Objects/cellobject.c stackless/trunk/Objects/descrobject.c stackless/trunk/Objects/exceptions.c stackless/trunk/Objects/fileobject.c stackless/trunk/Objects/typeobject.c stackless/trunk/PCbuild/readme.txt stackless/trunk/Python/ast.c stackless/trunk/Python/ceval.c stackless/trunk/Python/codecs.c stackless/trunk/Python/compile.c stackless/trunk/Python/import.c stackless/trunk/Python/mystrtoul.c stackless/trunk/Python/pystate.c stackless/trunk/Python/pystrtod.c stackless/trunk/Python/sysmodule.c stackless/trunk/README stackless/trunk/Stackless/core/stacklesseval.c stackless/trunk/Stackless/module/scheduling.c stackless/trunk/Tools/msi/ (props changed) stackless/trunk/Tools/msi/msi.py stackless/trunk/configure stackless/trunk/configure.in stackless/trunk/setup.py Log: Merged in the changelists included up to the 2.5b2 tag. This fixes the problems with inconsistent recursion depth in scheduling.c:schedule_tasklet_destruct, and the Stackless unit test warnings. Modified: stackless/trunk/Doc/Makefile.deps ============================================================================== --- stackless/trunk/Doc/Makefile.deps (original) +++ stackless/trunk/Doc/Makefile.deps Fri Jul 14 14:39:40 2006 @@ -270,6 +270,7 @@ lib/xmlsaxhandler.tex \ lib/xmlsaxutils.tex \ lib/xmlsaxreader.tex \ + lib/libetree.tex \ lib/libqueue.tex \ lib/liblocale.tex \ lib/libgettext.tex \ Modified: stackless/trunk/Doc/api/concrete.tex ============================================================================== --- stackless/trunk/Doc/api/concrete.tex (original) +++ stackless/trunk/Doc/api/concrete.tex Fri Jul 14 14:39:40 2006 @@ -376,7 +376,7 @@ \versionadded{2.3} \end{cfuncdesc} -\begin{cfuncdesc}{unsigned long}{PyLong_AsUnsignedLongLongMask}{PyObject *io} +\begin{cfuncdesc}{unsigned PY_LONG_LONG}{PyLong_AsUnsignedLongLongMask}{PyObject *io} Return a C \ctype{unsigned long long} from a Python long integer, without checking for overflow. \versionadded{2.3} Modified: stackless/trunk/Doc/commontex/boilerplate.tex ============================================================================== --- stackless/trunk/Doc/commontex/boilerplate.tex (original) +++ stackless/trunk/Doc/commontex/boilerplate.tex Fri Jul 14 14:39:40 2006 @@ -5,5 +5,5 @@ Email: \email{docs at python.org} } -\date{20 June, 2006} % XXX update before final release! +\date{11th July, 2006} % XXX update before final release! \input{patchlevel} % include Python version information Modified: stackless/trunk/Doc/dist/dist.tex ============================================================================== --- stackless/trunk/Doc/dist/dist.tex (original) +++ stackless/trunk/Doc/dist/dist.tex Fri Jul 14 14:39:40 2006 @@ -2873,9 +2873,20 @@ \modulesynopsis{Microsoft Compiler} This module provides \class{MSVCCompiler}, an implementation of the abstract -\class{CCompiler} class for Microsoft Visual Studio. It should also work using -the freely available compiler provided as part of the .Net SDK download. XXX -download link. +\class{CCompiler} class for Microsoft Visual Studio. Typically, extension +modules need to be compiled with the same compiler that was used to compile +Python. For Python 2.3 and earlier, the compiler was Visual Studio 6. For +Python 2.4 and 2.5, the compiler is Visual Studio .NET 2003. The AMD64 +and Itanium binaries are created using the Platform SDK. + +\class{MSVCCompiler} will normally choose the right compiler, linker etc. +on its own. To override this choice, the environment variables +\var{DISTUTILS\_USE\_SDK} and \var{MSSdk} must be both set. \var{MSSdk} +indicates that the current environment has been setup by the SDK's +\code{SetEnv.Cmd} script, or that the environment variables had been +registered when the SDK was installed; \var{DISTUTILS\_USE\_SDK} indicates +that the distutils user has made an explicit choice to override the +compiler selection by \class{MSVCCompiler}. \section{\module{distutils.bcppcompiler} --- Borland Compiler} \declaremodule{standard}{distutils.bcppcompiler} Modified: stackless/trunk/Doc/howto/Makefile ============================================================================== --- stackless/trunk/Doc/howto/Makefile (original) +++ stackless/trunk/Doc/howto/Makefile Fri Jul 14 14:39:40 2006 @@ -1,88 +1,84 @@ +# Makefile for the HOWTO directory +# LaTeX HOWTOs can be turned into HTML, PDF, PS, DVI or plain text output. +# reST HOWTOs can only be turned into HTML. -MKHOWTO=../tools/mkhowto -WEBDIR=. +# Variables to change + +# Paper size for non-HTML formats (letter or a4) +PAPER=letter + +# Arguments to rst2html.py, and location of the script RSTARGS = --input-encoding=utf-8 -VPATH=.:dvi:pdf:ps:txt +RST2HTML = rst2html.py -# List of HOWTOs that aren't to be processed +# List of HOWTOs that aren't to be processed. This should contain the +# base name of the HOWTO without any extension (e.g. 'advocacy', +# 'unicode'). +REMOVE_HOWTOS = -REMOVE_HOWTO = +MKHOWTO=../tools/mkhowto +WEBDIR=. +PAPERDIR=../paper-$(PAPER) +HTMLDIR=../html # Determine list of files to be built - -HOWTO=$(filter-out $(REMOVE_HOWTO),$(wildcard *.tex)) -RST_SOURCES = $(shell echo *.rst) -DVI =$(patsubst %.tex,%.dvi,$(HOWTO)) -PDF =$(patsubst %.tex,%.pdf,$(HOWTO)) -PS =$(patsubst %.tex,%.ps,$(HOWTO)) -TXT =$(patsubst %.tex,%.txt,$(HOWTO)) -HTML =$(patsubst %.tex,%,$(HOWTO)) +TEX_SOURCES = $(wildcard *.tex) +RST_SOURCES = $(wildcard *.rst) +TEX_NAMES = $(filter-out $(REMOVE_HOWTOS),$(patsubst %.tex,%,$(TEX_SOURCES))) + +PAPER_PATHS=$(addprefix $(PAPERDIR)/,$(TEX_NAMES)) +DVI =$(addsuffix .dvi,$(PAPER_PATHS)) +PDF =$(addsuffix .pdf,$(PAPER_PATHS)) +PS =$(addsuffix .ps,$(PAPER_PATHS)) + +ALL_HOWTO_NAMES = $(TEX_NAMES) $(patsubst %.rst,%,$(RST_SOURCES)) +HOWTO_NAMES = $(filter-out $(REMOVE_HOWTOS),$(ALL_HOWTO_NAMES)) +HTML = $(addprefix $(HTMLDIR)/,$(HOWTO_NAMES)) # Rules for building various formats -%.dvi : %.tex + +# reST to HTML +$(HTMLDIR)/%: %.rst + if [ ! -d $@ ] ; then mkdir $@ ; fi + $(RST2HTML) $(RSTARGS) $< >$@/index.html + +# LaTeX to various output formats +$(PAPERDIR)/%.dvi : %.tex $(MKHOWTO) --dvi $< - mv $@ dvi + mv $*.dvi $@ -%.pdf : %.tex +$(PAPERDIR)/%.pdf : %.tex $(MKHOWTO) --pdf $< - mv $@ pdf + mv $*.pdf $@ -%.ps : %.tex +$(PAPERDIR)/%.ps : %.tex $(MKHOWTO) --ps $< - mv $@ ps + mv $*.ps $@ -%.txt : %.tex +$(HTMLDIR)/% : %.tex + $(MKHOWTO) --html --iconserver="." --dir $@ $< + +# Rule that isn't actually used -- we no longer support the 'txt' target. +$(PAPERDIR)/%.txt : %.tex $(MKHOWTO) --text $< mv $@ txt -% : %.tex - $(MKHOWTO) --html --iconserver="." $< - tar -zcvf html/$*.tgz $* - #zip -r html/$*.zip $* - default: @echo "'all' -- build all files" - @echo "'dvi', 'pdf', 'ps', 'txt', 'html' -- build one format" - -all: $(HTML) - -.PHONY : dvi pdf ps txt html rst -dvi: $(DVI) + @echo "'dvi', 'pdf', 'ps', 'html' -- build one format" -pdf: $(PDF) -ps: $(PS) -txt: $(TXT) -html:$(HTML) - -# Rule to build collected tar files -dist: #all - for i in dvi pdf ps txt ; do \ - cd $$i ; \ - tar -zcf All.tgz *.$$i ;\ - cd .. ;\ - done - -# Rule to copy files to the Web tree on AMK's machine -web: dist - cp dvi/* $(WEBDIR)/dvi - cp ps/* $(WEBDIR)/ps - cp pdf/* $(WEBDIR)/pdf - cp txt/* $(WEBDIR)/txt - for dir in $(HTML) ; do cp -rp $$dir $(WEBDIR) ; done - for ltx in $(HOWTO) ; do cp -p $$ltx $(WEBDIR)/latex ; done +all: dvi pdf ps html -rst: unicode.html - -%.html: %.rst - rst2html $(RSTARGS) $< >$@ +.PHONY : dvi pdf ps html +dvi: $(DVI) +pdf: $(PDF) +ps: $(PS) +html: $(HTML) clean: - rm -f *~ *.log *.ind *.l2h *.aux *.toc *.how - rm -f *.dvi *.ps *.pdf *.bkm - rm -f unicode.html + rm -f *~ *.log *.ind *.l2h *.aux *.toc *.how *.bkm + rm -f *.dvi *.pdf *.ps clobber: - rm dvi/* ps/* pdf/* txt/* html/* - - - + rm -rf $(HTML) + rm -rf $(DVI) $(PDF) $(PS) Modified: stackless/trunk/Doc/lib/lib.tex ============================================================================== --- stackless/trunk/Doc/lib/lib.tex (original) +++ stackless/trunk/Doc/lib/lib.tex Fri Jul 14 14:39:40 2006 @@ -171,6 +171,7 @@ \input{xmlsaxhandler} \input{xmlsaxutils} \input{xmlsaxreader} +\input{libetree} % \input{libxmllib} \input{fileformats} % Miscellaneous file formats @@ -303,6 +304,7 @@ \input{libsmtplib} \input{libsmtpd} \input{libtelnetlib} +\input{libuuid} \input{liburlparse} \input{libsocksvr} \input{libbasehttp} Modified: stackless/trunk/Doc/lib/libcookielib.tex ============================================================================== --- stackless/trunk/Doc/lib/libcookielib.tex (original) +++ stackless/trunk/Doc/lib/libcookielib.tex Fri Jul 14 14:39:40 2006 @@ -24,7 +24,7 @@ the de-facto Netscape cookie protocol (which differs substantially from that set out in the original Netscape specification), including taking note of the \code{max-age} and \code{port} cookie-attributes -introduced with RFC 2109. \note{The various named parameters found in +introduced with RFC 2965. \note{The various named parameters found in \mailheader{Set-Cookie} and \mailheader{Set-Cookie2} headers (eg. \code{domain} and \code{expires}) are conventionally referred to as \dfn{attributes}. To distinguish them from Python attributes, the Modified: stackless/trunk/Doc/lib/libctypes.tex ============================================================================== --- stackless/trunk/Doc/lib/libctypes.tex (original) +++ stackless/trunk/Doc/lib/libctypes.tex Fri Jul 14 14:39:40 2006 @@ -1543,13 +1543,13 @@ The following public attributes are available, their name starts with an underscore to not clash with exported function names: -\begin{datadescni}{_handle: memberdesc} +\begin{memberdesc}{_handle} The system handle used to access the library. -\end{datadescni} +\end{memberdesc} -\begin{datadescni}{_name: memberdesc} +\begin{memberdesc}{_name} The name of the library passed in the contructor. -\end{datadescni} +\end{memberdesc} Shared libraries can also be loaded by using one of the prefabricated objects, which are instances of the \class{LibraryLoader} class, either by @@ -1648,6 +1648,12 @@ example, a \class{c{\_}char{\_}p} item in the \member{argtypes} tuple will convert a unicode string passed as argument into an byte string using ctypes conversion rules. + +New: It is now possible to put items in argtypes which are not +ctypes types, but each item must have a \method{from{\_}param} method +which returns a value usable as argument (integer, string, ctypes +instance). This allows to define adapters that can adapt custom +objects as function parameters. \end{memberdesc} \begin{memberdesc}{errcheck} @@ -1748,7 +1754,7 @@ Each item in this tuple contains further information about a parameter, it must be a tuple containing 1, 2, or 3 items. -The first item is an integer containing flags for the parameter. +The first item is an integer containing flags for the parameter: \begin{datadescni}{1} Specifies an input parameter to the function. @@ -2374,7 +2380,7 @@ \code{u} field is defined as anonymous field, it is now possible to access the members directly off the TYPEDESC instance. \code{td.lptdesc} and \code{td.u.lptdesc} are equivalent, but the former -is faster since it does not need to create a temporary \code{{\_}U} +is faster since it does not need to create a temporary union instance: \begin{verbatim} td = TYPEDESC() @@ -2386,9 +2392,16 @@ It is possible to defined sub-subclasses of structures, they inherit the fields of the base class. If the subclass definition has a -separate``{\_}fields{\_}`` variable, the fields specified in this are +separate \member{{\_}fields{\_}} variable, the fields specified in this are appended to the fields of the base class. +Structure and union constructors accept both positional and +keyword arguments. Positional arguments are used to initialize member +fields in the same order as they are appear in \member{{\_}fields{\_}}. Keyword +arguments in the constructor are interpreted as attribute assignments, +so they will initialize \member{{\_}fields{\_}} with the same name, or create new +attributes for names not present in \member{{\_}fields{\_}}. + \subsubsection{Arrays and pointers\label{ctypes-arrays-pointers}} Modified: stackless/trunk/Doc/lib/libfuncs.tex ============================================================================== --- stackless/trunk/Doc/lib/libfuncs.tex (original) +++ stackless/trunk/Doc/lib/libfuncs.tex Fri Jul 14 14:39:40 2006 @@ -468,10 +468,10 @@ Construct a list from those elements of \var{list} for which \var{function} returns true. \var{list} may be either a sequence, a container which supports iteration, or an iterator, If \var{list} - is a string or a tuple, the result also has that type; otherwise it - is always a list. If \var{function} is \code{None}, the identity - function is assumed, that is, all elements of \var{list} that are false - (zero or empty) are removed. + is a string or a tuple, the result + also has that type; otherwise it is always a list. If \var{function} is + \code{None}, the identity function is assumed, that is, all elements of + \var{list} that are false are removed. Note that \code{filter(function, \var{list})} is equivalent to \code{[item for item in \var{list} if function(item)]} if function is @@ -781,15 +781,30 @@ \begin{verbatim} class C(object): def __init__(self): self.__x = None - def getx(self): return self.__x - def setx(self, value): self.__x = value - def delx(self): del self.__x + def getx(self): return self._x + def setx(self, value): self._x = value + def delx(self): del self._x x = property(getx, setx, delx, "I'm the 'x' property.") \end{verbatim} If given, \var{doc} will be the docstring of the property attribute. Otherwise, the property will copy \var{fget}'s docstring (if it - exists). + exists). This makes it possible to create read-only properties + easily using \function{property()} as a decorator: + +\begin{verbatim} +class Parrot(object): + def __init__(self): + self._voltage = 100000 + + @property + def voltage(self): + """Get the current voltage.""" + return self._voltage +\end{verbatim} + + turns the \method{voltage()} method into a ``getter'' for a read-only + attribute with the same name. \versionadded{2.2} \versionchanged[Use \var{fget}'s docstring if no \var{doc} given]{2.5} @@ -993,8 +1008,30 @@ \begin{funcdesc}{sorted}{iterable\optional{, cmp\optional{, key\optional{, reverse}}}} Return a new sorted list from the items in \var{iterable}. - The optional arguments \var{cmp}, \var{key}, and \var{reverse} - have the same meaning as those for the \method{list.sort()} method. + + The optional arguments \var{cmp}, \var{key}, and \var{reverse} have + the same meaning as those for the \method{list.sort()} method + (described in section~\ref{typesseq-mutable}). + + \var{cmp} specifies a custom comparison function of two arguments + (iterable elements) which should return a negative, zero or positive + number depending on whether the first argument is considered smaller + than, equal to, or larger than the second argument: + \samp{\var{cmp}=\keyword{lambda} \var{x},\var{y}: + \function{cmp}(x.lower(), y.lower())} + + \var{key} specifies a function of one argument that is used to + extract a comparison key from each list element: + \samp{\var{key}=\function{str.lower}} + + \var{reverse} is a boolean value. If set to \code{True}, then the + list elements are sorted as if each comparison were reversed. + + In general, the \var{key} and \var{reverse} conversion processes are + much faster than specifying an equivalent \var{cmp} function. This is + because \var{cmp} is called multiple times for each list element while + \var{key} and \var{reverse} touch each element only once. + \versionadded{2.4} \end{funcdesc} Modified: stackless/trunk/Doc/lib/libstdtypes.tex ============================================================================== --- stackless/trunk/Doc/lib/libstdtypes.tex (original) +++ stackless/trunk/Doc/lib/libstdtypes.tex Fri Jul 14 14:39:40 2006 @@ -567,6 +567,7 @@ \subsubsection{String Methods \label{string-methods}} +\indexii{string}{methods} These are the string methods which both 8-bit strings and Unicode objects support: @@ -1100,7 +1101,8 @@ \lineiii{\var{s}[\var{i}] = \var{x}} {item \var{i} of \var{s} is replaced by \var{x}}{} \lineiii{\var{s}[\var{i}:\var{j}] = \var{t}} - {slice of \var{s} from \var{i} to \var{j} is replaced by \var{t}}{} + {slice of \var{s} from \var{i} to \var{j} + is replaced by the contents of the iterable \var{t}}{} \lineiii{del \var{s}[\var{i}:\var{j}]} {same as \code{\var{s}[\var{i}:\var{j}] = []}}{} \lineiii{\var{s}[\var{i}:\var{j}:\var{k}] = \var{t}} Modified: stackless/trunk/Doc/lib/libsys.tex ============================================================================== --- stackless/trunk/Doc/lib/libsys.tex (original) +++ stackless/trunk/Doc/lib/libsys.tex Fri Jul 14 14:39:40 2006 @@ -41,7 +41,7 @@ \code{Include/patchlevel.h} if the branch is a tag. Otherwise, it is \code{None}. \versionadded{2.5} -\end{datadesc} +\end{datadesc} \begin{datadesc}{builtin_module_names} A tuple of strings giving the names of all modules that are compiled @@ -55,6 +55,23 @@ interpreter. \end{datadesc} +\begin{funcdesc}{_current_frames}{} + Return a dictionary mapping each thread's identifier to the topmost stack + frame currently active in that thread at the time the function is called. + Note that functions in the \refmodule{traceback} module can build the + call stack given such a frame. + + This is most useful for debugging deadlock: this function does not + require the deadlocked threads' cooperation, and such threads' call stacks + are frozen for as long as they remain deadlocked. The frame returned + for a non-deadlocked thread may bear no relationship to that thread's + current activity by the time calling code examines the frame. + + This function should be used for internal and specialized purposes + only. + \versionadded{2.5} +\end{funcdesc} + \begin{datadesc}{dllhandle} Integer specifying the handle of the Python DLL. Availability: Windows. @@ -142,7 +159,7 @@ function, \function{exc_info()} will return three \code{None} values until another exception is raised in the current thread or the execution stack returns to a frame where another exception is being handled. - + This function is only needed in only a few obscure situations. These include logging and error handling systems that report information on the last or current exception. This function can also be used to try to free @@ -241,7 +258,7 @@ \begin{itemize} \item On Windows 9x, the encoding is ``mbcs''. \item On Mac OS X, the encoding is ``utf-8''. -\item On Unix, the encoding is the user's preference +\item On Unix, the encoding is the user's preference according to the result of nl_langinfo(CODESET), or None if the nl_langinfo(CODESET) failed. \item On Windows NT+, file names are Unicode natively, so no conversion @@ -279,8 +296,8 @@ \end{funcdesc} \begin{funcdesc}{getwindowsversion}{} - Return a tuple containing five components, describing the Windows - version currently running. The elements are \var{major}, \var{minor}, + Return a tuple containing five components, describing the Windows + version currently running. The elements are \var{major}, \var{minor}, \var{build}, \var{platform}, and \var{text}. \var{text} contains a string while all other values are integers. @@ -491,7 +508,7 @@ be registered using \function{settrace()} for each thread being debugged. \note{The \function{settrace()} function is intended only for implementing debuggers, profilers, coverage tools and the like. - Its behavior is part of the implementation platform, rather than + Its behavior is part of the implementation platform, rather than part of the language definition, and thus may not be available in all Python implementations.} \end{funcdesc} Modified: stackless/trunk/Doc/lib/libturtle.tex ============================================================================== --- stackless/trunk/Doc/lib/libturtle.tex (original) +++ stackless/trunk/Doc/lib/libturtle.tex Fri Jul 14 14:39:40 2006 @@ -42,6 +42,19 @@ line. \end{funcdesc} +\begin{funcdesc}{speed}{speed} +Set the speed of the turtle. Valid values for the parameter +\var{speed} are \code{'fastest'} (no delay), \code{'fast'}, +(delay 5ms), \code{'normal'} (delay 10ms), \code{'slow'} +(delay 15ms), and \code{'slowest'} (delay 20ms). +\versionadded{2.5} +\end{funcdesc} + +\begin{funcdesc}{delay}{delay} +Set the speed of the turtle to \var{delay}, which is given +in ms. \versionadded{2.5} +\end{funcdesc} + \begin{funcdesc}{forward}{distance} Go forward \var{distance} steps. \end{funcdesc} @@ -94,6 +107,18 @@ and call \code{fill(0)} when you finish to draw the path. \end{funcdesc} +\begin{funcdesc}{begin\_fill}{} +Switch turtle into filling mode; +Must eventually be followed by a corresponding end_fill() call. +Otherwise it will be ignored. +\versionadded{2.5} +\end{funcdesc} + +\begin{funcdesc}{end\_fill}{} +End filling mode, and fill the shape; equivalent to \code{fill(0)}. +\versionadded{2.5} +\end{funcdesc} + \begin{funcdesc}{circle}{radius\optional{, extent}} Draw a circle with radius \var{radius} whose center-point is \var{radius} units left of the turtle. @@ -113,6 +138,49 @@ specified either as two separate arguments or as a 2-tuple. \end{funcdesc} +\begin{funcdesc}{towards}{x, y} +Return the angle of the line from the turtle's position +to the point \var{x}, \var{y}. The co-ordinates may be +specified either as two separate arguments, as a 2-tuple, +or as another pen object. +\versionadded{2.5} +\end{funcdesc} + +\begin{funcdesc}{heading}{} +Return the current orientation of the turtle. +\versionadded{2.3} +\end{funcdesc} + +\begin{funcdesc}{setheading}{angle} +Set the orientation of the turtle to \var{angle}. +\versionadded{2.3} +\end{funcdesc} + +\begin{funcdesc}{position}{} +Return the current location of the turtle as an \code{(x,y)} pair. +\versionadded{2.3} +\end{funcdesc} + +\begin{funcdesc}{setx}{x} +Set the x coordinate of the turtle to \var{x}. +\versionadded{2.3} +\end{funcdesc} + +\begin{funcdesc}{sety}{y} +Set the y coordinate of the turtle to \var{y}. +\versionadded{2.3} +\end{funcdesc} + +\begin{funcdesc}{window\_width}{} +Return the width of the canvas window. +\versionadded{2.3} +\end{funcdesc} + +\begin{funcdesc}{window\_height}{} +Return the height of the canvas window. +\versionadded{2.3} +\end{funcdesc} + This module also does \code{from math import *}, so see the documentation for the \refmodule{math} module for additional constants and functions useful for turtle graphics. @@ -134,16 +202,21 @@ pen. The constructor automatically creates a canvas do be drawn on. \end{classdesc} +\begin{classdesc}{Turtle}{} +Define a pen. This is essentially a synonym for \code{Pen()}; +\class{Turtle} is an empty subclass of \class{Pen}. +\end{classdesc} + \begin{classdesc}{RawPen}{canvas} Define a pen which draws on a canvas \var{canvas}. This is useful if you want to use the module to create graphics in a ``real'' program. \end{classdesc} -\subsection{Pen and RawPen Objects \label{pen-rawpen-objects}} +\subsection{Turtle, Pen and RawPen Objects \label{pen-rawpen-objects}} -\class{Pen} and \class{RawPen} objects have all the global functions -described above, except for \function{demo()} as methods, which -manipulate the given pen. +\class{Turtle}, \class{Pen} and \class{RawPen} objects have all the +global functions described above, except for \function{demo()} as +methods, which manipulate the given pen. The only method which is more powerful as a method is \function{degrees()}. Modified: stackless/trunk/Doc/lib/libwarnings.tex ============================================================================== --- stackless/trunk/Doc/lib/libwarnings.tex (original) +++ stackless/trunk/Doc/lib/libwarnings.tex Fri Jul 14 14:39:40 2006 @@ -71,6 +71,11 @@ \lineii{FutureWarning}{Base category for warnings about constructs that will change semantically in the future.} +\lineii{PendingDeprecationWarning}{Base category for warnings about +features that will be deprecated in the future (ignored by default).} + +\lineii{ImportWarning}{Base category for warnings triggered during the +process of importing a module (ignored by default).} \end{tableii} While these are technically built-in exceptions, they are documented @@ -143,6 +148,17 @@ it is first imported (invalid options are ignored, after printing a message to \code{sys.stderr}). +The warnings that are ignored by default may be enabled by passing + \programopt{-Wd} to the interpreter. This enables default handling +for all warnings, including those that are normally ignored by +default. This is particular useful for enabling ImportWarning when +debugging problems importing a developed package. ImportWarning can +also be enabled explicitly in Python code using: + +\begin{verbatim} + warnings.simplefilter('default', ImportWarning) +\end{verbatim} + \subsection{Available Functions \label{warning-functions}} @@ -209,14 +225,26 @@ inserted at the front by default; if \var{append} is true, it is inserted at the end. This checks the types of the arguments, compiles the message and -module regular expressions, and inserts them as a tuple in front -of the warnings filter. Entries inserted later override entries -inserted earlier, if both match a particular warning. Omitted -arguments default to a value that matches everything. +module regular expressions, and inserts them as a tuple in the +list of warnings filters. Entries closer to the front of the list +override entries later in the list, if both match a particular +warning. Omitted arguments default to a value that matches +everything. +\end{funcdesc} + +\begin{funcdesc}{simplefilter}{action\optional{, + category\optional{, + lineno\optional{, append}}}} +Insert a simple entry into the list of warnings filters. The meaning +of the function parameters is as for \function{filterwarnings()}, but +regular expressions are not needed as the filter inserted always +matches any message in any module as long as the category and line +number match. \end{funcdesc} \begin{funcdesc}{resetwarnings}{} Reset the warnings filter. This discards the effect of all previous calls to \function{filterwarnings()}, including that of the -\programopt{-W} command line options. +\programopt{-W} command line options and calls to +\function{simplefilter()}. \end{funcdesc} Modified: stackless/trunk/Doc/tut/tut.tex ============================================================================== --- stackless/trunk/Doc/tut/tut.tex (original) +++ stackless/trunk/Doc/tut/tut.tex Fri Jul 14 14:39:40 2006 @@ -2919,14 +2919,13 @@ The submodules often need to refer to each other. For example, the \module{surround} module might use the \module{echo} module. In fact, -such references -are so common that the \keyword{import} statement first looks in the -containing package before looking in the standard module search path. -Thus, the surround module can simply use \code{import echo} or -\code{from echo import echofilter}. If the imported module is not -found in the current package (the package of which the current module -is a submodule), the \keyword{import} statement looks for a top-level -module with the given name. +such references are so common that the \keyword{import} statement +first looks in the containing package before looking in the standard +module search path. Thus, the \module{surround} module can simply use +\code{import echo} or \code{from echo import echofilter}. If the +imported module is not found in the current package (the package of +which the current module is a submodule), the \keyword{import} +statement looks for a top-level module with the given name. When packages are structured into subpackages (as with the \module{Sound} package in the example), there's no shortcut to refer @@ -2936,6 +2935,24 @@ in the \module{Sound.Effects} package, it can use \code{from Sound.Effects import echo}. +Starting with Python 2.5, in addition to the implicit relative imports +described above, you can write explicit relative imports with the +\code{from module import name} form of import statement. These explicit +relative imports use leading dots to indicate the current and parent +packages involved in the relative import. From the \module{surround} +module for example, you might use: + +\begin{verbatim} +from . import echo +from .. import Formats +from ..Filters import equalizer +\end{verbatim} + +Note that both explicit and implicit relative imports are based on the +name of the current module. Since the name of the main module is always +\code{"__main__"}, modules intended for use as the main module of a +Python application should always use absolute imports. + \subsection{Packages in Multiple Directories} Packages support one more special attribute, \member{__path__}. This Modified: stackless/trunk/Doc/whatsnew/whatsnew20.tex ============================================================================== --- stackless/trunk/Doc/whatsnew/whatsnew20.tex (original) +++ stackless/trunk/Doc/whatsnew/whatsnew20.tex Fri Jul 14 14:39:40 2006 @@ -777,7 +777,7 @@ Some work has been done to make integers and long integers a bit more interchangeable. In 1.5.2, large-file support was added for Solaris, -to allow reading files larger than 2Gb; this made the \method{tell()} +to allow reading files larger than 2~GiB; this made the \method{tell()} method of file objects return a long integer instead of a regular integer. Some code would subtract two file offsets and attempt to use the result to multiply a sequence or slice a string, but this raised a Modified: stackless/trunk/Doc/whatsnew/whatsnew23.tex ============================================================================== --- stackless/trunk/Doc/whatsnew/whatsnew23.tex (original) +++ stackless/trunk/Doc/whatsnew/whatsnew23.tex Fri Jul 14 14:39:40 2006 @@ -1479,7 +1479,7 @@ ('amk', 500) \end{verbatim} -\item The \module{gzip} module can now handle files exceeding 2~Gb. +\item The \module{gzip} module can now handle files exceeding 2~GiB. \item The new \module{heapq} module contains an implementation of a heap queue algorithm. A heap is an array-like data structure that Modified: stackless/trunk/Doc/whatsnew/whatsnew25.tex ============================================================================== --- stackless/trunk/Doc/whatsnew/whatsnew25.tex (original) +++ stackless/trunk/Doc/whatsnew/whatsnew25.tex Fri Jul 14 14:39:40 2006 @@ -2,12 +2,11 @@ \usepackage{distutils} % $Id$ -% wsgiref section % Fix XXX comments % Count up the patches and bugs \title{What's New in Python 2.5} -\release{0.2} +\release{0.3} \author{A.M. Kuchling} \authoraddress{\email{amk at amk.ca}} @@ -15,31 +14,51 @@ \maketitle \tableofcontents -This article explains the new features in Python 2.5. No release date -for Python 2.5 has been set; it will probably be released in the -autumn of 2006. \pep{356} describes the planned release schedule. - -Comments, suggestions, and error reports are welcome; please e-mail them -to the author or open a bug in the Python bug tracker. - -% XXX Compare with previous release in 2 - 3 sentences here. - -This article doesn't attempt to provide a complete specification of -the new features, but instead provides a convenient overview. For -full details, you should refer to the documentation for Python 2.5. +This article explains the new features in Python 2.5. The final +release of Python 2.5 is scheduled for August 2006; +\pep{356} describes the planned release schedule. + +The changes in Python 2.5 are an interesting mix of language and +library improvements. The library enhancements will be more important +to Python's user community, I think, because several widely-useful +packages were added. New modules include ElementTree for XML +processing (section~\ref{module-etree}), the SQLite database module +(section~\ref{module-sqlite}), and the \module{ctypes} module for +calling C functions (section~\ref{module-ctypes}). + +The language changes are of middling significance. Some pleasant new +features were added, but most of them aren't features that you'll use +every day. Conditional expressions were finally added to the language +using a novel syntax; see section~\ref{pep-308}. The new +'\keyword{with}' statement will make writing cleanup code easier +(section~\ref{pep-343}). Values can now be passed into generators +(section~\ref{pep-342}). Imports are now visible as either absolute +or relative (section~\ref{pep-328}). Some corner cases of exception +handling are handled better (section~\ref{pep-341}). All these +improvements are worthwhile, but they're improvements to one specific +language feature or another; none of them are broad modifications to +Python's semantics. + +This article doesn't try to be a complete specification of the new +features; instead changes are briefly introduced using helpful +examples. For full details, you should always refer to the +documentation for Python 2.5. % XXX add hyperlink when the documentation becomes available online. If you want to understand the complete implementation and design rationale, refer to the PEP for a particular new feature. +Comments, suggestions, and error reports for this document are +welcome; please e-mail them to the author or open a bug in the Python +bug tracker. %====================================================================== \section{PEP 308: Conditional Expressions\label{pep-308}} For a long time, people have been requesting a way to write -conditional expressions, expressions that return value A or value B -depending on whether a Boolean value is true or false. A conditional -expression lets you write a single assignment statement that has the -same effect as the following: +conditional expressions, which are expressions that return value A or +value B depending on whether a Boolean value is true or false. A +conditional expression lets you write a single assignment statement +that has the same effect as the following: \begin{verbatim} if condition: @@ -798,7 +817,7 @@ decorator that are useful for writing objects for use with the '\keyword{with}' statement. -The decorator is called \function{contextfactory}, and lets you write +The decorator is called \function{contextmanager}, and lets you write a single generator function instead of defining a new class. The generator should yield exactly one value. The code up to the \keyword{yield} will be executed as the \method{__enter__()} method, and the value @@ -812,9 +831,9 @@ using this decorator as: \begin{verbatim} -from contextlib import contextfactory +from contextlib import contextmanager - at contextfactory + at contextmanager def db_transaction (connection): cursor = connection.cursor() try: @@ -960,7 +979,7 @@ already more bytes than a 32-bit address space can contain. It's possible to address that much memory on a 64-bit platform, -however. The pointers for a list that size would only require 16GiB +however. The pointers for a list that size would only require 16~GiB of space, so it's not unreasonable that Python programmers might construct lists that large. Therefore, the Python interpreter had to be changed to use some type other than \ctype{int}, and this will be a @@ -1151,9 +1170,12 @@ to include an \file{__init__.py} module in a package directory. Debugging this mistake can be confusing, and usually requires running Python with the \programopt{-v} switch to log all the paths searched. -In Python 2.5, a new \exception{ImportWarning} warning is raised when +In Python 2.5, a new \exception{ImportWarning} warning is triggered when an import would have picked up a directory as a package but no -\file{__init__.py} was found. (Implemented by Thomas Wouters.) +\file{__init__.py} was found. This warning is silently ignored by default; +provide the \programopt{-Wd} option when running the Python executable +to display the warning message. +(Implemented by Thomas Wouters.) \item The list of base classes in a class definition can now be empty. As an example, this is now legal: @@ -1384,6 +1406,16 @@ code snippets that are usage examples intended for the reader and aren't actually test cases. +An \var{encoding} parameter was added to the \function{testfile()} +function and the \class{DocFileSuite} class to specify the file's +encoding. This makes it easier to use non-ASCII characters in +tests contained within a docstring. (Contributed by Bjorn Tillenius.) +% Patch 1080727 + +\item The \module{email} package has been updated to version 4.0. +% XXX need to provide some more detail here +(Contributed by Barry Warsaw.) + \item The \module{fileinput} module was made more flexible. Unicode filenames are now supported, and a \var{mode} parameter that defaults to \code{"r"} was added to the @@ -1402,6 +1434,7 @@ collection sweep will be made. The existing \function{gc.collect()} function now takes an optional \var{generation} argument of 0, 1, or 2 to specify which generation to collect. +(Contributed by Barry Warsaw.) \item The \function{nsmallest()} and \function{nlargest()} functions in the \module{heapq} module @@ -1540,6 +1573,9 @@ performing many different operations and reducing the result to a single number as \file{pystone.py} does. +\item The \module{pyexpat} module now uses version 2.0 of the Expat parser. +(Contributed by Trent Mick.) + \item The old \module{regex} and \module{regsub} modules, which have been deprecated ever since Python 2.0, have finally been deleted. Other deleted modules: \module{statcache}, \module{tzparse}, @@ -1682,6 +1718,14 @@ (Contributed by Ka-Ping Yee.) +\item The \module{weakref} module's \class{WeakKeyDictionary} and +\class{WeakValueDictionary} types gained new methods for iterating +over the weak references contained in the dictionary. +\method{iterkeyrefs()} and \method{keyrefs()} methods were +added to \class{WeakKeyDictionary}, and +\method{itervaluerefs()} and \method{valuerefs()} were added to +\class{WeakValueDictionary}. (Contributed by Fred L.~Drake, Jr.) + \item The \module{webbrowser} module received a number of enhancements. It's now usable as a script with \code{python -m webbrowser}, taking a @@ -1693,10 +1737,16 @@ additional feature, an \var{autoraise} parameter that signals whether to raise the open window when possible. A number of additional browsers were added to the supported list such as Firefox, Opera, -Konqueror, and elinks. (Contributed by Oleg Broytmann and George +Konqueror, and elinks. (Contributed by Oleg Broytmann and Georg Brandl.) % Patch #754022 +\item The standard library's XML-related package +has been renamed to \module{xmlcore}. The \module{xml} module will +now import either the \module{xmlcore} or PyXML version of subpackages +such as \module{xml.dom}. The renaming means it will always be +possible to import the standard library's XML support whether or not +the PyXML package is installed. \item The \module{xmlrpclib} module now supports returning \class{datetime} objects for the XML-RPC date type. Supply @@ -1705,6 +1755,12 @@ (Contributed by Skip Montanaro.) % Patch 1120353 +\item The \module{zipfile} module now supports the ZIP64 version of the +format, meaning that a .zip archive can now be larger than 4~GiB and +can contain individual files larger than 4~GiB. (Contributed by +Ronald Oussoren.) +% Patch 1446489 + \item The \module{zlib} module's \class{Compress} and \class{Decompress} objects now support a \method{copy()} method that makes a copy of the object's internal state and returns a new @@ -1795,6 +1851,9 @@ \seeurl{http://starship.python.net/crew/theller/ctypes/} {The ctypes web page, with a tutorial, reference, and FAQ.} +\seeurl{../lib/module-ctypes.html}{The documentation +for the \module{ctypes} module.} + \end{seealso} @@ -1906,7 +1965,6 @@ \seeurl{http://effbot.org/zone/element-index.htm} {Official documentation for ElementTree.} - \end{seealso} @@ -1957,6 +2015,13 @@ return the digest value as a binary string or a string of hex digits, and \method{copy()} returns a new hashing object with the same digest state. +\begin{seealso} + +\seeurl{../lib/module-hashlib.html}{The documentation +for the \module{hashlib} module.} + +\end{seealso} + %====================================================================== \subsection{The sqlite3 package\label{module-sqlite}} @@ -2067,6 +2132,9 @@ {The SQLite web page; the documentation describes the syntax and the available data types for the supported SQL dialect.} +\seeurl{../lib/module-sqlite3.html}{The documentation +for the \module{sqlite3} module.} + \seepep{249}{Database API Specification 2.0}{PEP written by Marc-Andr\'e Lemburg.} @@ -2074,10 +2142,9 @@ %====================================================================== -%\subsection{The wsgiref package\label{module-wsgiref}} +\subsection{The wsgiref package\label{module-wsgiref}} % XXX should this be in a PEP 333 section instead? -\begin{comment} The Web Server Gateway Interface (WSGI) v1.0 defines a standard interface between web servers and Python web applications and is @@ -2086,10 +2153,7 @@ The package includes a basic HTTP server that will run a WSGI application; this server is useful for debugging but isn't intended for -production use. - -% XXX structure of WSGI applications? -% XXX provide an example using Django or some other framework? +production use. Setting up a server takes only a few lines of code: \begin{verbatim} from wsgiref import simple_server @@ -2098,21 +2162,23 @@ host = '' port = 8000 -httpd = make_server(host, port, wsgi_app) +httpd = simple_server.make_server(host, port, wsgi_app) httpd.serve_forever() \end{verbatim} +% XXX discuss structure of WSGI applications? +% XXX provide an example using Django or some other framework? \begin{seealso} +\seeurl{http://www.wsgi.org}{A central web site for WSGI-related resources.} + \seepep{333}{Python Web Server Gateway Interface v1.0}{PEP written by Phillip J. Eby.} \end{seealso} -\end{comment} - % ====================================================================== \section{Build and C API Changes\label{build-api}} @@ -2146,12 +2212,13 @@ for_loop = ast.body[1] \end{verbatim} -No documentation has been written for the AST code yet. To start -learning about it, read the definition of the various AST nodes in -\file{Parser/Python.asdl}. A Python script reads this file and -generates a set of C structure definitions in -\file{Include/Python-ast.h}. The \cfunction{PyParser_ASTFromString()} -and \cfunction{PyParser_ASTFromFile()}, defined in +No official documentation has been written for the AST code yet, but +\pep{339} discusses the design. To start learning about the code, read the +definition of the various AST nodes in \file{Parser/Python.asdl}. A +Python script reads this file and generates a set of C structure +definitions in \file{Include/Python-ast.h}. The +\cfunction{PyParser_ASTFromString()} and +\cfunction{PyParser_ASTFromFile()}, defined in \file{Include/pythonrun.h}, take Python source as input and return the root of an AST representing the contents. This AST can then be turned into a code object by \cfunction{PyAST_Compile()}. For more @@ -2202,7 +2269,12 @@ \item The \cfunction{PyRange_New()} function was removed. It was never documented, never used in the core code, and had dangerously lax -error checking. +error checking. In the unlikely case that your extensions were using +it, you can replace it by something like the following: +\begin{verbatim} +range = PyObject_CallFunction((PyObject*) &PyRange_Type, "lll", + start, stop, step); +\end{verbatim} \end{itemize} @@ -2308,6 +2380,10 @@ \member{rpc_paths} to \code{None} or an empty tuple disables this path checking. +\item Library: the \module{xml} package has been renamed to \module{xmlcore}. +The PyXML package will therefore be \module{xml}, and the Python +distribution's code will always be accessible as \module{xmlcore}. + \item C API: Many functions now use \ctype{Py_ssize_t} instead of \ctype{int} to allow processing more data on 64-bit machines. Extension code may need to make the same change to avoid @@ -2330,7 +2406,8 @@ The author would like to thank the following people for offering suggestions, corrections and assistance with various drafts of this -article: Phillip J. Eby, Kent Johnson, Martin von~L\"owis, Fredrik Lundh, -Gustavo Niemeyer, James Pryor, Mike Rovner, Scott Weikart, Thomas Wouters. +article: Nick Coghlan, Phillip J. Eby, Ralf W. Grosse-Kunstleve, Kent +Johnson, Martin von~L\"owis, Fredrik Lundh, Gustavo Niemeyer, James +Pryor, Mike Rovner, Scott Weikart, Barry Warsaw, Thomas Wouters. \end{document} Modified: stackless/trunk/Include/patchlevel.h ============================================================================== --- stackless/trunk/Include/patchlevel.h (original) +++ stackless/trunk/Include/patchlevel.h Fri Jul 14 14:39:40 2006 @@ -23,10 +23,10 @@ #define PY_MINOR_VERSION 5 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA -#define PY_RELEASE_SERIAL 1 +#define PY_RELEASE_SERIAL 2 /* Version as a string */ -#define PY_VERSION "2.5b1" +#define PY_VERSION "2.5b2" /* Subversion Revision number of this file (not of the repository) */ #define PY_PATCHLEVEL_REVISION "$Revision$" Modified: stackless/trunk/Include/pystate.h ============================================================================== --- stackless/trunk/Include/pystate.h (original) +++ stackless/trunk/Include/pystate.h Fri Jul 14 14:39:40 2006 @@ -178,6 +178,11 @@ */ PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void); +/* The implementation of sys._current_frames() Returns a dict mapping + thread id to that thread's current frame. +*/ +PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void); + /* Routines for advanced debuggers, requested by David Beazley. Don't use unless you know what you are doing! */ PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void); Modified: stackless/trunk/Lib/compiler/transformer.py ============================================================================== --- stackless/trunk/Lib/compiler/transformer.py (original) +++ stackless/trunk/Lib/compiler/transformer.py Fri Jul 14 14:39:40 2006 @@ -536,12 +536,7 @@ lineno=nodelist[0][2]) def try_stmt(self, nodelist): - # 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] - # | 'try' ':' suite 'finally' ':' suite - if nodelist[3][0] != symbol.except_clause: - return self.com_try_finally(nodelist) - - return self.com_try_except(nodelist) + return self.com_try_except_finally(nodelist) def with_stmt(self, nodelist): return self.com_with(nodelist) @@ -732,17 +727,17 @@ def atom_lpar(self, nodelist): if nodelist[1][0] == token.RPAR: - return Tuple(()) + return Tuple((), lineno=nodelist[0][2]) return self.com_node(nodelist[1]) def atom_lsqb(self, nodelist): if nodelist[1][0] == token.RSQB: - return List(()) + return List((), lineno=nodelist[0][2]) return self.com_list_constructor(nodelist[1]) def atom_lbrace(self, nodelist): if nodelist[1][0] == token.RBRACE: - return Dict(()) + return Dict((), lineno=nodelist[0][2]) return self.com_dictmaker(nodelist[1]) def atom_backquote(self, nodelist): @@ -917,18 +912,21 @@ bases.append(self.com_node(node[i])) return bases - def com_try_finally(self, nodelist): - # try_fin_stmt: "try" ":" suite "finally" ":" suite - return TryFinally(self.com_node(nodelist[2]), - self.com_node(nodelist[5]), - lineno=nodelist[0][2]) + def com_try_except_finally(self, nodelist): + # ('try' ':' suite + # ((except_clause ':' suite)+ ['else' ':' suite] ['finally' ':' suite] + # | 'finally' ':' suite)) + + if nodelist[3][0] == token.NAME: + # first clause is a finally clause: only try-finally + return TryFinally(self.com_node(nodelist[2]), + self.com_node(nodelist[5]), + lineno=nodelist[0][2]) - def com_try_except(self, nodelist): - # try_except: 'try' ':' suite (except_clause ':' suite)* ['else' suite] #tryexcept: [TryNode, [except_clauses], elseNode)] - stmt = self.com_node(nodelist[2]) clauses = [] elseNode = None + finallyNode = None for i in range(3, len(nodelist), 3): node = nodelist[i] if node[0] == symbol.except_clause: @@ -944,9 +942,16 @@ clauses.append((expr1, expr2, self.com_node(nodelist[i+2]))) if node[0] == token.NAME: - elseNode = self.com_node(nodelist[i+2]) - return TryExcept(self.com_node(nodelist[2]), clauses, elseNode, - lineno=nodelist[0][2]) + if node[1] == 'else': + elseNode = self.com_node(nodelist[i+2]) + elif node[1] == 'finally': + finallyNode = self.com_node(nodelist[i+2]) + try_except = TryExcept(self.com_node(nodelist[2]), clauses, elseNode, + lineno=nodelist[0][2]) + if finallyNode: + return TryFinally(try_except, finallyNode, lineno=nodelist[0][2]) + else: + return try_except def com_with(self, nodelist): # with_stmt: 'with' expr [with_var] ':' suite @@ -1136,7 +1141,7 @@ values = [] for i in range(1, len(nodelist), 2): values.append(self.com_node(nodelist[i])) - return List(values) + return List(values, lineno=values[0].lineno) if hasattr(symbol, 'gen_for'): def com_generator_expression(self, expr, node): @@ -1183,7 +1188,7 @@ for i in range(1, len(nodelist), 4): items.append((self.com_node(nodelist[i]), self.com_node(nodelist[i+2]))) - return Dict(items) + return Dict(items, lineno=items[0][0].lineno) def com_apply_trailer(self, primaryNode, nodelist): t = nodelist[1][0] Modified: stackless/trunk/Lib/ctypes/test/test_objects.py ============================================================================== --- stackless/trunk/Lib/ctypes/test/test_objects.py (original) +++ stackless/trunk/Lib/ctypes/test/test_objects.py Fri Jul 14 14:39:40 2006 @@ -54,13 +54,17 @@ ''' -import unittest, doctest +import unittest, doctest, sys import ctypes.test.test_objects class TestCase(unittest.TestCase): - def test(self): - doctest.testmod(ctypes.test.test_objects) + if sys.hexversion > 0x02040000: + # Python 2.3 has no ELLIPSIS flag, so we don't test with this + # version: + def test(self): + doctest.testmod(ctypes.test.test_objects) if __name__ == '__main__': - doctest.testmod(ctypes.test.test_objects) + if sys.hexversion > 0x02040000: + doctest.testmod(ctypes.test.test_objects) Modified: stackless/trunk/Lib/ctypes/test/test_parameters.py ============================================================================== --- stackless/trunk/Lib/ctypes/test/test_parameters.py (original) +++ stackless/trunk/Lib/ctypes/test/test_parameters.py Fri Jul 14 14:39:40 2006 @@ -147,6 +147,41 @@ ## def test_performance(self): ## check_perf() + def test_noctypes_argtype(self): + import _ctypes_test + from ctypes import CDLL, c_void_p, ArgumentError + + func = CDLL(_ctypes_test.__file__)._testfunc_p_p + func.restype = c_void_p + # TypeError: has no from_param method + self.assertRaises(TypeError, setattr, func, "argtypes", (object,)) + + class Adapter(object): + def from_param(cls, obj): + return None + + func.argtypes = (Adapter(),) + self.failUnlessEqual(func(None), None) + self.failUnlessEqual(func(object()), None) + + class Adapter(object): + def from_param(cls, obj): + return obj + + func.argtypes = (Adapter(),) + # don't know how to convert parameter 1 + self.assertRaises(ArgumentError, func, object()) + self.failUnlessEqual(func(c_void_p(42)), 42) + + class Adapter(object): + def from_param(cls, obj): + raise ValueError(obj) + + func.argtypes = (Adapter(),) + # ArgumentError: argument 1: ValueError: 99 + self.assertRaises(ArgumentError, func, 99) + + ################################################################ if __name__ == '__main__': Modified: stackless/trunk/Lib/ctypes/test/test_pointers.py ============================================================================== --- stackless/trunk/Lib/ctypes/test/test_pointers.py (original) +++ stackless/trunk/Lib/ctypes/test/test_pointers.py Fri Jul 14 14:39:40 2006 @@ -157,6 +157,23 @@ q = pointer(y) pp[0] = q # <== self.failUnlessEqual(p[0], 6) + def test_c_void_p(self): + # http://sourceforge.net/tracker/?func=detail&aid=1518190&group_id=5470&atid=105470 + if sizeof(c_void_p) == 4: + self.failUnlessEqual(c_void_p(0xFFFFFFFFL).value, + c_void_p(-1).value) + self.failUnlessEqual(c_void_p(0xFFFFFFFFFFFFFFFFL).value, + c_void_p(-1).value) + elif sizeof(c_void_p) == 8: + self.failUnlessEqual(c_void_p(0xFFFFFFFFL).value, + 0xFFFFFFFFL) + self.failUnlessEqual(c_void_p(0xFFFFFFFFFFFFFFFFL).value, + c_void_p(-1).value) + self.failUnlessEqual(c_void_p(0xFFFFFFFFFFFFFFFFFFFFFFFFL).value, + c_void_p(-1).value) + + self.assertRaises(TypeError, c_void_p, 3.14) # make sure floats are NOT accepted + self.assertRaises(TypeError, c_void_p, object()) # nor other objects if __name__ == '__main__': unittest.main() Modified: stackless/trunk/Lib/ctypes/test/test_structures.py ============================================================================== --- stackless/trunk/Lib/ctypes/test/test_structures.py (original) +++ stackless/trunk/Lib/ctypes/test/test_structures.py Fri Jul 14 14:39:40 2006 @@ -371,5 +371,15 @@ items = [s.array[i] for i in range(3)] self.failUnlessEqual(items, [1, 2, 3]) + def test_none_to_pointer_fields(self): + class S(Structure): + _fields_ = [("x", c_int), + ("p", POINTER(c_int))] + + s = S() + s.x = 12345678 + s.p = None + self.failUnlessEqual(s.x, 12345678) + if __name__ == '__main__': unittest.main() Modified: stackless/trunk/Lib/ctypes/test/test_win32.py ============================================================================== --- stackless/trunk/Lib/ctypes/test/test_win32.py (original) +++ stackless/trunk/Lib/ctypes/test/test_win32.py Fri Jul 14 14:39:40 2006 @@ -1,6 +1,7 @@ # Windows specific tests from ctypes import * +from ctypes.test import is_resource_enabled import unittest, sys import _ctypes_test @@ -30,15 +31,10 @@ # or wrong calling convention self.assertRaises(ValueError, IsWindow, None) - def test_SEH(self): - # Call functions with invalid arguments, and make sure that access violations - # are trapped and raise an exception. - # - # Normally, in a debug build of the _ctypes extension - # module, exceptions are not trapped, so we can only run - # this test in a release build. - import sys - if not hasattr(sys, "getobjects"): + if is_resource_enabled("SEH"): + def test_SEH(self): + # Call functions with invalid arguments, and make sure that access violations + # are trapped and raise an exception. self.assertRaises(WindowsError, windll.kernel32.GetModuleHandleA, 32) class Structures(unittest.TestCase): Modified: stackless/trunk/Lib/distutils/command/bdist_rpm.py ============================================================================== --- stackless/trunk/Lib/distutils/command/bdist_rpm.py (original) +++ stackless/trunk/Lib/distutils/command/bdist_rpm.py Fri Jul 14 14:39:40 2006 @@ -467,7 +467,8 @@ # rpm scripts # figure out default build script - def_build = "%s setup.py build" % self.python + def_setup_call = "%s %s" % (self.python,os.path.basename(sys.argv[0])) + def_build = "%s build" % def_setup_call if self.use_rpm_opt_flags: def_build = 'env CFLAGS="$RPM_OPT_FLAGS" ' + def_build @@ -481,9 +482,9 @@ ('prep', 'prep_script', "%setup"), ('build', 'build_script', def_build), ('install', 'install_script', - ("%s setup.py install " + ("%s install " "--root=$RPM_BUILD_ROOT " - "--record=INSTALLED_FILES") % self.python), + "--record=INSTALLED_FILES") % def_setup_call), ('clean', 'clean_script', "rm -rf $RPM_BUILD_ROOT"), ('verifyscript', 'verify_script', None), ('pre', 'pre_install', None), Modified: stackless/trunk/Lib/distutils/command/upload.py ============================================================================== --- stackless/trunk/Lib/distutils/command/upload.py (original) +++ stackless/trunk/Lib/distutils/command/upload.py Fri Jul 14 14:39:40 2006 @@ -185,7 +185,7 @@ http.endheaders() http.send(body) except socket.error, e: - self.announce(e.msg, log.ERROR) + self.announce(str(e), log.ERROR) return r = http.getresponse() Modified: stackless/trunk/Lib/distutils/msvccompiler.py ============================================================================== --- stackless/trunk/Lib/distutils/msvccompiler.py (original) +++ stackless/trunk/Lib/distutils/msvccompiler.py Fri Jul 14 14:39:40 2006 @@ -131,7 +131,7 @@ self.set_macro("FrameworkSDKDir", net, "sdkinstallroot") except KeyError, exc: # raise DistutilsPlatformError, \ - ("The .NET Framework SDK needs to be installed before " + ("Visual Studio 2003 needs to be installed before " "building extensions for Python.") p = r"Software\Microsoft\NET Framework Setup\Product" @@ -237,7 +237,7 @@ def initialize(self): self.__paths = [] - if os.environ.has_key("MSSdk") and self.find_exe("cl.exe"): + if os.environ.has_key("DISTUTILS_USE_SDK") and os.environ.has_key("MSSdk") and self.find_exe("cl.exe"): # Assume that the SDK set up everything alright; don't try to be # smarter self.cc = "cl.exe" Modified: stackless/trunk/Lib/distutils/sysconfig.py ============================================================================== --- stackless/trunk/Lib/distutils/sysconfig.py (original) +++ stackless/trunk/Lib/distutils/sysconfig.py Fri Jul 14 14:39:40 2006 @@ -512,7 +512,7 @@ for key in ('LDFLAGS', 'BASECFLAGS'): flags = _config_vars[key] flags = re.sub('-arch\s+\w+\s', ' ', flags) - flags = re.sub('-isysroot [^ \t]* ', ' ', flags) + flags = re.sub('-isysroot [^ \t]*', ' ', flags) _config_vars[key] = flags if args: Modified: stackless/trunk/Lib/distutils/unixccompiler.py ============================================================================== --- stackless/trunk/Lib/distutils/unixccompiler.py (original) +++ stackless/trunk/Lib/distutils/unixccompiler.py Fri Jul 14 14:39:40 2006 @@ -78,7 +78,7 @@ try: index = compiler_so.index('-isysroot') # Strip this argument and the next one: - del compiler_so[index:index+1] + del compiler_so[index:index+2] except ValueError: pass Modified: stackless/trunk/Lib/idlelib/Debugger.py ============================================================================== --- stackless/trunk/Lib/idlelib/Debugger.py (original) +++ stackless/trunk/Lib/idlelib/Debugger.py Fri Jul 14 14:39:40 2006 @@ -4,6 +4,7 @@ from Tkinter import * from WindowList import ListedToplevel from ScrolledList import ScrolledList +import macosxSupport class Idb(bdb.Bdb): @@ -322,7 +323,13 @@ class StackViewer(ScrolledList): def __init__(self, master, flist, gui): - ScrolledList.__init__(self, master, width=80) + if macosxSupport.runningAsOSXApp(): + # At least on with the stock AquaTk version on OSX 10.4 you'll + # get an shaking GUI that eventually kills IDLE if the width + # argument is specified. + ScrolledList.__init__(self, master) + else: + ScrolledList.__init__(self, master, width=80) self.flist = flist self.gui = gui self.stack = [] Modified: stackless/trunk/Lib/idlelib/NEWS.txt ============================================================================== --- stackless/trunk/Lib/idlelib/NEWS.txt (original) +++ stackless/trunk/Lib/idlelib/NEWS.txt Fri Jul 14 14:39:40 2006 @@ -1,3 +1,8 @@ +What's New in IDLE 1.2b2? +========================= + +*Release date: 11-JUL-2006* + What's New in IDLE 1.2b1? ========================= Modified: stackless/trunk/Lib/idlelib/idlever.py ============================================================================== --- stackless/trunk/Lib/idlelib/idlever.py (original) +++ stackless/trunk/Lib/idlelib/idlever.py Fri Jul 14 14:39:40 2006 @@ -1 +1 @@ -IDLE_VERSION = "1.2b1" +IDLE_VERSION = "1.2b2" Modified: stackless/trunk/Lib/inspect.py ============================================================================== --- stackless/trunk/Lib/inspect.py (original) +++ stackless/trunk/Lib/inspect.py Fri Jul 14 14:39:40 2006 @@ -355,40 +355,37 @@ return None if os.path.exists(filename): return filename - # Ugly but necessary - '' and '' mean that getmodule() - # would infinitely recurse, because they're not real files nor loadable - # Note that this means that writing a PEP 302 loader that uses '<' - # at the start of a filename is now not a good idea. :( - if filename[:1]!='<' and hasattr(getmodule(object), '__loader__'): + # only return a non-existent filename if the module has a PEP 302 loader + if hasattr(getmodule(object, filename), '__loader__'): return filename -def getabsfile(object): +def getabsfile(object, _filename=None): """Return an absolute path to the source or compiled file for an object. The idea is for each object to have a unique origin, so this routine normalizes the result as much as possible.""" return os.path.normcase( - os.path.abspath(getsourcefile(object) or getfile(object))) + os.path.abspath(_filename or getsourcefile(object) or getfile(object))) modulesbyfile = {} -def getmodule(object): +def getmodule(object, _filename=None): """Return the module an object was defined in, or None if not found.""" if ismodule(object): return object if hasattr(object, '__module__'): return sys.modules.get(object.__module__) try: - file = getabsfile(object) + file = getabsfile(object, _filename) except TypeError: return None if file in modulesbyfile: return sys.modules.get(modulesbyfile[file]) for module in sys.modules.values(): if ismodule(module) and hasattr(module, '__file__'): - modulesbyfile[ - os.path.realpath( - getabsfile(module))] = module.__name__ + f = getabsfile(module) + modulesbyfile[f] = modulesbyfile[ + os.path.realpath(f)] = module.__name__ if file in modulesbyfile: return sys.modules.get(modulesbyfile[file]) main = sys.modules['__main__'] Modified: stackless/trunk/Lib/lib-tk/turtle.py ============================================================================== --- stackless/trunk/Lib/lib-tk/turtle.py (original) +++ stackless/trunk/Lib/lib-tk/turtle.py Fri Jul 14 14:39:40 2006 @@ -30,6 +30,7 @@ self._tracing = 1 self._arrow = 0 self._delay = 10 # default delay for drawing + self._angle = 0.0 self.degrees() self.reset() @@ -39,6 +40,10 @@ Example: >>> turtle.degrees() """ + # Don't try to change _angle if it is 0, because + # _fullcircle might not be set, yet + if self._angle: + self._angle = (self._angle / self._fullcircle) * fullcircle self._fullcircle = fullcircle self._invradian = pi / (fullcircle * 0.5) @@ -81,7 +86,6 @@ self._color = "black" self._filling = 0 self._path = [] - self._tofill = [] self.clear() canvas._root().tkraise() @@ -301,19 +305,15 @@ {'fill': self._color, 'smooth': smooth}) self._items.append(item) - if self._tofill: - for item in self._tofill: - self._canvas.itemconfigure(item, fill=self._color) - self._items.append(item) self._path = [] - self._tofill = [] self._filling = flag if flag: self._path.append(self._position) - self.forward(0) def begin_fill(self): """ Called just before drawing a shape to be filled. + Must eventually be followed by a corresponding end_fill() call. + Otherwise it will be ignored. Example: >>> turtle.begin_fill() @@ -326,7 +326,8 @@ >>> turtle.forward(100) >>> turtle.end_fill() """ - self.fill(1) + self._path = [self._position] + self._filling = 1 def end_fill(self): """ Called after drawing a shape to be filled. @@ -344,7 +345,7 @@ """ self.fill(0) - def circle(self, radius, extent=None): + def circle(self, radius, extent = None): """ Draw a circle with given radius. The center is radius units left of the turtle; extent determines which part of the circle is drawn. If not given, @@ -361,52 +362,18 @@ """ if extent is None: extent = self._fullcircle - x0, y0 = self._position - xc = x0 - radius * sin(self._angle * self._invradian) - yc = y0 - radius * cos(self._angle * self._invradian) - if radius >= 0.0: - start = self._angle - (self._fullcircle / 4.0) - else: - start = self._angle + (self._fullcircle / 4.0) - extent = -extent - if self._filling: - if abs(extent) >= self._fullcircle: - item = self._canvas.create_oval(xc-radius, yc-radius, - xc+radius, yc+radius, - width=self._width, - outline="") - self._tofill.append(item) - item = self._canvas.create_arc(xc-radius, yc-radius, - xc+radius, yc+radius, - style="chord", - start=start, - extent=extent, - width=self._width, - outline="") - self._tofill.append(item) - if self._drawing: - if abs(extent) >= self._fullcircle: - item = self._canvas.create_oval(xc-radius, yc-radius, - xc+radius, yc+radius, - width=self._width, - outline=self._color) - self._items.append(item) - item = self._canvas.create_arc(xc-radius, yc-radius, - xc+radius, yc+radius, - style="arc", - start=start, - extent=extent, - width=self._width, - outline=self._color) - self._items.append(item) - angle = start + extent - x1 = xc + abs(radius) * cos(angle * self._invradian) - y1 = yc - abs(radius) * sin(angle * self._invradian) - self._angle = (self._angle + extent) % self._fullcircle - self._position = x1, y1 - if self._filling: - self._path.append(self._position) - self._draw_turtle() + frac = abs(extent)/self._fullcircle + steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac) + w = 1.0 * extent / steps + w2 = 0.5 * w + l = 2.0 * radius * sin(w2*self._invradian) + if radius < 0: + l, w, w2 = -l, -w, -w2 + self.left(w2) + for i in range(steps): + self.forward(l) + self.left(w) + self.right(w2) def heading(self): """ Return the turtle's current heading. @@ -679,7 +646,7 @@ _canvas = Tkinter.Canvas(_root, background="white") _canvas.pack(expand=1, fill="both") - setup(width=_width, height= _height, startx=_startx, starty=_starty) + setup(width=_width, height= _height, startx=_startx, starty=_starty) RawPen.__init__(self, _canvas) @@ -721,7 +688,7 @@ def write(arg, move=0): _getpen().write(arg, move) def fill(flag): _getpen().fill(flag) def begin_fill(): _getpen().begin_fill() -def end_fill(): _getpen.end_fill() +def end_fill(): _getpen().end_fill() def circle(radius, extent=None): _getpen().circle(radius, extent) def goto(*args): _getpen().goto(*args) def heading(): return _getpen().heading() @@ -930,15 +897,30 @@ speed(speeds[sp]) color(0.25,0,0.75) fill(0) - color("green") - left(130) + # draw and fill a concave shape + left(120) up() - forward(90) + forward(70) + right(30) + down() color("red") - speed('fastest') + speed("fastest") + fill(1) + for i in range(4): + circle(50,90) + right(90) + forward(30) + right(90) + color("yellow") + fill(0) + left(90) + up() + forward(30) down(); + color("red") + # create a second turtle and make the original pursue and catch it turtle=Turtle() turtle.reset() Modified: stackless/trunk/Lib/logging/config.py ============================================================================== --- stackless/trunk/Lib/logging/config.py (original) +++ stackless/trunk/Lib/logging/config.py Fri Jul 14 14:39:40 2006 @@ -79,6 +79,7 @@ logging._acquireLock() try: logging._handlers.clear() + logging._handlerList = [] # Handlers add themselves to logging._handlers handlers = _install_handlers(cp, formatters) _install_loggers(cp, handlers) Modified: stackless/trunk/Lib/logging/handlers.py ============================================================================== --- stackless/trunk/Lib/logging/handlers.py (original) +++ stackless/trunk/Lib/logging/handlers.py Fri Jul 14 14:39:40 2006 @@ -128,12 +128,7 @@ dfn = self.baseFilename + ".1" if os.path.exists(dfn): os.remove(dfn) - try: - os.rename(self.baseFilename, dfn) - except (KeyboardInterrupt, SystemExit): - raise - except: - self.handleError(record) + os.rename(self.baseFilename, dfn) #print "%s -> %s" % (self.baseFilename, dfn) if self.encoding: self.stream = codecs.open(self.baseFilename, 'w', self.encoding) @@ -273,12 +268,7 @@ dfn = self.baseFilename + "." + time.strftime(self.suffix, timeTuple) if os.path.exists(dfn): os.remove(dfn) - try: - os.rename(self.baseFilename, dfn) - except (KeyboardInterrupt, SystemExit): - raise - except: - self.handleError(record) + os.rename(self.baseFilename, dfn) if self.backupCount > 0: # find the oldest log file and delete it s = glob.glob(self.baseFilename + ".20*") Modified: stackless/trunk/Lib/mailbox.py ============================================================================== --- stackless/trunk/Lib/mailbox.py (original) +++ stackless/trunk/Lib/mailbox.py Fri Jul 14 14:39:40 2006 @@ -15,7 +15,7 @@ import rfc822 import StringIO try: - import fnctl + import fcntl except ImportError: fcntl = None @@ -1798,26 +1798,18 @@ def _lock_file(f, dotlock=True): - """Lock file f using lockf, flock, and dot locking.""" + """Lock file f using lockf and dot locking.""" dotlock_done = False try: if fcntl: try: fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB) except IOError, e: - if e.errno == errno.EAGAIN: + if e.errno in (errno.EAGAIN, errno.EACCES): raise ExternalClashError('lockf: lock unavailable: %s' % f.name) else: raise - try: - fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB) - except IOError, e: - if e.errno == errno.EWOULDBLOCK: - raise ExternalClashError('flock: lock unavailable: %s' % - f.name) - else: - raise if dotlock: try: pre_lock = _create_temporary(f.name + '.lock') @@ -1845,16 +1837,14 @@ except: if fcntl: fcntl.lockf(f, fcntl.LOCK_UN) - fcntl.flock(f, fcntl.LOCK_UN) if dotlock_done: os.remove(f.name + '.lock') raise def _unlock_file(f): - """Unlock file f using lockf, flock, and dot locking.""" + """Unlock file f using lockf and dot locking.""" if fcntl: fcntl.lockf(f, fcntl.LOCK_UN) - fcntl.flock(f, fcntl.LOCK_UN) if os.path.exists(f.name + '.lock'): os.remove(f.name + '.lock') Modified: stackless/trunk/Lib/msilib/__init__.py ============================================================================== --- stackless/trunk/Lib/msilib/__init__.py (original) +++ stackless/trunk/Lib/msilib/__init__.py Fri Jul 14 14:39:40 2006 @@ -187,7 +187,7 @@ self.filenames = sets.Set() self.index = 0 - def gen_id(self, dir, file): + def gen_id(self, file): logical = _logical = make_id(file) pos = 1 while logical in self.filenames: @@ -196,9 +196,11 @@ self.filenames.add(logical) return logical - def append(self, full, logical): + def append(self, full, file, logical): if os.path.isdir(full): return + if not logical: + logical = self.gen_id(file) self.index += 1 self.files.append((full, logical)) return self.index, logical @@ -328,7 +330,7 @@ logical = self.keyfiles[file] else: logical = None - sequence, logical = self.cab.append(absolute, logical) + sequence, logical = self.cab.append(absolute, file, logical) assert logical not in self.ids self.ids.add(logical) short = self.make_short(file) @@ -403,7 +405,7 @@ [(self.dlg.name, self.name, event, argument, condition, ordering)]) - def mapping(self, mapping, attribute): + def mapping(self, event, attribute): add_data(self.dlg.db, "EventMapping", [(self.dlg.name, self.name, event, attribute)]) Modified: stackless/trunk/Lib/popen2.py ============================================================================== --- stackless/trunk/Lib/popen2.py (original) +++ stackless/trunk/Lib/popen2.py Fri Jul 14 14:39:40 2006 @@ -79,7 +79,7 @@ def _run_child(self, cmd): if isinstance(cmd, basestring): cmd = ['/bin/sh', '-c', cmd] - for i in range(3, MAXFD): + for i in xrange(3, MAXFD): try: os.close(i) except OSError: Modified: stackless/trunk/Lib/sgmllib.py ============================================================================== --- stackless/trunk/Lib/sgmllib.py (original) +++ stackless/trunk/Lib/sgmllib.py Fri Jul 14 14:39:40 2006 @@ -29,11 +29,16 @@ shorttagopen = re.compile('<[a-zA-Z][-.a-zA-Z0-9]*/') shorttag = re.compile('<([a-zA-Z][-.a-zA-Z0-9]*)/([^/]*)/') piclose = re.compile('>') -endbracket = re.compile('[<>]') +starttag = re.compile(r'<[a-zA-Z][-_.:a-zA-Z0-9]*\s*(' + r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*' + r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~@]' + r'[][\-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"@]*(?=[\s>/<])))?' + r')*\s*/?\s*(?=[<>])') +endtag = re.compile(r'])') tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*') attrfind = re.compile( r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*' - r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"@]*))?') + r'(\'[^\']*\'|"[^"]*"|[][\-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"@]*))?') class SGMLParseError(RuntimeError): @@ -249,14 +254,10 @@ self.finish_shorttag(tag, data) self.__starttag_text = rawdata[start_pos:match.end(1) + 1] return k - # XXX The following should skip matching quotes (' or ") - # As a shortcut way to exit, this isn't so bad, but shouldn't - # be used to locate the actual end of the start tag since the - # < or > characters may be embedded in an attribute value. - match = endbracket.search(rawdata, i+1) + match = starttag.match(rawdata, i) if not match: return -1 - j = match.start(0) + j = match.end(0) # Now parse the data between i+1 and j into a tag and attrs attrs = [] if rawdata[i:i+2] == '<>': @@ -305,10 +306,10 @@ # Internal -- parse endtag def parse_endtag(self, i): rawdata = self.rawdata - match = endbracket.search(rawdata, i+1) + match = endtag.match(rawdata, i) if not match: return -1 - j = match.start(0) + j = match.end(0) tag = rawdata[i+2:j].strip().lower() if rawdata[j] == '>': j = j+1 @@ -400,11 +401,11 @@ def handle_charref(self, name): """Handle character reference, no need to override.""" - replacement = convert_charref(name) + replacement = self.convert_charref(name) if replacement is None: self.unknown_charref(name) else: - self.handle_data(convert_charref(name)) + self.handle_data(replacement) # Definition of entities -- derived classes may override entitydefs = \ Modified: stackless/trunk/Lib/socket.py ============================================================================== --- stackless/trunk/Lib/socket.py (original) +++ stackless/trunk/Lib/socket.py Fri Jul 14 14:39:40 2006 @@ -130,35 +130,37 @@ if sys.platform == "riscos": _socketmethods = _socketmethods + ('sleeptaskw',) +# All the method names that must be delegated to either the real socket +# object or the _closedsocket object. +_delegate_methods = ("recv", "recvfrom", "recv_into", "recvfrom_into", + "send", "sendto") + class _closedsocket(object): __slots__ = [] def _dummy(*args): raise error(EBADF, 'Bad file descriptor') - send = recv = sendto = recvfrom = __getattr__ = _dummy + # All _delegate_methods must also be initialized here. + send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy + __getattr__ = _dummy class _socketobject(object): __doc__ = _realsocket.__doc__ - __slots__ = ["_sock", - "recv", "recv_into", "recvfrom_into", - "send", "sendto", "recvfrom", - "__weakref__"] + __slots__ = ["_sock", "__weakref__"] + list(_delegate_methods) def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None): if _sock is None: _sock = _realsocket(family, type, proto) self._sock = _sock - self.send = self._sock.send - self.recv = self._sock.recv - self.recv_into = self._sock.recv_into - self.sendto = self._sock.sendto - self.recvfrom = self._sock.recvfrom - self.recvfrom_into = self._sock.recvfrom_into + for method in _delegate_methods: + setattr(self, method, getattr(_sock, method)) def close(self): self._sock = _closedsocket() - self.send = self.recv = self.sendto = self.recvfrom = self._sock._dummy + dummy = self._sock._dummy + for method in _delegate_methods: + setattr(self, method, dummy) close.__doc__ = _realsocket.close.__doc__ def accept(self): Modified: stackless/trunk/Lib/sqlite3/test/types.py ============================================================================== --- stackless/trunk/Lib/sqlite3/test/types.py (original) +++ stackless/trunk/Lib/sqlite3/test/types.py Fri Jul 14 14:39:40 2006 @@ -21,7 +21,7 @@ # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. -import datetime +import bz2, datetime import unittest import sqlite3 as sqlite @@ -273,6 +273,23 @@ val = self.cur.fetchone()[0] self.failUnlessEqual(type(val), float) +class BinaryConverterTests(unittest.TestCase): + def convert(s): + return bz2.decompress(s) + convert = staticmethod(convert) + + def setUp(self): + self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES) + sqlite.register_converter("bin", BinaryConverterTests.convert) + + def tearDown(self): + self.con.close() + + def CheckBinaryInputForConverter(self): + testdata = "abcdefg" * 10 + result = self.con.execute('select ? as "x [bin]"', (buffer(bz2.compress(testdata)),)).fetchone()[0] + self.failUnlessEqual(testdata, result) + class DateTimeTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES) @@ -322,8 +339,9 @@ decltypes_type_suite = unittest.makeSuite(DeclTypesTests, "Check") colnames_type_suite = unittest.makeSuite(ColNamesTests, "Check") adaptation_suite = unittest.makeSuite(ObjectAdaptationTests, "Check") + bin_suite = unittest.makeSuite(BinaryConverterTests, "Check") date_suite = unittest.makeSuite(DateTimeTests, "Check") - return unittest.TestSuite((sqlite_type_suite, decltypes_type_suite, colnames_type_suite, adaptation_suite, date_suite)) + return unittest.TestSuite((sqlite_type_suite, decltypes_type_suite, colnames_type_suite, adaptation_suite, bin_suite, date_suite)) def test(): runner = unittest.TextTestRunner() Modified: stackless/trunk/Lib/sqlite3/test/userfunctions.py ============================================================================== --- stackless/trunk/Lib/sqlite3/test/userfunctions.py (original) +++ stackless/trunk/Lib/sqlite3/test/userfunctions.py Fri Jul 14 14:39:40 2006 @@ -365,7 +365,6 @@ class AuthorizerTests(unittest.TestCase): def setUp(self): - sqlite.enable_callback_tracebacks(1) self.con = sqlite.connect(":memory:") self.con.executescript(""" create table t1 (c1, c2); Modified: stackless/trunk/Lib/string.py ============================================================================== --- stackless/trunk/Lib/string.py (original) +++ stackless/trunk/Lib/string.py Fri Jul 14 14:39:40 2006 @@ -161,7 +161,7 @@ val = mapping[named] # We use this idiom instead of str() because the latter will # fail if val is a Unicode containing non-ASCII characters. - return '%s' % val + return '%s' % (val,) if mo.group('escaped') is not None: return self.delimiter if mo.group('invalid') is not None: @@ -186,13 +186,13 @@ try: # We use this idiom instead of str() because the latter # will fail if val is a Unicode containing non-ASCII - return '%s' % mapping[named] + return '%s' % (mapping[named],) except KeyError: return self.delimiter + named braced = mo.group('braced') if braced is not None: try: - return '%s' % mapping[braced] + return '%s' % (mapping[braced],) except KeyError: return self.delimiter + '{' + braced + '}' if mo.group('escaped') is not None: Modified: stackless/trunk/Lib/subprocess.py ============================================================================== --- stackless/trunk/Lib/subprocess.py (original) +++ stackless/trunk/Lib/subprocess.py Fri Jul 14 14:39:40 2006 @@ -234,7 +234,7 @@ sts = os.system("mycmd" + " myarg") ==> p = Popen("mycmd" + " myarg", shell=True) -sts = os.waitpid(p.pid, 0) +pid, sts = os.waitpid(p.pid, 0) Note: @@ -941,7 +941,7 @@ def _close_fds(self, but): - for i in range(3, MAXFD): + for i in xrange(3, MAXFD): if i == but: continue try: Modified: stackless/trunk/Lib/tarfile.py ============================================================================== --- stackless/trunk/Lib/tarfile.py (original) +++ stackless/trunk/Lib/tarfile.py Fri Jul 14 14:39:40 2006 @@ -1750,13 +1750,6 @@ try: tarinfo = TarInfo.frombuf(buf) - # We shouldn't rely on this checksum, because some tar programs - # calculate it differently and it is merely validating the - # header block. We could just as well skip this part, which would - # have a slight effect on performance... - if tarinfo.chksum not in calc_chksums(buf): - self._dbg(1, "tarfile: Bad Checksum %r" % tarinfo.name) - # Set the TarInfo object's offset to the current position of the # TarFile and set self.offset to the position where the data blocks # should begin. Modified: stackless/trunk/Lib/telnetlib.py ============================================================================== --- stackless/trunk/Lib/telnetlib.py (original) +++ stackless/trunk/Lib/telnetlib.py Fri Jul 14 14:39:40 2006 @@ -311,6 +311,8 @@ s_args = s_reply if timeout is not None: s_args = s_args + (timeout,) + from time import time + time_start = time() while not self.eof and select.select(*s_args) == s_reply: i = max(0, len(self.cookedq)-n) self.fill_rawq() @@ -321,6 +323,11 @@ buf = self.cookedq[:i] self.cookedq = self.cookedq[i:] return buf + if timeout is not None: + elapsed = time() - time_start + if elapsed >= timeout: + break + s_args = s_reply + (timeout-elapsed,) return self.read_very_lazy() def read_all(self): @@ -601,6 +608,9 @@ if not hasattr(list[i], "search"): if not re: import re list[i] = re.compile(list[i]) + if timeout is not None: + from time import time + time_start = time() while 1: self.process_rawq() for i in indices: @@ -613,7 +623,11 @@ if self.eof: break if timeout is not None: - r, w, x = select.select([self.fileno()], [], [], timeout) + elapsed = time() - time_start + if elapsed >= timeout: + break + s_args = ([self.fileno()], [], [], timeout-elapsed) + r, w, x = select.select(*s_args) if not r: break self.fill_rawq() Deleted: /stackless/trunk/Lib/test/crashers/xml_parsers.py ============================================================================== --- /stackless/trunk/Lib/test/crashers/xml_parsers.py Fri Jul 14 14:39:40 2006 +++ (empty file) @@ -1,56 +0,0 @@ -from xml.parsers import expat - -# http://python.org/sf/1296433 - -def test_parse_only_xml_data(): - # - xml = "%s" % ('a' * 1025) - # this one doesn't crash - #xml = "%s" % ('a' * 10000) - - def handler(text): - raise Exception - - parser = expat.ParserCreate() - parser.CharacterDataHandler = handler - - try: - parser.Parse(xml) - except: - pass - -if __name__ == '__main__': - test_parse_only_xml_data() - -# Invalid read of size 4 -# at 0x43F936: PyObject_Free (obmalloc.c:735) -# by 0x45A7C7: unicode_dealloc (unicodeobject.c:246) -# by 0x1299021D: PyUnknownEncodingHandler (pyexpat.c:1314) -# by 0x12993A66: processXmlDecl (xmlparse.c:3330) -# by 0x12999211: doProlog (xmlparse.c:3678) -# by 0x1299C3F0: prologInitProcessor (xmlparse.c:3550) -# by 0x12991EA3: XML_ParseBuffer (xmlparse.c:1562) -# by 0x1298F8EC: xmlparse_Parse (pyexpat.c:895) -# by 0x47B3A1: PyEval_EvalFrameEx (ceval.c:3565) -# by 0x47CCAC: PyEval_EvalCodeEx (ceval.c:2739) -# by 0x47CDE1: PyEval_EvalCode (ceval.c:490) -# by 0x499820: PyRun_SimpleFileExFlags (pythonrun.c:1198) -# by 0x4117F1: Py_Main (main.c:492) -# by 0x12476D1F: __libc_start_main (in /lib/libc-2.3.5.so) -# by 0x410DC9: (within /home/neal/build/python/svn/clean/python) -# Address 0x12704020 is 264 bytes inside a block of size 592 free'd -# at 0x11B1BA8A: free (vg_replace_malloc.c:235) -# by 0x124B5F18: (within /lib/libc-2.3.5.so) -# by 0x48DE43: find_module (import.c:1320) -# by 0x48E997: import_submodule (import.c:2249) -# by 0x48EC15: load_next (import.c:2083) -# by 0x48F091: import_module_ex (import.c:1914) -# by 0x48F385: PyImport_ImportModuleEx (import.c:1955) -# by 0x46D070: builtin___import__ (bltinmodule.c:44) -# by 0x4186CF: PyObject_Call (abstract.c:1777) -# by 0x474E9B: PyEval_CallObjectWithKeywords (ceval.c:3432) -# by 0x47928E: PyEval_EvalFrameEx (ceval.c:2038) -# by 0x47CCAC: PyEval_EvalCodeEx (ceval.c:2739) -# by 0x47CDE1: PyEval_EvalCode (ceval.c:490) -# by 0x48D0F7: PyImport_ExecCodeModuleEx (import.c:635) -# by 0x48D4F4: load_source_module (import.c:913) Modified: stackless/trunk/Lib/test/fork_wait.py ============================================================================== --- stackless/trunk/Lib/test/fork_wait.py (original) +++ stackless/trunk/Lib/test/fork_wait.py Fri Jul 14 14:39:40 2006 @@ -34,7 +34,14 @@ pass def wait_impl(self, cpid): - spid, status = os.waitpid(cpid, 0) + for i in range(10): + # waitpid() shouldn't hang, but some of the buildbots seem to hang + # in the forking tests. This is an attempt to fix the problem. + spid, status = os.waitpid(cpid, os.WNOHANG) + if spid == cpid: + break + time.sleep(2 * SHORTSLEEP) + self.assertEquals(spid, cpid) self.assertEquals(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8)) Modified: stackless/trunk/Lib/test/regrtest.py ============================================================================== --- stackless/trunk/Lib/test/regrtest.py (original) +++ stackless/trunk/Lib/test/regrtest.py Fri Jul 14 14:39:40 2006 @@ -1274,6 +1274,37 @@ test_winreg test_winsound """, + 'netbsd3': + """ + test_aepack + test_al + test_applesingle + test_bsddb + test_bsddb185 + test_bsddb3 + test_cd + test_cl + test_ctypes + test_curses + test_dl + test_gdbm + test_gl + test_imgfile + test_linuxaudiodev + test_locale + test_macfs + test_macostools + test_nis + test_ossaudiodev + test_pep277 + test_sqlite + test_startfile + test_sunaudiodev + test_tcl + test_unicode_file + test_winreg + test_winsound + """, } _expectations['freebsd5'] = _expectations['freebsd4'] _expectations['freebsd6'] = _expectations['freebsd4'] Modified: stackless/trunk/Lib/test/test__locale.py ============================================================================== --- stackless/trunk/Lib/test/test__locale.py (original) +++ stackless/trunk/Lib/test/test__locale.py Fri Jul 14 14:39:40 2006 @@ -113,6 +113,9 @@ "using eval('3.14') failed for %s" % loc) self.assertEquals(int(float('3.14') * 100), 314, "using float('3.14') failed for %s" % loc) + if localeconv()['decimal_point'] != '.': + self.assertRaises(ValueError, float, + localeconv()['decimal_point'].join(['1', '23'])) def test_main(): run_unittest(_LocaleTests) Modified: stackless/trunk/Lib/test/test_ast.py ============================================================================== --- stackless/trunk/Lib/test/test_ast.py (original) +++ stackless/trunk/Lib/test/test_ast.py Fri Jul 14 14:39:40 2006 @@ -160,7 +160,7 @@ ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, []), [('Return', (1, 8), ('Num', (1, 15), 1))], [])]), ('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]), ('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))]), -('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Load',)), ('Add',), ('Num', (1, 5), 1))]), +('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Num', (1, 5), 1))]), ('Module', [('Print', (1, 0), ('Name', (1, 8), 'f', ('Load',)), [('Num', (1, 11), 1)], False)]), ('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [])]), ('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])]), Modified: stackless/trunk/Lib/test/test_builtin.py ============================================================================== --- stackless/trunk/Lib/test/test_builtin.py (original) +++ stackless/trunk/Lib/test/test_builtin.py Fri Jul 14 14:39:40 2006 @@ -558,13 +558,24 @@ @run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE') def test_float_with_comma(self): # set locale to something that doesn't use '.' for the decimal point + # float must not accept the locale specific decimal point but + # it still has to accept the normal python syntac import locale if not locale.localeconv()['decimal_point'] == ',': return - self.assertEqual(float(" 3,14 "), 3.14) - self.assertEqual(float(" +3,14 "), 3.14) - self.assertEqual(float(" -3,14 "), -3.14) + self.assertEqual(float(" 3.14 "), 3.14) + self.assertEqual(float("+3.14 "), 3.14) + self.assertEqual(float("-3.14 "), -3.14) + self.assertEqual(float(".14 "), .14) + self.assertEqual(float("3. "), 3.0) + self.assertEqual(float("3.e3 "), 3000.0) + self.assertEqual(float("3.2e3 "), 3200.0) + self.assertEqual(float("2.5e-1 "), 0.25) + self.assertEqual(float("5e-1"), 0.5) + self.assertRaises(ValueError, float, " 3,14 ") + self.assertRaises(ValueError, float, " +3,14 ") + self.assertRaises(ValueError, float, " -3,14 ") self.assertRaises(ValueError, float, " 0x3.1 ") self.assertRaises(ValueError, float, " -0x3.p-1 ") self.assertEqual(float(" 25.e-1 "), 2.5) Modified: stackless/trunk/Lib/test/test_bz2.py ============================================================================== --- stackless/trunk/Lib/test/test_bz2.py (original) +++ stackless/trunk/Lib/test/test_bz2.py Fri Jul 14 14:39:40 2006 @@ -352,6 +352,7 @@ BZ2DecompressorTest, FuncTest ) + test_support.reap_children() if __name__ == '__main__': test_main() Modified: stackless/trunk/Lib/test/test_cmd_line.py ============================================================================== --- stackless/trunk/Lib/test/test_cmd_line.py (original) +++ stackless/trunk/Lib/test/test_cmd_line.py Fri Jul 14 14:39:40 2006 @@ -87,6 +87,7 @@ def test_main(): test.test_support.run_unittest(CmdLineTest) + test.test_support.reap_children() if __name__ == "__main__": test_main() Modified: stackless/trunk/Lib/test/test_commands.py ============================================================================== --- stackless/trunk/Lib/test/test_commands.py (original) +++ stackless/trunk/Lib/test/test_commands.py Fri Jul 14 14:39:40 2006 @@ -5,7 +5,7 @@ import unittest import os, tempfile, re -from test.test_support import TestSkipped, run_unittest +from test.test_support import TestSkipped, run_unittest, reap_children from commands import * # The module says: @@ -58,6 +58,7 @@ def test_main(): run_unittest(CommandTests) + reap_children() if __name__ == "__main__": Modified: stackless/trunk/Lib/test/test_compile.py ============================================================================== --- stackless/trunk/Lib/test/test_compile.py (original) +++ stackless/trunk/Lib/test/test_compile.py Fri Jul 14 14:39:40 2006 @@ -166,6 +166,16 @@ pass""" compile(s, "", "exec") + # This test is probably specific to CPython and may not generalize + # to other implementations. We are trying to ensure that when + # the first line of code starts after 256, correct line numbers + # in tracebacks are still produced. + def test_leading_newlines(self): + s256 = "".join(["\n"] * 256 + ["spam"]) + co = compile(s256, 'fn', 'exec') + self.assertEqual(co.co_firstlineno, 257) + self.assertEqual(co.co_lnotab, '') + def test_literals_with_leading_zeroes(self): for arg in ["077787", "0xj", "0x.", "0e", "090000000000000", "080000000000000", "000000000000009", "000000000000008"]: @@ -211,6 +221,25 @@ self.assertEqual(eval("-" + all_one_bits), -18446744073709551615L) else: self.fail("How many bits *does* this machine have???") + # Verify treatment of contant folding on -(sys.maxint+1) + # i.e. -2147483648 on 32 bit platforms. Should return int, not long. + self.assertTrue(isinstance(eval("%s" % (-sys.maxint - 1)), int)) + self.assertTrue(isinstance(eval("%s" % (-sys.maxint - 2)), long)) + + if sys.maxint == 9223372036854775807: + def test_32_63_bit_values(self): + a = +4294967296 # 1 << 32 + b = -4294967296 # 1 << 32 + c = +281474976710656 # 1 << 48 + d = -281474976710656 # 1 << 48 + e = +4611686018427387904 # 1 << 62 + f = -4611686018427387904 # 1 << 62 + g = +9223372036854775807 # 1 << 63 - 1 + h = -9223372036854775807 # 1 << 63 - 1 + + for variable in self.test_32_63_bit_values.func_code.co_consts: + if variable is not None: + self.assertTrue(isinstance(variable, int)) def test_sequence_unpacking_error(self): # Verify sequence packing/unpacking with "or". SF bug #757818 @@ -238,6 +267,8 @@ succeed = [ 'import sys', 'import os, sys', + 'import os as bar', + 'import os.path as bar', 'from __future__ import nested_scopes, generators', 'from __future__ import (nested_scopes,\ngenerators)', 'from __future__ import (nested_scopes,\ngenerators,)', @@ -257,6 +288,10 @@ 'import (sys', 'import sys)', 'import (os,)', + 'import os As bar', + 'import os.path a bar', + 'from sys import stdin As stdout', + 'from sys import stdin a stdout', 'from (sys) import stdin', 'from __future__ import (nested_scopes', 'from __future__ import nested_scopes)', Modified: stackless/trunk/Lib/test/test_compiler.py ============================================================================== --- stackless/trunk/Lib/test/test_compiler.py (original) +++ stackless/trunk/Lib/test/test_compiler.py Fri Jul 14 14:39:40 2006 @@ -56,6 +56,15 @@ def testYieldExpr(self): compiler.compile("def g(): yield\n\n", "", "exec") + def testTryExceptFinally(self): + # Test that except and finally clauses in one try stmt are recognized + c = compiler.compile("try:\n 1/0\nexcept:\n e = 1\nfinally:\n f = 1", + "", "exec") + dct = {} + exec c in dct + self.assertEquals(dct.get('e'), 1) + self.assertEquals(dct.get('f'), 1) + def testDefaultArgs(self): self.assertRaises(SyntaxError, compiler.parse, "def foo(a=1, b): pass") @@ -103,6 +112,12 @@ l = [(x, y) for x, y in zip(range(5), range(5,10))] l[0] l[3:4] +d = {'a': 2} +d = {} +t = () +t = (1, 2) +l = [] +l = [1, 2] if l: pass else: Modified: stackless/trunk/Lib/test/test_descr.py ============================================================================== --- stackless/trunk/Lib/test/test_descr.py (original) +++ stackless/trunk/Lib/test/test_descr.py Fri Jul 14 14:39:40 2006 @@ -3966,6 +3966,13 @@ o.whatever = Provoker(o) del o +def wrapper_segfault(): + # SF 927248: deeply nested wrappers could cause stack overflow + f = lambda:None + for i in xrange(1000000): + f = f.__call__ + f = None + # Fix SF #762455, segfault when sys.stdout is changed in getattr def filefault(): if verbose: @@ -4121,6 +4128,7 @@ def test_main(): weakref_segfault() # Must be first, somehow + wrapper_segfault() do_this_first() class_docstrings() lists() Modified: stackless/trunk/Lib/test/test_exceptions.py ============================================================================== --- stackless/trunk/Lib/test/test_exceptions.py (original) +++ stackless/trunk/Lib/test/test_exceptions.py Fri Jul 14 14:39:40 2006 @@ -305,6 +305,18 @@ x = DerivedException(fancy_arg=42) self.assertEquals(x.fancy_arg, 42) + def testInfiniteRecursion(self): + def f(): + return f() + self.assertRaises(RuntimeError, f) + + def g(): + try: + return g() + except ValueError: + return -1 + self.assertRaises(RuntimeError, g) + def test_main(): run_unittest(ExceptionTests) Modified: stackless/trunk/Lib/test/test_fcntl.py ============================================================================== --- stackless/trunk/Lib/test/test_fcntl.py (original) +++ stackless/trunk/Lib/test/test_fcntl.py Fri Jul 14 14:39:40 2006 @@ -20,9 +20,10 @@ if sys.platform.startswith('atheos'): start_len = "qq" -if sys.platform in ('netbsd1', 'netbsd2', 'Darwin1.2', 'darwin', - 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5', 'freebsd6', - 'freebsd7', +if sys.platform in ('netbsd1', 'netbsd2', 'netbsd3', + 'Darwin1.2', 'darwin', + 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5', + 'freebsd6', 'freebsd7', 'bsdos2', 'bsdos3', 'bsdos4', 'openbsd', 'openbsd2', 'openbsd3'): if struct.calcsize('l') == 8: Modified: stackless/trunk/Lib/test/test_fork1.py ============================================================================== --- stackless/trunk/Lib/test/test_fork1.py (original) +++ stackless/trunk/Lib/test/test_fork1.py Fri Jul 14 14:39:40 2006 @@ -2,8 +2,9 @@ """ import os +import time from test.fork_wait import ForkWait -from test.test_support import TestSkipped, run_unittest +from test.test_support import TestSkipped, run_unittest, reap_children try: os.fork @@ -12,12 +13,20 @@ class ForkTest(ForkWait): def wait_impl(self, cpid): - spid, status = os.waitpid(cpid, 0) + for i in range(10): + # waitpid() shouldn't hang, but some of the buildbots seem to hang + # in the forking tests. This is an attempt to fix the problem. + spid, status = os.waitpid(cpid, os.WNOHANG) + if spid == cpid: + break + time.sleep(1.0) + self.assertEqual(spid, cpid) self.assertEqual(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8)) def test_main(): run_unittest(ForkTest) + reap_children() if __name__ == "__main__": test_main() Modified: stackless/trunk/Lib/test/test_inspect.py ============================================================================== --- stackless/trunk/Lib/test/test_inspect.py (original) +++ stackless/trunk/Lib/test/test_inspect.py Fri Jul 14 14:39:40 2006 @@ -178,6 +178,16 @@ def test_getfile(self): self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__) + def test_getmodule_recursion(self): + from new import module + name = '__inspect_dummy' + m = sys.modules[name] = module(name) + m.__file__ = "" # hopefully not a real filename... + m.__loader__ = "dummy" # pretend the filename is understood by a loader + exec "def x(): pass" in m.__dict__ + self.assertEqual(inspect.getsourcefile(m.x.func_code), '') + del sys.modules[name] + class TestDecorators(GetSourceBase): fodderFile = mod2 Modified: stackless/trunk/Lib/test/test_logging.py ============================================================================== --- stackless/trunk/Lib/test/test_logging.py (original) +++ stackless/trunk/Lib/test/test_logging.py Fri Jul 14 14:39:40 2006 @@ -480,6 +480,8 @@ f.close() try: logging.config.fileConfig(fn) + #call again to make sure cleanup is correct + logging.config.fileConfig(fn) except: t = sys.exc_info()[0] message(str(t)) Modified: stackless/trunk/Lib/test/test_mailbox.py ============================================================================== --- stackless/trunk/Lib/test/test_mailbox.py (original) +++ stackless/trunk/Lib/test/test_mailbox.py Fri Jul 14 14:39:40 2006 @@ -720,6 +720,30 @@ self.assert_(contents == open(self._path, 'rb').read()) self._box = self._factory(self._path) + def test_lock_conflict(self): + # Fork off a subprocess that will lock the file for 2 seconds, + # unlock it, and then exit. + if not hasattr(os, 'fork'): + return + pid = os.fork() + if pid == 0: + # In the child, lock the mailbox. + self._box.lock() + time.sleep(2) + self._box.unlock() + os._exit(0) + + # In the parent, sleep a bit to give the child time to acquire + # the lock. + time.sleep(0.5) + self.assertRaises(mailbox.ExternalClashError, + self._box.lock) + + # Wait for child to exit. Locking should now succeed. + exited_pid, status = os.waitpid(pid, 0) + self._box.lock() + self._box.unlock() + class TestMbox(_TestMboxMMDF): @@ -1761,6 +1785,7 @@ TestMessageConversion, TestProxyFile, TestPartialFile, MaildirTestCase) test_support.run_unittest(*tests) + test_support.reap_children() if __name__ == '__main__': Modified: stackless/trunk/Lib/test/test_multibytecodec.py ========================================================