summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorThomas Wouters <thomas@python.org>2006-12-13 04:49:30 (GMT)
committerThomas Wouters <thomas@python.org>2006-12-13 04:49:30 (GMT)
commit89f507fe8c497b3f70fdcecce8bc240f9af2bbe2 (patch)
tree8acfdf7de23d9802924a2cef9f8ed32222eaa8f4 /Lib
parent16f3e03283cdbea6101d21960743d3901ddf8d57 (diff)
downloadcpython-89f507fe8c497b3f70fdcecce8bc240f9af2bbe2.zip
cpython-89f507fe8c497b3f70fdcecce8bc240f9af2bbe2.tar.gz
cpython-89f507fe8c497b3f70fdcecce8bc240f9af2bbe2.tar.bz2
Four months of trunk changes (including a few releases...)
Merged revisions 51434-53004 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r51434 | neal.norwitz | 2006-08-21 20:20:10 +0200 (Mon, 21 Aug 2006) | 1 line Fix a couple of ssize-t issues reported by Alexander Belopolsky on python-dev ........ r51439 | neal.norwitz | 2006-08-21 21:47:08 +0200 (Mon, 21 Aug 2006) | 6 lines Patch #1542451: disallow continue anywhere under a finally I'm undecided if this should be backported to 2.5 or 2.5.1. Armin suggested to wait (I'm of the same opinion). Thomas W thinks it's fine to go in 2.5. ........ r51443 | neal.norwitz | 2006-08-21 22:16:24 +0200 (Mon, 21 Aug 2006) | 4 lines Handle a few more error conditions. Klocwork 301 and 302. Will backport. ........ r51450 | neal.norwitz | 2006-08-22 00:21:19 +0200 (Tue, 22 Aug 2006) | 5 lines Patch #1541585: fix buffer overrun when performing repr() on a unicode string in a build with wide unicode (UCS-4) support. This code could be improved, so add an XXX comment. ........ r51456 | neal.norwitz | 2006-08-22 01:44:48 +0200 (Tue, 22 Aug 2006) | 1 line Try to get the windows bots working again with the new peephole.c ........ r51461 | anthony.baxter | 2006-08-22 09:36:59 +0200 (Tue, 22 Aug 2006) | 1 line patch for documentation for recent uuid changes (from ping) ........ r51473 | neal.norwitz | 2006-08-22 15:56:56 +0200 (Tue, 22 Aug 2006) | 1 line Alexander Belopolsky pointed out that pos is a size_t ........ r51489 | jeremy.hylton | 2006-08-22 22:46:00 +0200 (Tue, 22 Aug 2006) | 2 lines Expose column offset information in parse trees. ........ r51497 | andrew.kuchling | 2006-08-23 01:13:43 +0200 (Wed, 23 Aug 2006) | 1 line Move functional howto into trunk ........ r51515 | jeremy.hylton | 2006-08-23 20:37:43 +0200 (Wed, 23 Aug 2006) | 2 lines Baby steps towards better tests for tokenize ........ r51525 | alex.martelli | 2006-08-23 22:42:02 +0200 (Wed, 23 Aug 2006) | 6 lines x**2 should about equal x*x (including for a float x such that the result is inf) but didn't; added a test to test_float to verify that, and ignored the ERANGE value for errno in the pow operation to make the new test pass (with help from Marilyn Davis at the Google Python Sprint -- thanks!). ........ r51526 | jeremy.hylton | 2006-08-23 23:14:03 +0200 (Wed, 23 Aug 2006) | 20 lines Bug fixes large and small for tokenize. Small: Always generate a NL or NEWLINE token following a COMMENT token. The old code did not generate an NL token if the comment was on a line by itself. Large: The output of untokenize() will now match the input exactly if it is passed the full token sequence. The old, crufty output is still generated if a limited input sequence is provided, where limited means that it does not include position information for tokens. Remaining bug: There is no CONTINUATION token (\) so there is no way for untokenize() to handle such code. Also, expanded the number of doctests in hopes of eventually removing the old-style tests that compare against a golden file. Bug fix candidate for Python 2.5.1. (Sigh.) ........ r51527 | jeremy.hylton | 2006-08-23 23:26:46 +0200 (Wed, 23 Aug 2006) | 5 lines Replace dead code with an assert. Now that COMMENT tokens are reliably followed by NL or NEWLINE, there is never a need to add extra newlines in untokenize. ........ r51530 | alex.martelli | 2006-08-24 00:17:59 +0200 (Thu, 24 Aug 2006) | 7 lines Reverting the patch that tried to fix the issue whereby x**2 raises OverflowError while x*x succeeds and produces infinity; apparently these inconsistencies cannot be fixed across ``all'' platforms and there's a widespread feeling that therefore ``every'' platform should keep suffering forevermore. Ah well. ........ r51565 | thomas.wouters | 2006-08-24 20:40:20 +0200 (Thu, 24 Aug 2006) | 6 lines Fix SF bug #1545837: array.array borks on deepcopy. array.__deepcopy__() needs to take an argument, even if it doesn't actually use it. Will backport to 2.5 and 2.4 (if applicable.) ........ r51580 | martin.v.loewis | 2006-08-25 02:03:34 +0200 (Fri, 25 Aug 2006) | 3 lines Patch #1545507: Exclude ctypes package in Win64 MSI file. Will backport to 2.5. ........ r51589 | neal.norwitz | 2006-08-25 03:52:49 +0200 (Fri, 25 Aug 2006) | 1 line importing types is not necessary if we use isinstance ........ r51604 | thomas.heller | 2006-08-25 09:27:33 +0200 (Fri, 25 Aug 2006) | 3 lines Port _ctypes.pyd to win64 on AMD64. ........ r51605 | thomas.heller | 2006-08-25 09:34:51 +0200 (Fri, 25 Aug 2006) | 3 lines Add missing file for _ctypes.pyd port to win64 on AMD64. ........ r51606 | thomas.heller | 2006-08-25 11:26:33 +0200 (Fri, 25 Aug 2006) | 6 lines Build _ctypes.pyd for win AMD64 into the MSVC project file. Since MSVC doesn't know about .asm files, a helper batch file is needed to find ml64.exe in predefined locations. The helper script hardcodes the path to the MS Platform SDK. ........ r51608 | armin.rigo | 2006-08-25 14:44:28 +0200 (Fri, 25 Aug 2006) | 4 lines The regular expression engine in '_sre' can segfault when interpreting bogus bytecode. It is unclear whether this is a real bug or a "won't fix" case like bogus_code_obj.py. ........ r51617 | tim.peters | 2006-08-26 00:05:39 +0200 (Sat, 26 Aug 2006) | 2 lines Whitespace normalization. ........ r51618 | tim.peters | 2006-08-26 00:06:44 +0200 (Sat, 26 Aug 2006) | 2 lines Add missing svn:eol-style property to text files. ........ r51619 | tim.peters | 2006-08-26 00:26:21 +0200 (Sat, 26 Aug 2006) | 3 lines A new test here relied on preserving invisible trailing whitespace in expected output. Stop that. ........ r51624 | jack.diederich | 2006-08-26 20:42:06 +0200 (Sat, 26 Aug 2006) | 4 lines - Move functions common to all path modules into genericpath.py and have the OS speicifc path modules import them. - Have os2emxpath import common functions fron ntpath instead of using copies ........ r51642 | neal.norwitz | 2006-08-29 07:40:58 +0200 (Tue, 29 Aug 2006) | 1 line Fix a couple of typos. ........ r51647 | marc-andre.lemburg | 2006-08-29 12:34:12 +0200 (Tue, 29 Aug 2006) | 5 lines Fix a buglet in the error reporting (SF bug report #1546372). This should probably go into Python 2.5 or 2.5.1 as well. ........ r51663 | armin.rigo | 2006-08-31 10:51:06 +0200 (Thu, 31 Aug 2006) | 3 lines Doc fix: hashlib objects don't always return a digest of 16 bytes. Backport candidate for 2.5. ........ r51664 | nick.coghlan | 2006-08-31 14:00:43 +0200 (Thu, 31 Aug 2006) | 1 line Fix the wrongheaded implementation of context management in the decimal module and add unit tests. (python-dev discussion is ongoing regarding what we do about Python 2.5) ........ r51665 | nick.coghlan | 2006-08-31 14:51:25 +0200 (Thu, 31 Aug 2006) | 1 line Remove the old decimal context management tests from test_contextlib (guess who didn't run the test suite before committing...) ........ r51669 | brett.cannon | 2006-08-31 20:54:26 +0200 (Thu, 31 Aug 2006) | 4 lines Make sure memory is properly cleaned up in file_init. Backport candidate. ........ r51671 | brett.cannon | 2006-08-31 23:47:52 +0200 (Thu, 31 Aug 2006) | 2 lines Fix comment about indentation level in C files. ........ r51674 | brett.cannon | 2006-09-01 00:42:37 +0200 (Fri, 01 Sep 2006) | 3 lines Have pre-existing C files use 8 spaces indents (to match old PEP 7 style), but have all new files use 4 spaces (to match current PEP 7 style). ........ r51676 | fred.drake | 2006-09-01 05:57:19 +0200 (Fri, 01 Sep 2006) | 3 lines - SF patch #1550263: Enhance and correct unittest docs - various minor cleanups for improved consistency ........ r51677 | georg.brandl | 2006-09-02 00:30:52 +0200 (Sat, 02 Sep 2006) | 2 lines evalfile() should be execfile(). ........ r51681 | neal.norwitz | 2006-09-02 04:43:17 +0200 (Sat, 02 Sep 2006) | 1 line SF #1547931, fix typo (missing and). Will backport to 2.5 ........ r51683 | neal.norwitz | 2006-09-02 04:50:35 +0200 (Sat, 02 Sep 2006) | 1 line Bug #1548092: fix curses.tparm seg fault on invalid input. Needs backport to 2.5.1 and earlier. ........ r51684 | neal.norwitz | 2006-09-02 04:58:13 +0200 (Sat, 02 Sep 2006) | 4 lines Bug #1550714: fix SystemError from itertools.tee on negative value for n. Needs backport to 2.5.1 and earlier. ........ r51685 | nick.coghlan | 2006-09-02 05:54:17 +0200 (Sat, 02 Sep 2006) | 1 line Make decimal.ContextManager a private implementation detail of decimal.localcontext() ........ r51686 | nick.coghlan | 2006-09-02 06:04:18 +0200 (Sat, 02 Sep 2006) | 1 line Further corrections to the decimal module context management documentation ........ r51688 | raymond.hettinger | 2006-09-02 19:07:23 +0200 (Sat, 02 Sep 2006) | 1 line Fix documentation nits for decimal context managers. ........ r51690 | neal.norwitz | 2006-09-02 20:51:34 +0200 (Sat, 02 Sep 2006) | 1 line Add missing word in comment ........ r51691 | neal.norwitz | 2006-09-02 21:40:19 +0200 (Sat, 02 Sep 2006) | 7 lines Hmm, this test has failed at least twice recently on the OpenBSD and Debian sparc buildbots. Since this goes through a lot of tests and hits the disk a lot it could be slow (especially if NFS is involved). I'm not sure if that's the problem, but printing periodic msgs shouldn't hurt. The code was stolen from test_compiler. ........ r51693 | nick.coghlan | 2006-09-03 03:02:00 +0200 (Sun, 03 Sep 2006) | 1 line Fix final documentation nits before backporting decimal module fixes to 2.5 ........ r51694 | nick.coghlan | 2006-09-03 03:06:07 +0200 (Sun, 03 Sep 2006) | 1 line Typo fix for decimal docs ........ r51697 | nick.coghlan | 2006-09-03 03:20:46 +0200 (Sun, 03 Sep 2006) | 1 line NEWS entry on trunk for decimal module changes ........ r51704 | raymond.hettinger | 2006-09-04 17:32:48 +0200 (Mon, 04 Sep 2006) | 1 line Fix endcase for str.rpartition() ........ r51716 | tim.peters | 2006-09-05 04:18:09 +0200 (Tue, 05 Sep 2006) | 12 lines "Conceptual" merge of rev 51711 from the 2.5 branch. i_divmod(): As discussed on Python-Dev, changed the overflow checking to live happily with recent gcc optimizations that assume signed integer arithmetic never overflows. This differs from the corresponding change on the 2.5 and 2.4 branches, using a less obscure approach, but one that /may/ tickle platform idiocies in their definitions of LONG_MIN. The 2.4 + 2.5 change avoided introducing a dependence on LONG_MIN, at the cost of substantially goofier code. ........ r51717 | tim.peters | 2006-09-05 04:21:19 +0200 (Tue, 05 Sep 2006) | 2 lines Whitespace normalization. ........ r51719 | tim.peters | 2006-09-05 04:22:17 +0200 (Tue, 05 Sep 2006) | 2 lines Add missing svn:eol-style property to text files. ........ r51720 | neal.norwitz | 2006-09-05 04:24:03 +0200 (Tue, 05 Sep 2006) | 2 lines Fix SF bug #1546288, crash in dict_equal. ........ r51721 | neal.norwitz | 2006-09-05 04:25:41 +0200 (Tue, 05 Sep 2006) | 1 line Fix SF #1552093, eval docstring typo (3 ps in mapping) ........ r51724 | neal.norwitz | 2006-09-05 04:35:08 +0200 (Tue, 05 Sep 2006) | 1 line This was found by Guido AFAIK on p3yk (sic) branch. ........ r51725 | neal.norwitz | 2006-09-05 04:36:20 +0200 (Tue, 05 Sep 2006) | 1 line Add a NEWS entry for str.rpartition() change ........ r51728 | neal.norwitz | 2006-09-05 04:57:01 +0200 (Tue, 05 Sep 2006) | 1 line Patch #1540470, for OpenBSD 4.0. Backport candidate for 2.[34]. ........ r51729 | neal.norwitz | 2006-09-05 05:53:08 +0200 (Tue, 05 Sep 2006) | 12 lines Bug #1520864 (again): unpacking singleton tuples in list comprehensions and generator expressions (x for x, in ... ) works again. Sigh, I only fixed for loops the first time, not list comps and genexprs too. I couldn't find any more unpacking cases where there is a similar bug lurking. This code should be refactored to eliminate the duplication. I'm sure the listcomp/genexpr code can be refactored. I'm not sure if the for loop can re-use any of the same code though. Will backport to 2.5 (the only place it matters). ........ r51731 | neal.norwitz | 2006-09-05 05:58:26 +0200 (Tue, 05 Sep 2006) | 1 line Add a comment about some refactoring. (There's probably more that should be done.) I will reformat this file in the next checkin due to the inconsistent tabs/spaces. ........ r51732 | neal.norwitz | 2006-09-05 06:00:12 +0200 (Tue, 05 Sep 2006) | 1 line M-x untabify ........ r51737 | hyeshik.chang | 2006-09-05 14:07:09 +0200 (Tue, 05 Sep 2006) | 7 lines Fix a few bugs on cjkcodecs found by Oren Tirosh: - gbk and gb18030 codec now handle U+30FB KATAKANA MIDDLE DOT correctly. - iso2022_jp_2 codec now encodes into G0 for KS X 1001, GB2312 codepoints to conform the standard. - iso2022_jp_3 and iso2022_jp_2004 codec can encode JIS X 2013:2 codepoints now. ........ r51738 | hyeshik.chang | 2006-09-05 14:14:57 +0200 (Tue, 05 Sep 2006) | 2 lines Fix a typo: 2013 -> 0213 ........ r51740 | georg.brandl | 2006-09-05 14:44:58 +0200 (Tue, 05 Sep 2006) | 3 lines Bug #1552618: change docs of dict.has_key() to reflect recommendation to use "in". ........ r51742 | andrew.kuchling | 2006-09-05 15:02:40 +0200 (Tue, 05 Sep 2006) | 1 line Rearrange example a bit, and show rpartition() when separator is not found ........ r51744 | andrew.kuchling | 2006-09-05 15:15:41 +0200 (Tue, 05 Sep 2006) | 1 line [Bug #1525469] SimpleXMLRPCServer still uses the sys.exc_{value,type} module-level globals instead of calling sys.exc_info(). Reported by Russell Warren ........ r51745 | andrew.kuchling | 2006-09-05 15:19:18 +0200 (Tue, 05 Sep 2006) | 3 lines [Bug #1526834] Fix crash in pdb when you do 'b f('; the function name was placed into a regex pattern and the unbalanced paren caused re.compile() to report an error ........ r51751 | kristjan.jonsson | 2006-09-05 19:58:12 +0200 (Tue, 05 Sep 2006) | 6 lines Update the PCBuild8 solution. Facilitate cross-compilation by having binaries in separate Win32 and x64 directories. Rationalized configs by making proper use of platforms/configurations. Remove pythoncore_pgo project. Add new PGIRelease and PGORelease configurations to perform Profile Guided Optimisation. Removed I64 support, but this can be easily added by copying the x64 platform settings. ........ r51758 | gustavo.niemeyer | 2006-09-06 03:58:52 +0200 (Wed, 06 Sep 2006) | 3 lines Fixing #1531862: Do not close standard file descriptors in the subprocess module. ........ r51760 | neal.norwitz | 2006-09-06 05:58:34 +0200 (Wed, 06 Sep 2006) | 1 line Revert 51758 because it broke all the buildbots ........ r51762 | georg.brandl | 2006-09-06 08:03:59 +0200 (Wed, 06 Sep 2006) | 3 lines Bug #1551427: fix a wrong NULL pointer check in the win32 version of os.urandom(). ........ r51765 | georg.brandl | 2006-09-06 08:09:31 +0200 (Wed, 06 Sep 2006) | 3 lines Bug #1550983: emit better error messages for erroneous relative imports (if not in package and if beyond toplevel package). ........ r51767 | neal.norwitz | 2006-09-06 08:28:06 +0200 (Wed, 06 Sep 2006) | 1 line with and as are now keywords. There are some generated files I can't recreate. ........ r51770 | georg.brandl | 2006-09-06 08:50:05 +0200 (Wed, 06 Sep 2006) | 5 lines Bug #1542051: Exceptions now correctly call PyObject_GC_UnTrack. Also make sure that every exception class has __module__ set to 'exceptions'. ........ r51785 | georg.brandl | 2006-09-06 22:05:58 +0200 (Wed, 06 Sep 2006) | 2 lines Fix missing import of the types module in logging.config. ........ r51789 | marc-andre.lemburg | 2006-09-06 22:40:22 +0200 (Wed, 06 Sep 2006) | 3 lines Add news item for bug fix of SF bug report #1546372. ........ r51797 | gustavo.niemeyer | 2006-09-07 02:48:33 +0200 (Thu, 07 Sep 2006) | 3 lines Fixed subprocess bug #1531862 again, after removing tests offending buildbot ........ r51798 | raymond.hettinger | 2006-09-07 04:42:48 +0200 (Thu, 07 Sep 2006) | 1 line Fix refcounts and add error checks. ........ r51803 | nick.coghlan | 2006-09-07 12:50:34 +0200 (Thu, 07 Sep 2006) | 1 line Fix the speed regression in inspect.py by adding another cache to speed up getmodule(). Patch #1553314 ........ r51805 | ronald.oussoren | 2006-09-07 14:03:10 +0200 (Thu, 07 Sep 2006) | 2 lines Fix a glaring error and update some version numbers. ........ r51814 | andrew.kuchling | 2006-09-07 15:56:23 +0200 (Thu, 07 Sep 2006) | 1 line Typo fix ........ r51815 | andrew.kuchling | 2006-09-07 15:59:38 +0200 (Thu, 07 Sep 2006) | 8 lines [Bug #1552726] Avoid repeatedly polling in interactive mode -- only put a timeout on the select() if an input hook has been defined. Patch by Richard Boulton. This select() code is only executed with readline 2.1, or if READLINE_CALLBACKS is defined. Backport candidate for 2.5, 2.4, probably earlier versions too. ........ r51816 | armin.rigo | 2006-09-07 17:06:00 +0200 (Thu, 07 Sep 2006) | 2 lines Add a warning notice on top of the generated grammar.txt. ........ r51819 | thomas.heller | 2006-09-07 20:56:28 +0200 (Thu, 07 Sep 2006) | 5 lines Anonymous structure fields that have a bit-width specified did not work, and they gave a strange error message from PyArg_ParseTuple: function takes exactly 2 arguments (3 given). With tests. ........ r51820 | thomas.heller | 2006-09-07 21:09:54 +0200 (Thu, 07 Sep 2006) | 4 lines The cast function did not accept c_char_p or c_wchar_p instances as first argument, and failed with a 'bad argument to internal function' error message. ........ r51827 | nick.coghlan | 2006-09-08 12:04:38 +0200 (Fri, 08 Sep 2006) | 1 line Add missing NEWS entry for rev 51803 ........ r51828 | andrew.kuchling | 2006-09-08 15:25:23 +0200 (Fri, 08 Sep 2006) | 1 line Add missing word ........ r51829 | andrew.kuchling | 2006-09-08 15:35:49 +0200 (Fri, 08 Sep 2006) | 1 line Explain SQLite a bit more clearly ........ r51830 | andrew.kuchling | 2006-09-08 15:36:36 +0200 (Fri, 08 Sep 2006) | 1 line Explain SQLite a bit more clearly ........ r51832 | andrew.kuchling | 2006-09-08 16:02:45 +0200 (Fri, 08 Sep 2006) | 1 line Use native SQLite types ........ r51833 | andrew.kuchling | 2006-09-08 16:03:01 +0200 (Fri, 08 Sep 2006) | 1 line Use native SQLite types ........ r51835 | andrew.kuchling | 2006-09-08 16:05:10 +0200 (Fri, 08 Sep 2006) | 1 line Fix typo in example ........ r51837 | brett.cannon | 2006-09-09 09:11:46 +0200 (Sat, 09 Sep 2006) | 6 lines Remove the __unicode__ method from exceptions. Allows unicode() to be called on exception classes. Would require introducing a tp_unicode slot to make it work otherwise. Fixes bug #1551432 and will be backported. ........ r51854 | neal.norwitz | 2006-09-11 06:24:09 +0200 (Mon, 11 Sep 2006) | 8 lines Forward port of 51850 from release25-maint branch. As mentioned on python-dev, reverting patch #1504333 because it introduced an infinite loop in rev 47154. This patch also adds a test to prevent the regression. ........ r51855 | neal.norwitz | 2006-09-11 06:28:16 +0200 (Mon, 11 Sep 2006) | 5 lines Properly handle a NULL returned from PyArena_New(). (Also fix some whitespace) Klocwork #364. ........ r51856 | neal.norwitz | 2006-09-11 06:32:57 +0200 (Mon, 11 Sep 2006) | 1 line Add a "crasher" taken from the sgml bug report referenced in the comment ........ r51858 | georg.brandl | 2006-09-11 11:38:35 +0200 (Mon, 11 Sep 2006) | 12 lines Forward-port of rev. 51857: Building with HP's cc on HP-UX turned up a couple of problems. _PyGILState_NoteThreadState was declared as static inconsistently. Make it static as it's not necessary outside of this module. Some tests failed because errno was reset to 0. (I think the tests that failed were at least: test_fcntl and test_mailbox). Ensure that errno doesn't change after a call to Py_END_ALLOW_THREADS. This only affected debug builds. ........ r51865 | martin.v.loewis | 2006-09-12 21:49:20 +0200 (Tue, 12 Sep 2006) | 2 lines Forward-port 51862: Add sgml_input.html. ........ r51866 | andrew.kuchling | 2006-09-12 22:50:23 +0200 (Tue, 12 Sep 2006) | 1 line Markup typo fix ........ r51867 | andrew.kuchling | 2006-09-12 23:09:02 +0200 (Tue, 12 Sep 2006) | 1 line Some editing, markup fixes ........ r51868 | andrew.kuchling | 2006-09-12 23:21:51 +0200 (Tue, 12 Sep 2006) | 1 line More wordsmithing ........ r51877 | andrew.kuchling | 2006-09-14 13:22:18 +0200 (Thu, 14 Sep 2006) | 1 line Make --help mention that -v can be supplied multiple times ........ r51878 | andrew.kuchling | 2006-09-14 13:28:50 +0200 (Thu, 14 Sep 2006) | 1 line Rewrite help message to remove some of the parentheticals. (There were a lot of them.) ........ r51883 | ka-ping.yee | 2006-09-15 02:34:19 +0200 (Fri, 15 Sep 2006) | 2 lines Fix grammar errors and improve clarity. ........ r51885 | georg.brandl | 2006-09-15 07:22:24 +0200 (Fri, 15 Sep 2006) | 3 lines Correct elementtree module index entry. ........ r51889 | fred.drake | 2006-09-15 17:18:04 +0200 (Fri, 15 Sep 2006) | 4 lines - fix module name in links in formatted documentation - minor markup cleanup (forward-ported from release25-maint revision 51888) ........ r51891 | fred.drake | 2006-09-15 18:11:27 +0200 (Fri, 15 Sep 2006) | 3 lines revise explanation of returns_unicode to reflect bool values and to include the default value (merged from release25-maint revision 51890) ........ r51897 | martin.v.loewis | 2006-09-16 19:36:37 +0200 (Sat, 16 Sep 2006) | 2 lines Patch #1557515: Add RLIMIT_SBSIZE. ........ r51903 | ronald.oussoren | 2006-09-17 20:42:53 +0200 (Sun, 17 Sep 2006) | 2 lines Port of revision 51902 in release25-maint to the trunk ........ r51904 | ronald.oussoren | 2006-09-17 21:23:27 +0200 (Sun, 17 Sep 2006) | 3 lines Tweak Mac/Makefile in to ensure that pythonw gets rebuild when the major version of python changes (2.5 -> 2.6). Bug #1552935. ........ r51913 | guido.van.rossum | 2006-09-18 23:36:16 +0200 (Mon, 18 Sep 2006) | 2 lines Make this thing executable. ........ r51920 | gregory.p.smith | 2006-09-19 19:35:04 +0200 (Tue, 19 Sep 2006) | 5 lines Fixes a bug with bsddb.DB.stat where the flags and txn keyword arguments are transposed. (reported by Louis Zechtzer) ..already committed to release24-maint ..needs committing to release25-maint ........ r51926 | brett.cannon | 2006-09-20 20:34:28 +0200 (Wed, 20 Sep 2006) | 3 lines Accidentally didn't commit Misc/NEWS entry on when __unicode__() was removed from exceptions. ........ r51927 | brett.cannon | 2006-09-20 20:43:13 +0200 (Wed, 20 Sep 2006) | 6 lines Allow exceptions to be directly sliced again (e.g., ``BaseException(1,2,3)[0:2]``). Discovered in Python 2.5.0 by Thomas Heller and reported to python-dev. This should be backported to 2.5 . ........ r51928 | brett.cannon | 2006-09-20 21:28:35 +0200 (Wed, 20 Sep 2006) | 2 lines Make python.vim output more deterministic. ........ r51949 | walter.doerwald | 2006-09-21 17:09:55 +0200 (Thu, 21 Sep 2006) | 2 lines Fix typo. ........ r51950 | jack.diederich | 2006-09-21 19:50:26 +0200 (Thu, 21 Sep 2006) | 5 lines * regression bug, count_next was coercing a Py_ssize_t to an unsigned Py_size_t which breaks negative counts * added test for negative numbers will backport to 2.5.1 ........ r51953 | jack.diederich | 2006-09-21 22:34:49 +0200 (Thu, 21 Sep 2006) | 1 line added itertools.count(-n) fix ........ r51971 | neal.norwitz | 2006-09-22 10:16:26 +0200 (Fri, 22 Sep 2006) | 10 lines Fix %zd string formatting on Mac OS X so it prints negative numbers. In addition to testing positive numbers, verify negative numbers work in configure. In order to avoid compiler warnings on OS X 10.4, also change the order of the check for the format character to use (PY_FORMAT_SIZE_T) in the sprintf format for Py_ssize_t. This patch changes PY_FORMAT_SIZE_T from "" to "l" if it wasn't defined at configure time. Need to verify the buildbot results. Backport candidate (if everyone thinks this patch can't be improved). ........ r51972 | neal.norwitz | 2006-09-22 10:18:10 +0200 (Fri, 22 Sep 2006) | 7 lines Bug #1557232: fix seg fault with def f((((x)))) and def f(((x),)). These tests should be improved. Hopefully this fixes variations when flipping back and forth between fpdef and fplist. Backport candidate. ........ r51975 | neal.norwitz | 2006-09-22 10:47:23 +0200 (Fri, 22 Sep 2006) | 4 lines Mostly revert this file to the same version as before. Only force setting of PY_FORMAT_SIZE_T to "l" for Mac OSX. I don't know a better define to use. This should get rid of the warnings on other platforms and Mac too. ........ r51986 | fred.drake | 2006-09-23 02:26:31 +0200 (Sat, 23 Sep 2006) | 1 line add boilerplate "What's New" document so the docs will build ........ r51987 | neal.norwitz | 2006-09-23 06:11:38 +0200 (Sat, 23 Sep 2006) | 1 line Remove extra semi-colons reported by Johnny Lee on python-dev. Backport if anyone cares. ........ r51989 | neal.norwitz | 2006-09-23 20:11:58 +0200 (Sat, 23 Sep 2006) | 1 line SF Bug #1563963, add missing word and cleanup first sentance ........ r51990 | brett.cannon | 2006-09-23 21:53:20 +0200 (Sat, 23 Sep 2006) | 3 lines Make output on test_strptime() be more verbose in face of failure. This is in hopes that more information will help debug the failing test on HPPA Ubuntu. ........ r51991 | georg.brandl | 2006-09-24 12:36:01 +0200 (Sun, 24 Sep 2006) | 2 lines Fix webbrowser.BackgroundBrowser on Windows. ........ r51993 | georg.brandl | 2006-09-24 14:35:36 +0200 (Sun, 24 Sep 2006) | 4 lines Fix a bug in the parser's future statement handling that led to "with" not being recognized as a keyword after, e.g., this statement: from __future__ import division, with_statement ........ r51995 | georg.brandl | 2006-09-24 14:50:24 +0200 (Sun, 24 Sep 2006) | 4 lines Fix a bug in traceback.format_exception_only() that led to an error being raised when print_exc() was called without an exception set. In version 2.4, this printed "None", restored that behavior. ........ r52000 | armin.rigo | 2006-09-25 17:16:26 +0200 (Mon, 25 Sep 2006) | 2 lines Another crasher. ........ r52011 | brett.cannon | 2006-09-27 01:38:24 +0200 (Wed, 27 Sep 2006) | 2 lines Make the error message for when the time data and format do not match clearer. ........ r52014 | andrew.kuchling | 2006-09-27 18:37:30 +0200 (Wed, 27 Sep 2006) | 1 line Add news item for rev. 51815 ........ r52018 | andrew.kuchling | 2006-09-27 21:23:05 +0200 (Wed, 27 Sep 2006) | 1 line Make examples do error checking on Py_InitModule ........ r52032 | brett.cannon | 2006-09-29 00:10:14 +0200 (Fri, 29 Sep 2006) | 2 lines Very minor grammatical fix in a comment. ........ r52048 | george.yoshida | 2006-09-30 07:14:02 +0200 (Sat, 30 Sep 2006) | 4 lines SF bug #1567976 : fix typo Will backport to 2.5. ........ r52051 | gregory.p.smith | 2006-09-30 08:08:20 +0200 (Sat, 30 Sep 2006) | 2 lines wording change ........ r52053 | georg.brandl | 2006-09-30 09:24:48 +0200 (Sat, 30 Sep 2006) | 2 lines Bug #1567375: a minor logical glitch in example description. ........ r52056 | georg.brandl | 2006-09-30 09:31:57 +0200 (Sat, 30 Sep 2006) | 3 lines Bug #1565661: in webbrowser, split() the command for the default GNOME browser in case it is a command with args. ........ r52058 | georg.brandl | 2006-09-30 10:43:30 +0200 (Sat, 30 Sep 2006) | 4 lines Patch #1567691: super() and new.instancemethod() now don't accept keyword arguments any more (previously they accepted them, but didn't use them). ........ r52061 | georg.brandl | 2006-09-30 11:03:42 +0200 (Sat, 30 Sep 2006) | 3 lines Bug #1566800: make sure that EnvironmentError can be called with any number of arguments, as was the case in Python 2.4. ........ r52063 | georg.brandl | 2006-09-30 11:06:45 +0200 (Sat, 30 Sep 2006) | 2 lines Bug #1566663: remove obsolete example from datetime docs. ........ r52065 | georg.brandl | 2006-09-30 11:13:21 +0200 (Sat, 30 Sep 2006) | 3 lines Bug #1566602: correct failure of posixpath unittest when $HOME ends with a slash. ........ r52068 | georg.brandl | 2006-09-30 12:58:01 +0200 (Sat, 30 Sep 2006) | 3 lines Bug #1457823: cgi.(Sv)FormContentDict's constructor now takes keep_blank_values and strict_parsing keyword arguments. ........ r52069 | georg.brandl | 2006-09-30 13:06:47 +0200 (Sat, 30 Sep 2006) | 3 lines Bug #1560617: in pyclbr, return full module name not only for classes, but also for functions. ........ r52072 | georg.brandl | 2006-09-30 13:17:34 +0200 (Sat, 30 Sep 2006) | 3 lines Bug #1556784: allow format strings longer than 127 characters in datetime's strftime function. ........ r52075 | georg.brandl | 2006-09-30 13:22:28 +0200 (Sat, 30 Sep 2006) | 3 lines Bug #1446043: correctly raise a LookupError if an encoding name given to encodings.search_function() contains a dot. ........ r52078 | georg.brandl | 2006-09-30 14:02:57 +0200 (Sat, 30 Sep 2006) | 3 lines Bug #1546052: clarify that PyString_FromString(AndSize) copies the string pointed to by its parameter. ........ r52080 | georg.brandl | 2006-09-30 14:16:03 +0200 (Sat, 30 Sep 2006) | 3 lines Convert test_import to unittest. ........ r52083 | kurt.kaiser | 2006-10-01 23:16:45 +0200 (Sun, 01 Oct 2006) | 5 lines Some syntax errors were being caught by tokenize during the tabnanny check, resulting in obscure error messages. Do the syntax check first. Bug 1562716, 1562719 ........ r52084 | kurt.kaiser | 2006-10-01 23:54:37 +0200 (Sun, 01 Oct 2006) | 3 lines Add comment explaining that error msgs may be due to user code when running w/o subprocess. ........ r52086 | martin.v.loewis | 2006-10-02 16:55:51 +0200 (Mon, 02 Oct 2006) | 3 lines Fix test for uintptr_t. Fixes #1568842. Will backport. ........ r52089 | martin.v.loewis | 2006-10-02 17:20:37 +0200 (Mon, 02 Oct 2006) | 3 lines Guard uintptr_t test with HAVE_STDINT_H, test for stdint.h. Will backport. ........ r52100 | vinay.sajip | 2006-10-03 20:02:37 +0200 (Tue, 03 Oct 2006) | 1 line Documentation omitted the additional parameter to LogRecord.__init__ which was added in 2.5. (See SF #1569622). ........ r52101 | vinay.sajip | 2006-10-03 20:20:26 +0200 (Tue, 03 Oct 2006) | 1 line Documentation clarified to mention optional parameters. ........ r52102 | vinay.sajip | 2006-10-03 20:21:56 +0200 (Tue, 03 Oct 2006) | 1 line Modified LogRecord.__init__ to make the func parameter optional. (See SF #1569622). ........ r52121 | brett.cannon | 2006-10-03 23:58:55 +0200 (Tue, 03 Oct 2006) | 2 lines Fix minor typo in a comment. ........ r52123 | brett.cannon | 2006-10-04 01:23:14 +0200 (Wed, 04 Oct 2006) | 2 lines Convert test_imp over to unittest. ........ r52128 | barry.warsaw | 2006-10-04 04:06:36 +0200 (Wed, 04 Oct 2006) | 3 lines decode_rfc2231(): As Christian Robottom Reis points out, it makes no sense to test for parts > 3 when we use .split(..., 2). ........ r52129 | jeremy.hylton | 2006-10-04 04:24:52 +0200 (Wed, 04 Oct 2006) | 9 lines Fix for SF bug 1569998: break permitted inside try. The compiler was checking that there was something on the fblock stack, but not that there was a loop on the stack. Fixed that and added a test for the specific syntax error. Bug fix candidate. ........ r52130 | martin.v.loewis | 2006-10-04 07:47:34 +0200 (Wed, 04 Oct 2006) | 4 lines Fix integer negation and absolute value to not rely on undefined behaviour of the C compiler anymore. Will backport to 2.5 and 2.4. ........ r52135 | martin.v.loewis | 2006-10-04 11:21:20 +0200 (Wed, 04 Oct 2006) | 1 line Forward port r52134: Add uuids for 2.4.4. ........ r52137 | armin.rigo | 2006-10-04 12:23:57 +0200 (Wed, 04 Oct 2006) | 3 lines Compilation problem caused by conflicting typedefs for uint32_t (unsigned long vs. unsigned int). ........ r52139 | armin.rigo | 2006-10-04 14:17:45 +0200 (Wed, 04 Oct 2006) | 23 lines Forward-port of r52136,52138: a review of overflow-detecting code. * unified the way intobject, longobject and mystrtoul handle values around -sys.maxint-1. * in general, trying to entierely avoid overflows in any computation involving signed ints or longs is extremely involved. Fixed a few simple cases where a compiler might be too clever (but that's all guesswork). * more overflow checks against bad data in marshal.c. * 2.5 specific: fixed a number of places that were still confusing int and Py_ssize_t. Some of them could potentially have caused "real-world" breakage. * list.pop(x): fixing overflow issues on x was messy. I just reverted to PyArg_ParseTuple("n"), which does the right thing. (An obscure test was trying to give a Decimal to list.pop()... doesn't make sense any more IMHO) * trying to write a few tests... ........ r52147 | andrew.kuchling | 2006-10-04 15:42:43 +0200 (Wed, 04 Oct 2006) | 6 lines Cause a PyObject_Malloc() failure to trigger a MemoryError, and then add 'if (PyErr_Occurred())' checks to various places so that NULL is returned properly. 2.4 backport candidate. ........ r52148 | martin.v.loewis | 2006-10-04 17:25:28 +0200 (Wed, 04 Oct 2006) | 1 line Add MSVC8 project files to create wininst-8.exe. ........ r52196 | brett.cannon | 2006-10-06 00:02:31 +0200 (Fri, 06 Oct 2006) | 7 lines Clarify what "re-initialization" means for init_builtin() and init_dynamic(). Also remove warning about re-initialization as possibly raising an execption as both call _PyImport_FindExtension() which pulls any module that was already imported from the Python process' extension cache and just copies the __dict__ into the module stored in sys.modules. ........ r52200 | fred.drake | 2006-10-06 02:03:45 +0200 (Fri, 06 Oct 2006) | 3 lines - update links - remove Sleepycat name now that they have been bought ........ r52204 | andrew.kuchling | 2006-10-06 12:41:01 +0200 (Fri, 06 Oct 2006) | 1 line Case fix ........ r52208 | georg.brandl | 2006-10-06 14:46:08 +0200 (Fri, 06 Oct 2006) | 3 lines Fix name. ........ r52211 | andrew.kuchling | 2006-10-06 15:18:26 +0200 (Fri, 06 Oct 2006) | 1 line [Bug #1545341] Allow 'classifier' parameter to be a tuple as well as a list. Will backport. ........ r52212 | armin.rigo | 2006-10-06 18:33:22 +0200 (Fri, 06 Oct 2006) | 4 lines A very minor bug fix: this code looks like it is designed to accept any hue value and do the modulo itself, except it doesn't quite do it in all cases. At least, the "cannot get here" comment was wrong. ........ r52213 | andrew.kuchling | 2006-10-06 20:51:55 +0200 (Fri, 06 Oct 2006) | 1 line Comment grammar ........ r52218 | skip.montanaro | 2006-10-07 13:05:02 +0200 (Sat, 07 Oct 2006) | 6 lines Note that the excel_tab class is registered as the "excel-tab" dialect. Fixes 1572471. Make a similar change for the excel class and clean up references to the Dialects and Formatting Parameters section in a few places. ........ r52221 | georg.brandl | 2006-10-08 09:11:54 +0200 (Sun, 08 Oct 2006) | 3 lines Add missing NEWS entry for rev. 52129. ........ r52223 | hyeshik.chang | 2006-10-08 15:48:34 +0200 (Sun, 08 Oct 2006) | 3 lines Bug #1572832: fix a bug in ISO-2022 codecs which may cause segfault when encoding non-BMP unicode characters. (Submitted by Ray Chason) ........ r52227 | ronald.oussoren | 2006-10-08 19:37:58 +0200 (Sun, 08 Oct 2006) | 4 lines Add version number to the link to the python documentation in /Developer/Documentation/Python, better for users that install multiple versions of python. ........ r52229 | ronald.oussoren | 2006-10-08 19:40:02 +0200 (Sun, 08 Oct 2006) | 2 lines Fix for bug #1570284 ........ r52233 | ronald.oussoren | 2006-10-08 19:49:52 +0200 (Sun, 08 Oct 2006) | 6 lines MacOSX: distutils changes the values of BASECFLAGS and LDFLAGS when using a universal build of python on OSX 10.3 to ensure that those flags can be used to compile code (the universal build uses compiler flags that aren't supported on 10.3). This patches gives the same treatment to CFLAGS, PY_CFLAGS and BLDSHARED. ........ r52236 | ronald.oussoren | 2006-10-08 19:51:46 +0200 (Sun, 08 Oct 2006) | 5 lines MacOSX: The universal build requires that users have the MacOSX10.4u SDK installed to build extensions. This patch makes distutils emit a warning when the compiler should use an SDK but that SDK is not installed, hopefully reducing some confusion. ........ r52238 | ronald.oussoren | 2006-10-08 20:18:26 +0200 (Sun, 08 Oct 2006) | 3 lines MacOSX: add more logic to recognize the correct startup file to patch to the shell profile patching post-install script. ........ r52242 | andrew.kuchling | 2006-10-09 19:10:12 +0200 (Mon, 09 Oct 2006) | 1 line Add news item for rev. 52211 change ........ r52245 | andrew.kuchling | 2006-10-09 20:05:19 +0200 (Mon, 09 Oct 2006) | 1 line Fix wording in comment ........ r52251 | georg.brandl | 2006-10-09 21:03:06 +0200 (Mon, 09 Oct 2006) | 2 lines Patch #1572724: fix typo ('=' instead of '==') in _msi.c. ........ r52255 | barry.warsaw | 2006-10-09 21:43:24 +0200 (Mon, 09 Oct 2006) | 2 lines List gc.get_count() in the module docstring. ........ r52257 | martin.v.loewis | 2006-10-09 22:44:25 +0200 (Mon, 09 Oct 2006) | 1 line Bug #1565150: Fix subsecond processing for os.utime on Windows. ........ r52268 | ronald.oussoren | 2006-10-10 09:55:06 +0200 (Tue, 10 Oct 2006) | 2 lines MacOSX: fix permission problem in the generated installer ........ r52293 | georg.brandl | 2006-10-12 09:38:04 +0200 (Thu, 12 Oct 2006) | 2 lines Bug #1575746: fix typo in property() docs. ........ r52295 | georg.brandl | 2006-10-12 09:57:21 +0200 (Thu, 12 Oct 2006) | 3 lines Bug #813342: Start the IDLE subprocess with -Qnew if the parent is started with that option. ........ r52297 | georg.brandl | 2006-10-12 10:22:53 +0200 (Thu, 12 Oct 2006) | 2 lines Bug #1565919: document set types in the Language Reference. ........ r52299 | georg.brandl | 2006-10-12 11:20:33 +0200 (Thu, 12 Oct 2006) | 3 lines Bug #1550524: better heuristics to find correct class definition in inspect.findsource(). ........ r52301 | georg.brandl | 2006-10-12 11:47:12 +0200 (Thu, 12 Oct 2006) | 4 lines Bug #1548891: The cStringIO.StringIO() constructor now encodes unicode arguments with the system default encoding just like the write() method does, instead of converting it to a raw buffer. ........ r52303 | georg.brandl | 2006-10-12 13:14:40 +0200 (Thu, 12 Oct 2006) | 2 lines Bug #1546628: add a note about urlparse.urljoin() and absolute paths. ........ r52305 | georg.brandl | 2006-10-12 13:27:59 +0200 (Thu, 12 Oct 2006) | 3 lines Bug #1545497: when given an explicit base, int() did ignore NULs embedded in the string to convert. ........ r52307 | georg.brandl | 2006-10-12 13:41:11 +0200 (Thu, 12 Oct 2006) | 3 lines Add a note to fpectl docs that it's not built by default (bug #1556261). ........ r52309 | georg.brandl | 2006-10-12 13:46:57 +0200 (Thu, 12 Oct 2006) | 3 lines Bug #1560114: the Mac filesystem does have accurate information about the case of filenames. ........ r52311 | georg.brandl | 2006-10-12 13:59:27 +0200 (Thu, 12 Oct 2006) | 2 lines Small grammar fix, thanks Sjoerd. ........ r52313 | georg.brandl | 2006-10-12 14:03:07 +0200 (Thu, 12 Oct 2006) | 2 lines Fix tarfile depending on buggy int('1\0', base) behavior. ........ r52315 | georg.brandl | 2006-10-12 14:33:07 +0200 (Thu, 12 Oct 2006) | 2 lines Bug #1283491: follow docstring convention wrt. keyword-able args in sum(). ........ r52316 | georg.brandl | 2006-10-12 15:08:16 +0200 (Thu, 12 Oct 2006) | 3 lines Bug #1560179: speed up posixpath.(dir|base)name ........ r52327 | brett.cannon | 2006-10-14 08:36:45 +0200 (Sat, 14 Oct 2006) | 3 lines Clean up the language of a sentence relating to the connect() function and user-defined datatypes. ........ r52332 | neal.norwitz | 2006-10-14 23:33:38 +0200 (Sat, 14 Oct 2006) | 3 lines Update the peephole optimizer to remove more dead code (jumps after returns) and inline jumps to returns. ........ r52333 | martin.v.loewis | 2006-10-15 09:54:40 +0200 (Sun, 15 Oct 2006) | 4 lines Patch #1576954: Update VC6 build directory; remove redundant files in VC7. Will backport to 2.5. ........ r52335 | martin.v.loewis | 2006-10-15 10:43:33 +0200 (Sun, 15 Oct 2006) | 1 line Patch #1576166: Support os.utime for directories on Windows NT+. ........ r52336 | martin.v.loewis | 2006-10-15 10:51:22 +0200 (Sun, 15 Oct 2006) | 2 lines Patch #1577551: Add ctypes and ET build support for VC6. Will backport to 2.5. ........ r52338 | martin.v.loewis | 2006-10-15 11:35:51 +0200 (Sun, 15 Oct 2006) | 1 line Loosen the test for equal time stamps. ........ r52339 | martin.v.loewis | 2006-10-15 11:43:39 +0200 (Sun, 15 Oct 2006) | 2 lines Bug #1567666: Emulate GetFileAttributesExA for Win95. Will backport to 2.5. ........ r52341 | martin.v.loewis | 2006-10-15 13:02:07 +0200 (Sun, 15 Oct 2006) | 2 lines Round to int, because some systems support sub-second time stamps in stat, but not in utime. Also be consistent with modifying only mtime, not atime. ........ r52342 | martin.v.loewis | 2006-10-15 13:57:40 +0200 (Sun, 15 Oct 2006) | 2 lines Set the eol-style for project files to "CRLF". ........ r52343 | martin.v.loewis | 2006-10-15 13:59:56 +0200 (Sun, 15 Oct 2006) | 3 lines Drop binary property on dsp files, set eol-style to CRLF instead. ........ r52344 | martin.v.loewis | 2006-10-15 14:01:43 +0200 (Sun, 15 Oct 2006) | 2 lines Remove binary property, set eol-style to CRLF instead. ........ r52346 | martin.v.loewis | 2006-10-15 16:30:38 +0200 (Sun, 15 Oct 2006) | 2 lines Mention the bdist_msi module. Will backport to 2.5. ........ r52354 | brett.cannon | 2006-10-16 05:09:52 +0200 (Mon, 16 Oct 2006) | 3 lines Fix turtle so that you can launch the demo2 function on its own instead of only when the module is launched as a script. ........ r52356 | martin.v.loewis | 2006-10-17 17:18:06 +0200 (Tue, 17 Oct 2006) | 2 lines Patch #1457736: Update VC6 to use current PCbuild settings. Will backport to 2.5. ........ r52360 | martin.v.loewis | 2006-10-17 20:09:55 +0200 (Tue, 17 Oct 2006) | 2 lines Remove obsolete file. Will backport. ........ r52363 | martin.v.loewis | 2006-10-17 20:59:23 +0200 (Tue, 17 Oct 2006) | 4 lines Forward-port r52358: - Bug #1578513: Cross compilation was broken by a change to configure. Repair so that it's back to how it was in 2.4.3. ........ r52365 | thomas.heller | 2006-10-17 21:30:48 +0200 (Tue, 17 Oct 2006) | 6 lines ctypes callback functions only support 'fundamental' result types. Check this and raise an error when something else is used - before this change ctypes would hang or crash when such a callback was called. This is a partial fix for #1574584. Will backport to release25-maint. ........ r52377 | tim.peters | 2006-10-18 07:06:06 +0200 (Wed, 18 Oct 2006) | 2 lines newIobject(): repaired incorrect cast to quiet MSVC warning. ........ r52378 | tim.peters | 2006-10-18 07:09:12 +0200 (Wed, 18 Oct 2006) | 2 lines Whitespace normalization. ........ r52379 | tim.peters | 2006-10-18 07:10:28 +0200 (Wed, 18 Oct 2006) | 2 lines Add missing svn:eol-style to text files. ........ r52387 | martin.v.loewis | 2006-10-19 12:58:46 +0200 (Thu, 19 Oct 2006) | 3 lines Add check for the PyArg_ParseTuple format, and declare it if it is supported. ........ r52388 | martin.v.loewis | 2006-10-19 13:00:37 +0200 (Thu, 19 Oct 2006) | 3 lines Fix various minor errors in passing arguments to PyArg_ParseTuple. ........ r52389 | martin.v.loewis | 2006-10-19 18:01:37 +0200 (Thu, 19 Oct 2006) | 2 lines Restore CFLAGS after checking for __attribute__ ........ r52390 | andrew.kuchling | 2006-10-19 23:55:55 +0200 (Thu, 19 Oct 2006) | 1 line [Bug #1576348] Fix typo in example ........ r52414 | walter.doerwald | 2006-10-22 10:59:41 +0200 (Sun, 22 Oct 2006) | 2 lines Port test___future__ to unittest. ........ r52415 | ronald.oussoren | 2006-10-22 12:45:18 +0200 (Sun, 22 Oct 2006) | 3 lines Patch #1580674: with this patch os.readlink uses the filesystem encoding to decode unicode objects and returns an unicode object when the argument is one. ........ r52416 | martin.v.loewis | 2006-10-22 12:46:18 +0200 (Sun, 22 Oct 2006) | 3 lines Patch #1580872: Remove duplicate declaration of PyCallable_Check. Will backport to 2.5. ........ r52418 | martin.v.loewis | 2006-10-22 12:55:15 +0200 (Sun, 22 Oct 2006) | 4 lines - Patch #1560695: Add .note.GNU-stack to ctypes' sysv.S so that ctypes isn't considered as requiring executable stacks. Will backport to 2.5. ........ r52420 | martin.v.loewis | 2006-10-22 15:45:13 +0200 (Sun, 22 Oct 2006) | 3 lines Remove passwd.adjunct.byname from list of maps for test_nis. Will backport to 2.5. ........ r52431 | georg.brandl | 2006-10-24 18:54:16 +0200 (Tue, 24 Oct 2006) | 2 lines Patch [ 1583506 ] tarfile.py: 100-char filenames are truncated ........ r52446 | andrew.kuchling | 2006-10-26 21:10:46 +0200 (Thu, 26 Oct 2006) | 1 line [Bug #1579796] Wrong syntax for PyDateTime_IMPORT in documentation. Reported by David Faure. ........ r52449 | andrew.kuchling | 2006-10-26 21:16:46 +0200 (Thu, 26 Oct 2006) | 1 line Typo fix ........ r52452 | martin.v.loewis | 2006-10-27 08:16:31 +0200 (Fri, 27 Oct 2006) | 3 lines Patch #1549049: Rewrite type conversion in structmember. Fixes #1545696 and #1566140. Will backport to 2.5. ........ r52454 | martin.v.loewis | 2006-10-27 08:42:27 +0200 (Fri, 27 Oct 2006) | 2 lines Check for values.h. Will backport. ........ r52456 | martin.v.loewis | 2006-10-27 09:06:52 +0200 (Fri, 27 Oct 2006) | 2 lines Get DBL_MAX from float.h not values.h. Will backport. ........ r52458 | martin.v.loewis | 2006-10-27 09:13:28 +0200 (Fri, 27 Oct 2006) | 2 lines Patch #1567274: Support SMTP over TLS. ........ r52459 | andrew.kuchling | 2006-10-27 13:33:29 +0200 (Fri, 27 Oct 2006) | 1 line Set svn:keywords property ........ r52460 | andrew.kuchling | 2006-10-27 13:36:41 +0200 (Fri, 27 Oct 2006) | 1 line Add item ........ r52461 | andrew.kuchling | 2006-10-27 13:37:01 +0200 (Fri, 27 Oct 2006) | 1 line Some wording changes and markup fixes ........ r52462 | andrew.kuchling | 2006-10-27 14:18:38 +0200 (Fri, 27 Oct 2006) | 1 line [Bug #1585690] Note that line_num was added in Python 2.5 ........ r52464 | andrew.kuchling | 2006-10-27 14:50:38 +0200 (Fri, 27 Oct 2006) | 1 line [Bug #1583946] Reword description of server and issuer ........ r52466 | andrew.kuchling | 2006-10-27 15:06:25 +0200 (Fri, 27 Oct 2006) | 1 line [Bug #1562583] Mention the set_reuse_addr() method ........ r52469 | andrew.kuchling | 2006-10-27 15:22:46 +0200 (Fri, 27 Oct 2006) | 4 lines [Bug #1542016] Report PCALL_POP value. This makes the return value of sys.callstats() match its docstring. Backport candidate. Though it's an API change, this is a pretty obscure portion of the API. ........ r52473 | andrew.kuchling | 2006-10-27 16:53:41 +0200 (Fri, 27 Oct 2006) | 1 line Point users to the subprocess module in the docs for os.system, os.spawn*, os.popen2, and the popen2 and commands modules ........ r52476 | andrew.kuchling | 2006-10-27 18:39:10 +0200 (Fri, 27 Oct 2006) | 1 line [Bug #1576241] Let functools.wraps work with built-in functions ........ r52478 | andrew.kuchling | 2006-10-27 18:55:34 +0200 (Fri, 27 Oct 2006) | 1 line [Bug #1575506] The _singlefileMailbox class was using the wrong file object in its flush() method, causing an error ........ r52480 | andrew.kuchling | 2006-10-27 19:06:16 +0200 (Fri, 27 Oct 2006) | 1 line Clarify docstring ........ r52481 | andrew.kuchling | 2006-10-27 19:11:23 +0200 (Fri, 27 Oct 2006) | 5 lines [Patch #1574068 by Scott Dial] urllib and urllib2 were using base64.encodestring() for encoding authentication data. encodestring() can include newlines for very long input, which produced broken HTTP headers. ........ r52483 | andrew.kuchling | 2006-10-27 20:13:46 +0200 (Fri, 27 Oct 2006) | 1 line Check db_setup_debug for a few print statements; change sqlite_setup_debug to False ........ r52484 | andrew.kuchling | 2006-10-27 20:15:02 +0200 (Fri, 27 Oct 2006) | 1 line [Patch #1503717] Tiny patch from Chris AtLee to stop a lengthy line from being printed ........ r52485 | thomas.heller | 2006-10-27 20:31:36 +0200 (Fri, 27 Oct 2006) | 5 lines WindowsError.str should display the windows error code, not the posix error code; with test. Fixes #1576174. Will backport to release25-maint. ........ r52487 | thomas.heller | 2006-10-27 21:05:53 +0200 (Fri, 27 Oct 2006) | 4 lines Modulefinder now handles absolute and relative imports, including tests. Will backport to release25-maint. ........ r52488 | georg.brandl | 2006-10-27 22:39:43 +0200 (Fri, 27 Oct 2006) | 2 lines Patch #1552024: add decorator support to unparse.py demo script. ........ r52492 | walter.doerwald | 2006-10-28 12:47:12 +0200 (Sat, 28 Oct 2006) | 2 lines Port test_bufio to unittest. ........ r52493 | georg.brandl | 2006-10-28 15:10:17 +0200 (Sat, 28 Oct 2006) | 6 lines Convert test_global, test_scope and test_grammar to unittest. I tried to enclose all tests which must be run at the toplevel (instead of inside a method) in exec statements. ........ r52494 | georg.brandl | 2006-10-28 15:11:41 +0200 (Sat, 28 Oct 2006) | 3 lines Update outstanding bugs test file. ........ r52495 | georg.brandl | 2006-10-28 15:51:49 +0200 (Sat, 28 Oct 2006) | 3 lines Convert test_math to unittest. ........ r52496 | georg.brandl | 2006-10-28 15:56:58 +0200 (Sat, 28 Oct 2006) | 3 lines Convert test_opcodes to unittest. ........ r52497 | georg.brandl | 2006-10-28 18:04:04 +0200 (Sat, 28 Oct 2006) | 2 lines Fix nth() itertool recipe. ........ r52500 | georg.brandl | 2006-10-28 22:25:09 +0200 (Sat, 28 Oct 2006) | 2 lines make test_grammar pass with python -O ........ r52501 | neal.norwitz | 2006-10-28 23:15:30 +0200 (Sat, 28 Oct 2006) | 6 lines Add some asserts. In sysmodule, I think these were to try to silence some warnings from Klokwork. They verify the assumptions of the format of svn version output. The assert in the thread module helped debug a problem on HP-UX. ........ r52502 | neal.norwitz | 2006-10-28 23:16:54 +0200 (Sat, 28 Oct 2006) | 5 lines Fix warnings with HP's C compiler. It doesn't recognize that infinite loops are, um, infinite. These conditions should not be able to happen. Will backport. ........ r52503 | neal.norwitz | 2006-10-28 23:17:51 +0200 (Sat, 28 Oct 2006) | 5 lines Fix crash in test on HP-UX. Apparently, it's not possible to delete a lock if it's held (even by the current thread). Will backport. ........ r52504 | neal.norwitz | 2006-10-28 23:19:07 +0200 (Sat, 28 Oct 2006) | 6 lines Fix bug #1565514, SystemError not raised on too many nested blocks. It seems like this should be a different error than SystemError, but I don't have any great ideas and SystemError was raised in 2.4 and earlier. Will backport. ........ r52505 | neal.norwitz | 2006-10-28 23:20:12 +0200 (Sat, 28 Oct 2006) | 4 lines Prevent crash if alloc of garbage fails. Found by Typo.pl. Will backport. ........ r52506 | neal.norwitz | 2006-10-28 23:21:00 +0200 (Sat, 28 Oct 2006) | 4 lines Don't inline Py_ADDRESS_IN_RANGE with gcc 4+ either. Will backport. ........ r52513 | neal.norwitz | 2006-10-28 23:56:49 +0200 (Sat, 28 Oct 2006) | 2 lines Fix test_modulefinder so it doesn't fail when run after test_distutils. ........ r52514 | neal.norwitz | 2006-10-29 00:12:26 +0200 (Sun, 29 Oct 2006) | 4 lines From SF 1557890, fix problem of using wrong type in example. Will backport. ........ r52517 | georg.brandl | 2006-10-29 09:39:22 +0100 (Sun, 29 Oct 2006) | 4 lines Fix codecs.EncodedFile which did not use file_encoding in 2.5.0, and fix all codecs file wrappers to work correctly with the "with" statement (bug #1586513). ........ r52519 | georg.brandl | 2006-10-29 09:47:08 +0100 (Sun, 29 Oct 2006) | 3 lines Clean up a leftover from old listcomp generation code. ........ r52520 | georg.brandl | 2006-10-29 09:53:06 +0100 (Sun, 29 Oct 2006) | 4 lines Bug #1586448: the compiler module now emits the same bytecode for list comprehensions as the builtin compiler, using the LIST_APPEND opcode. ........ r52521 | georg.brandl | 2006-10-29 10:01:01 +0100 (Sun, 29 Oct 2006) | 3 lines Remove trailing comma. ........ r52522 | georg.brandl | 2006-10-29 10:05:04 +0100 (Sun, 29 Oct 2006) | 3 lines Bug #1357915: allow all sequence types for shell arguments in subprocess. ........ r52524 | georg.brandl | 2006-10-29 10:16:12 +0100 (Sun, 29 Oct 2006) | 3 lines Patch #1583880: fix tarfile's problems with long names and posix/ GNU modes. ........ r52526 | georg.brandl | 2006-10-29 10:18:00 +0100 (Sun, 29 Oct 2006) | 3 lines Test assert if __debug__ is true. ........ r52527 | georg.brandl | 2006-10-29 10:32:16 +0100 (Sun, 29 Oct 2006) | 2 lines Fix the new EncodedFile test to work with big endian platforms. ........ r52529 | georg.brandl | 2006-10-29 15:39:09 +0100 (Sun, 29 Oct 2006) | 2 lines Bug #1586613: fix zlib and bz2 codecs' incremental en/decoders. ........ r52532 | georg.brandl | 2006-10-29 19:01:08 +0100 (Sun, 29 Oct 2006) | 2 lines Bug #1586773: extend hashlib docstring. ........ r52534 | neal.norwitz | 2006-10-29 19:30:10 +0100 (Sun, 29 Oct 2006) | 4 lines Update comments, remove commented out code. Move assembler structure next to assembler code to make it easier to move it to a separate file. ........ r52535 | georg.brandl | 2006-10-29 19:31:42 +0100 (Sun, 29 Oct 2006) | 3 lines Bug #1576657: when setting a KeyError for a tuple key, make sure that the tuple isn't used as the "exception arguments tuple". ........ r52537 | georg.brandl | 2006-10-29 20:13:40 +0100 (Sun, 29 Oct 2006) | 3 lines Convert test_mmap to unittest. ........ r52538 | georg.brandl | 2006-10-29 20:20:45 +0100 (Sun, 29 Oct 2006) | 3 lines Convert test_poll to unittest. ........ r52539 | georg.brandl | 2006-10-29 20:24:43 +0100 (Sun, 29 Oct 2006) | 3 lines Convert test_nis to unittest. ........ r52540 | georg.brandl | 2006-10-29 20:35:03 +0100 (Sun, 29 Oct 2006) | 3 lines Convert test_types to unittest. ........ r52541 | georg.brandl | 2006-10-29 20:51:16 +0100 (Sun, 29 Oct 2006) | 3 lines Convert test_cookie to unittest. ........ r52542 | georg.brandl | 2006-10-29 21:09:12 +0100 (Sun, 29 Oct 2006) | 3 lines Convert test_cgi to unittest. ........ r52543 | georg.brandl | 2006-10-29 21:24:01 +0100 (Sun, 29 Oct 2006) | 3 lines Completely convert test_httplib to unittest. ........ r52544 | georg.brandl | 2006-10-29 21:28:26 +0100 (Sun, 29 Oct 2006) | 2 lines Convert test_MimeWriter to unittest. ........ r52545 | georg.brandl | 2006-10-29 21:31:17 +0100 (Sun, 29 Oct 2006) | 3 lines Convert test_openpty to unittest. ........ r52546 | georg.brandl | 2006-10-29 21:35:12 +0100 (Sun, 29 Oct 2006) | 3 lines Remove leftover test output file. ........ r52547 | georg.brandl | 2006-10-29 22:54:18 +0100 (Sun, 29 Oct 2006) | 3 lines Move the check for openpty to the beginning. ........ r52548 | walter.doerwald | 2006-10-29 23:06:28 +0100 (Sun, 29 Oct 2006) | 2 lines Add tests for basic argument errors. ........ r52549 | walter.doerwald | 2006-10-30 00:02:27 +0100 (Mon, 30 Oct 2006) | 3 lines Add tests for incremental codecs with an errors argument. ........ r52550 | neal.norwitz | 2006-10-30 00:39:03 +0100 (Mon, 30 Oct 2006) | 1 line Fix refleak ........ r52552 | neal.norwitz | 2006-10-30 00:58:36 +0100 (Mon, 30 Oct 2006) | 1 line I'm assuming this is correct, it fixes the tests so they pass again ........ r52555 | vinay.sajip | 2006-10-31 18:32:37 +0100 (Tue, 31 Oct 2006) | 1 line Change to improve speed of _fixupChildren ........ r52556 | vinay.sajip | 2006-10-31 18:34:31 +0100 (Tue, 31 Oct 2006) | 1 line Added relativeCreated to Formatter doc (has been in the system for a long time - was unaccountably left out of the docs and not noticed until now). ........ r52588 | thomas.heller | 2006-11-02 20:48:24 +0100 (Thu, 02 Nov 2006) | 5 lines Replace the XXX marker in the 'Arrays and pointers' reference manual section with a link to the tutorial sections. Will backport to release25-maint. ........ r52592 | thomas.heller | 2006-11-02 21:22:29 +0100 (Thu, 02 Nov 2006) | 6 lines Fix a code example by adding a missing import. Fixes #1557890. Will backport to release25-maint. ........ r52598 | tim.peters | 2006-11-03 03:32:46 +0100 (Fri, 03 Nov 2006) | 2 lines Whitespace normalization. ........ r52619 | martin.v.loewis | 2006-11-04 19:14:06 +0100 (Sat, 04 Nov 2006) | 4 lines - Patch #1060577: Extract list of RPM files from spec file in bdist_rpm Will backport to 2.5. ........ r52621 | neal.norwitz | 2006-11-04 20:25:22 +0100 (Sat, 04 Nov 2006) | 4 lines Bug #1588287: fix invalid assertion for `1,2` in debug builds. Will backport ........ r52630 | andrew.kuchling | 2006-11-05 22:04:37 +0100 (Sun, 05 Nov 2006) | 1 line Update link ........ r52631 | skip.montanaro | 2006-11-06 15:34:52 +0100 (Mon, 06 Nov 2006) | 1 line note that user can control directory location even if default dir is used ........ r52644 | ronald.oussoren | 2006-11-07 16:53:38 +0100 (Tue, 07 Nov 2006) | 2 lines Fix a number of typos in strings and comments (sf#1589070) ........ r52647 | ronald.oussoren | 2006-11-07 17:00:34 +0100 (Tue, 07 Nov 2006) | 2 lines Whitespace changes to make the source more compliant with PEP8 (SF#1589070) ........ r52651 | thomas.heller | 2006-11-07 19:01:18 +0100 (Tue, 07 Nov 2006) | 3 lines Fix markup. Will backport to release25-maint. ........ r52653 | thomas.heller | 2006-11-07 19:20:47 +0100 (Tue, 07 Nov 2006) | 3 lines Fix grammatical error as well. Will backport to release25-maint. ........ r52657 | andrew.kuchling | 2006-11-07 21:39:16 +0100 (Tue, 07 Nov 2006) | 1 line Add missing word ........ r52662 | martin.v.loewis | 2006-11-08 07:46:37 +0100 (Wed, 08 Nov 2006) | 4 lines Correctly forward exception in instance_contains(). Fixes #1591996. Patch contributed by Neal Norwitz. Will backport. ........ r52664 | martin.v.loewis | 2006-11-08 07:48:36 +0100 (Wed, 08 Nov 2006) | 2 lines News entry for 52662. ........ r52665 | martin.v.loewis | 2006-11-08 08:35:55 +0100 (Wed, 08 Nov 2006) | 2 lines Patch #1351744: Add askyesnocancel helper for tkMessageBox. ........ r52666 | georg.brandl | 2006-11-08 08:45:59 +0100 (Wed, 08 Nov 2006) | 2 lines Patch #1592072: fix docs for return value of PyErr_CheckSignals. ........ r52668 | georg.brandl | 2006-11-08 11:04:29 +0100 (Wed, 08 Nov 2006) | 3 lines Bug #1592533: rename variable in heapq doc example, to avoid shadowing "sorted". ........ r52671 | andrew.kuchling | 2006-11-08 14:35:34 +0100 (Wed, 08 Nov 2006) | 1 line Add section on the functional module ........ r52672 | andrew.kuchling | 2006-11-08 15:14:30 +0100 (Wed, 08 Nov 2006) | 1 line Add section on operator module; make a few edits ........ r52673 | andrew.kuchling | 2006-11-08 15:24:03 +0100 (Wed, 08 Nov 2006) | 1 line Add table of contents; this required fixing a few headings. Some more smalle edits. ........ r52674 | andrew.kuchling | 2006-11-08 15:30:14 +0100 (Wed, 08 Nov 2006) | 1 line More edits ........ r52686 | martin.v.loewis | 2006-11-09 12:06:03 +0100 (Thu, 09 Nov 2006) | 3 lines Patch #838546: Make terminal become controlling in pty.fork(). Will backport to 2.5. ........ r52688 | martin.v.loewis | 2006-11-09 12:27:32 +0100 (Thu, 09 Nov 2006) | 2 lines Patch #1592250: Add elidge argument to Tkinter.Text.search. ........ r52690 | andrew.kuchling | 2006-11-09 14:27:07 +0100 (Thu, 09 Nov 2006) | 7 lines [Bug #1569790] mailbox.Maildir.get_folder() loses factory information Both the Maildir and MH classes had this bug; the patch fixes both classes and adds a test. Will backport to 25-maint. ........ r52692 | andrew.kuchling | 2006-11-09 14:51:14 +0100 (Thu, 09 Nov 2006) | 1 line [Patch #1514544 by David Watson] use fsync() to ensure data is really on disk ........ r52695 | walter.doerwald | 2006-11-09 17:23:26 +0100 (Thu, 09 Nov 2006) | 2 lines Replace C++ comment with C comment (fixes SF bug #1593525). ........ r52712 | andrew.kuchling | 2006-11-09 22:16:46 +0100 (Thu, 09 Nov 2006) | 11 lines [Patch #1514543] mailbox (Maildir): avoid losing messages on name clash Two changes: Where possible, use link()/remove() to move files into a directory; this makes it easier to avoid overwriting an existing file. Use _create_carefully() to create files in tmp/, which uses O_EXCL. Backport candidate. ........ r52716 | phillip.eby | 2006-11-10 01:33:36 +0100 (Fri, 10 Nov 2006) | 4 lines Fix SF#1566719: not creating site-packages (or other target directory) when installing .egg-info for a project that contains no modules or packages, while using --root (as in bdist_rpm). ........ r52719 | andrew.kuchling | 2006-11-10 14:14:01 +0100 (Fri, 10 Nov 2006) | 1 line Reword entry ........ r52725 | andrew.kuchling | 2006-11-10 15:39:01 +0100 (Fri, 10 Nov 2006) | 1 line [Feature request #1542920] Link to wsgi.org ........ r52731 | georg.brandl | 2006-11-11 19:29:11 +0100 (Sat, 11 Nov 2006) | 2 lines Bug #1594742: wrong word in stringobject doc. ........ r52733 | georg.brandl | 2006-11-11 19:32:47 +0100 (Sat, 11 Nov 2006) | 2 lines Bug #1594758: wording improvement for dict.update() docs. ........ r52736 | martin.v.loewis | 2006-11-12 11:32:47 +0100 (Sun, 12 Nov 2006) | 3 lines Patch #1065257: Support passing open files as body in HTTPConnection.request(). ........ r52737 | martin.v.loewis | 2006-11-12 11:41:39 +0100 (Sun, 12 Nov 2006) | 2 lines Patch #1355023: support whence argument for GzipFile.seek. ........ r52738 | martin.v.loewis | 2006-11-12 19:24:26 +0100 (Sun, 12 Nov 2006) | 2 lines Bug #1067760: Deprecate passing floats to file.seek. ........ r52739 | martin.v.loewis | 2006-11-12 19:48:13 +0100 (Sun, 12 Nov 2006) | 3 lines Patch #1359217: Ignore 2xx response before 150 response. Will backport to 2.5. ........ r52741 | martin.v.loewis | 2006-11-12 19:56:03 +0100 (Sun, 12 Nov 2006) | 4 lines Patch #1360200: Use unmangled_version RPM spec field to deal with file name mangling. Will backport to 2.5. ........ r52753 | walter.doerwald | 2006-11-15 17:23:46 +0100 (Wed, 15 Nov 2006) | 2 lines Fix typo. ........ r52754 | georg.brandl | 2006-11-15 18:42:03 +0100 (Wed, 15 Nov 2006) | 2 lines Bug #1594809: add a note to README regarding PYTHONPATH and make install. ........ r52762 | georg.brandl | 2006-11-16 16:05:14 +0100 (Thu, 16 Nov 2006) | 2 lines Bug #1597576: mention that the new base64 api has been introduced in py2.4. ........ r52764 | georg.brandl | 2006-11-16 17:50:59 +0100 (Thu, 16 Nov 2006) | 3 lines Bug #1597824: return the registered function from atexit.register() to facilitate usage as a decorator. ........ r52765 | georg.brandl | 2006-11-16 18:08:45 +0100 (Thu, 16 Nov 2006) | 4 lines Bug #1588217: don't parse "= " as a soft line break in binascii's a2b_qp() function, instead leave it in the string as quopri.decode() does. ........ r52776 | andrew.kuchling | 2006-11-17 14:30:25 +0100 (Fri, 17 Nov 2006) | 17 lines Remove file-locking in MH.pack() method. This change looks massive but it's mostly a re-indenting after removing some try...finally blocks. Also adds a test case that does a pack() while the mailbox is locked; this test would have turned up bugs in the original code on some platforms. In both nmh and GNU Mailutils' implementation of MH-format mailboxes, no locking is done of individual message files when renaming them. The original mailbox.py code did do locking, which meant that message files had to be opened. This code was buggy on certain platforms (found through reading the code); there were code paths that closed the file object and then called _unlock_file() on it. Will backport to 25-maint once I see how the buildbots react to this patch. ........ r52780 | martin.v.loewis | 2006-11-18 19:00:23 +0100 (Sat, 18 Nov 2006) | 5 lines Patch #1538878: Don't make tkSimpleDialog dialogs transient if the parent window is withdrawn. This mirrors what dialog.tcl does. Will backport to 2.5. ........ r52782 | martin.v.loewis | 2006-11-18 19:05:35 +0100 (Sat, 18 Nov 2006) | 4 lines Patch #1594554: Always close a tkSimpleDialog on ok(), even if an exception occurs. Will backport to 2.5. ........ r52784 | martin.v.loewis | 2006-11-18 19:42:11 +0100 (Sat, 18 Nov 2006) | 3 lines Patch #1472877: Fix Tix subwidget name resolution. Will backport to 2.5. ........ r52786 | andrew.kuchling | 2006-11-18 23:17:33 +0100 (Sat, 18 Nov 2006) | 1 line Expand checking in test_sha ........ r52787 | georg.brandl | 2006-11-19 09:48:30 +0100 (Sun, 19 Nov 2006) | 3 lines Patch [ 1586791 ] better error msgs for some TypeErrors ........ r52788 | martin.v.loewis | 2006-11-19 11:41:41 +0100 (Sun, 19 Nov 2006) | 4 lines Make cStringIO.truncate raise IOError for negative arguments (even for -1). Fixes the last bit of #1359365. ........ r52789 | andrew.kuchling | 2006-11-19 19:40:01 +0100 (Sun, 19 Nov 2006) | 1 line Add a test case of data w/ bytes > 127 ........ r52790 | martin.v.loewis | 2006-11-19 19:51:54 +0100 (Sun, 19 Nov 2006) | 3 lines Patch #1070046: Marshal new-style objects like InstanceType in xmlrpclib. ........ r52792 | neal.norwitz | 2006-11-19 22:26:53 +0100 (Sun, 19 Nov 2006) | 4 lines Speed up function calls into the math module by using METH_O. There should be no functional changes. However, the error msgs are slightly different. Also verified that the module dict is not NULL on init. ........ r52794 | george.yoshida | 2006-11-20 03:24:48 +0100 (Mon, 20 Nov 2006) | 2 lines markup fix ........ r52795 | georg.brandl | 2006-11-20 08:12:58 +0100 (Mon, 20 Nov 2006) | 3 lines Further markup fix. ........ r52800 | andrew.kuchling | 2006-11-20 14:39:37 +0100 (Mon, 20 Nov 2006) | 2 lines Jython compatibility fix: if uu.decode() opened its output file, be sure to close it. ........ r52811 | neal.norwitz | 2006-11-21 06:26:22 +0100 (Tue, 21 Nov 2006) | 9 lines Bug #1599782: Fix segfault on bsddb.db.DB().type(). The problem is that _DB_get_type() can't be called without the GIL because it calls a bunch of PyErr_* APIs when an error occurs. There were no other cases in this file that it was called without the GIL. Removing the BEGIN/END THREAD around _DB_get_type() made everything work. Will backport. ........ r52814 | neal.norwitz | 2006-11-21 06:51:51 +0100 (Tue, 21 Nov 2006) | 1 line Oops, convert tabs to spaces ........ r52815 | neal.norwitz | 2006-11-21 07:23:44 +0100 (Tue, 21 Nov 2006) | 1 line Fix SF #1599879, socket.gethostname should ref getfqdn directly. ........ r52817 | martin.v.loewis | 2006-11-21 19:20:25 +0100 (Tue, 21 Nov 2006) | 4 lines Conditionalize definition of _CRT_SECURE_NO_DEPRECATE and _CRT_NONSTDC_NO_DEPRECATE. Will backport. ........ r52821 | martin.v.loewis | 2006-11-22 09:50:02 +0100 (Wed, 22 Nov 2006) | 4 lines Patch #1362975: Rework CodeContext indentation algorithm to avoid hard-coding pixel widths. Also make the text's scrollbar a child of the text frame, not the top widget. ........ r52826 | walter.doerwald | 2006-11-23 06:03:56 +0100 (Thu, 23 Nov 2006) | 3 lines Change decode() so that it works with a buffer (i.e. unicode(..., 'utf-8-sig')) SF bug #1601501. ........ r52833 | georg.brandl | 2006-11-23 10:55:07 +0100 (Thu, 23 Nov 2006) | 2 lines Bug #1601630: little improvement to getopt docs ........ r52835 | michael.hudson | 2006-11-23 14:54:04 +0100 (Thu, 23 Nov 2006) | 3 lines a test for an error condition not covered by existing tests (noticed this when writing the equivalent code for pypy) ........ r52839 | raymond.hettinger | 2006-11-23 22:06:03 +0100 (Thu, 23 Nov 2006) | 1 line Fix and/add typo ........ r52840 | raymond.hettinger | 2006-11-23 22:35:19 +0100 (Thu, 23 Nov 2006) | 1 line ... and the number of the counting shall be three. ........ r52841 | thomas.heller | 2006-11-24 19:45:39 +0100 (Fri, 24 Nov 2006) | 1 line Fix bug #1598620: A ctypes structure cannot contain itself. ........ r52843 | martin.v.loewis | 2006-11-25 16:39:19 +0100 (Sat, 25 Nov 2006) | 3 lines Disable _XOPEN_SOURCE on NetBSD 1.x. Will backport to 2.5 ........ r52845 | georg.brandl | 2006-11-26 20:27:47 +0100 (Sun, 26 Nov 2006) | 2 lines Bug #1603321: make pstats.Stats accept Unicode file paths. ........ r52850 | georg.brandl | 2006-11-27 19:46:21 +0100 (Mon, 27 Nov 2006) | 2 lines Bug #1603789: grammatical error in Tkinter docs. ........ r52855 | thomas.heller | 2006-11-28 21:21:54 +0100 (Tue, 28 Nov 2006) | 7 lines Fix #1563807: _ctypes built on AIX fails with ld ffi error. The contents of ffi_darwin.c must be compiled unless __APPLE__ is defined and __ppc__ is not. Will backport. ........ r52862 | armin.rigo | 2006-11-29 22:59:22 +0100 (Wed, 29 Nov 2006) | 3 lines Forgot a case where the locals can now be a general mapping instead of just a dictionary. (backporting...) ........ r52872 | guido.van.rossum | 2006-11-30 20:23:13 +0100 (Thu, 30 Nov 2006) | 2 lines Update version. ........ r52890 | walter.doerwald | 2006-12-01 17:59:47 +0100 (Fri, 01 Dec 2006) | 3 lines Move xdrlib tests from the module into a separate test script, port the tests to unittest and add a few new tests. ........ r52900 | raymond.hettinger | 2006-12-02 03:00:39 +0100 (Sat, 02 Dec 2006) | 1 line Add name to credits (for untokenize). ........ r52905 | martin.v.loewis | 2006-12-03 10:54:46 +0100 (Sun, 03 Dec 2006) | 2 lines Move IDLE news into NEWS.txt. ........ r52906 | martin.v.loewis | 2006-12-03 12:23:45 +0100 (Sun, 03 Dec 2006) | 4 lines Patch #1544279: Improve thread-safety of the socket module by moving the sock_addr_t storage out of the socket object. Will backport to 2.5. ........ r52908 | martin.v.loewis | 2006-12-03 13:01:53 +0100 (Sun, 03 Dec 2006) | 3 lines Patch #1371075: Make ConfigParser accept optional dict type for ordering, sorting, etc. ........ r52910 | matthias.klose | 2006-12-03 18:16:41 +0100 (Sun, 03 Dec 2006) | 2 lines - Fix build failure on kfreebsd and on the hurd. ........ r52915 | george.yoshida | 2006-12-04 12:41:54 +0100 (Mon, 04 Dec 2006) | 2 lines fix a versionchanged tag ........ r52917 | george.yoshida | 2006-12-05 06:39:50 +0100 (Tue, 05 Dec 2006) | 3 lines Fix pickle doc typo Patch #1608758 ........ r52938 | georg.brandl | 2006-12-06 23:21:18 +0100 (Wed, 06 Dec 2006) | 2 lines Patch #1610437: fix a tarfile bug with long filename headers. ........ r52945 | brett.cannon | 2006-12-07 00:38:48 +0100 (Thu, 07 Dec 2006) | 3 lines Fix a bad assumption that all objects assigned to '__loader__' on a module will have a '_files' attribute. ........ r52951 | georg.brandl | 2006-12-07 10:30:06 +0100 (Thu, 07 Dec 2006) | 3 lines RFE #1592899: mention string.maketrans() in docs for str.translate, remove reference to the old regex module in the former's doc. ........ r52962 | raymond.hettinger | 2006-12-08 04:17:18 +0100 (Fri, 08 Dec 2006) | 1 line Eliminate two redundant calls to PyObject_Hash(). ........ r52963 | raymond.hettinger | 2006-12-08 05:24:33 +0100 (Fri, 08 Dec 2006) | 3 lines Port Armin's fix for a dict resize vulnerability (svn revision 46589, sf bug 1456209). ........ r52964 | raymond.hettinger | 2006-12-08 05:57:50 +0100 (Fri, 08 Dec 2006) | 4 lines Port Georg's dictobject.c fix keys that were tuples got unpacked on the way to setting a KeyError (svn revision 52535, sf bug 1576657). ........ r52966 | raymond.hettinger | 2006-12-08 18:35:25 +0100 (Fri, 08 Dec 2006) | 2 lines Add test for SF bug 1576657 ........ r52970 | georg.brandl | 2006-12-08 21:46:11 +0100 (Fri, 08 Dec 2006) | 3 lines #1577756: svnversion doesn't react to LANG=C, use LC_ALL=C to force English output. ........ r52972 | georg.brandl | 2006-12-09 10:08:29 +0100 (Sat, 09 Dec 2006) | 3 lines Patch #1608267: fix a race condition in os.makedirs() is the directory to be created is already there. ........ r52975 | matthias.klose | 2006-12-09 13:15:27 +0100 (Sat, 09 Dec 2006) | 2 lines - Fix the build of the library reference in info format. ........ r52994 | neal.norwitz | 2006-12-11 02:01:06 +0100 (Mon, 11 Dec 2006) | 1 line Fix a typo ........ r52996 | georg.brandl | 2006-12-11 08:56:33 +0100 (Mon, 11 Dec 2006) | 2 lines Move errno imports back to individual functions. ........ r52998 | vinay.sajip | 2006-12-11 15:07:16 +0100 (Mon, 11 Dec 2006) | 1 line Patch by Jeremy Katz (SF #1609407) ........ r53000 | vinay.sajip | 2006-12-11 15:26:23 +0100 (Mon, 11 Dec 2006) | 1 line Patch by "cuppatea" (SF #1503765) ........
Diffstat (limited to 'Lib')
-rw-r--r--Lib/ConfigParser.py15
-rw-r--r--Lib/Queue.py2
-rw-r--r--Lib/SimpleXMLRPCServer.py6
-rw-r--r--Lib/_strptime.py2
-rw-r--r--Lib/atexit.py3
-rwxr-xr-xLib/base64.py2
-rw-r--r--Lib/bsddb/test/test_dbobj.py4
-rwxr-xr-xLib/cgi.py6
-rw-r--r--Lib/codecs.py33
-rw-r--r--Lib/colorsys.py3
-rw-r--r--Lib/compiler/pycodegen.py12
-rw-r--r--Lib/ctypes/__init__.py2
-rw-r--r--Lib/ctypes/test/__init__.py3
-rw-r--r--Lib/ctypes/test/test_bitfields.py9
-rw-r--r--Lib/ctypes/test/test_callbacks.py13
-rw-r--r--Lib/ctypes/test/test_cast.py16
-rw-r--r--Lib/ctypes/test/test_structures.py30
-rw-r--r--Lib/ctypes/test/test_win32.py3
-rw-r--r--Lib/decimal.py67
-rw-r--r--Lib/distutils/command/bdist_rpm.py67
-rw-r--r--Lib/distutils/command/build_ext.py2
-rw-r--r--Lib/distutils/command/install_egg_info.py3
-rw-r--r--Lib/distutils/command/register.py2
-rw-r--r--Lib/distutils/command/wininst-8.exebin0 -> 61440 bytes
-rw-r--r--Lib/distutils/sysconfig.py5
-rw-r--r--Lib/distutils/unixccompiler.py16
-rw-r--r--Lib/email/utils.py4
-rw-r--r--Lib/encodings/__init__.py6
-rw-r--r--Lib/encodings/bz2_codec.py29
-rw-r--r--Lib/encodings/utf_8_sig.py2
-rw-r--r--Lib/encodings/zlib_codec.py30
-rw-r--r--Lib/ftplib.py11
-rw-r--r--Lib/functools.py4
-rw-r--r--Lib/genericpath.py77
-rw-r--r--Lib/gzip.py7
-rw-r--r--Lib/hashlib.py31
-rw-r--r--Lib/httplib.py26
-rw-r--r--Lib/idlelib/CodeContext.py77
-rw-r--r--Lib/idlelib/EditorWindow.py2
-rw-r--r--Lib/idlelib/NEWS.txt7
-rw-r--r--Lib/idlelib/PyShell.py4
-rw-r--r--Lib/idlelib/ScriptBinding.py10
-rw-r--r--Lib/inspect.py38
-rwxr-xr-xLib/lib-tk/Tix.py5
-rw-r--r--Lib/lib-tk/Tkinter.py3
-rw-r--r--Lib/lib-tk/tkMessageBox.py10
-rw-r--r--Lib/lib-tk/tkSimpleDialog.py14
-rw-r--r--Lib/lib-tk/turtle.py2
-rw-r--r--Lib/logging/__init__.py9
-rw-r--r--Lib/logging/config.py11
-rw-r--r--Lib/logging/handlers.py4
-rw-r--r--Lib/macpath.py63
-rwxr-xr-xLib/mailbox.py99
-rw-r--r--Lib/ntpath.py77
-rw-r--r--Lib/os.py8
-rw-r--r--Lib/os2emxpath.py276
-rwxr-xr-xLib/pdb.py2
-rw-r--r--Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py2
-rw-r--r--Lib/plat-sunos5/STROPTS.py2
-rw-r--r--Lib/posixpath.py87
-rw-r--r--Lib/pstats.py2
-rw-r--r--Lib/pty.py4
-rw-r--r--Lib/pyclbr.py2
-rw-r--r--Lib/sgmllib.py19
-rwxr-xr-xLib/smtplib.py39
-rw-r--r--Lib/subprocess.py14
-rw-r--r--Lib/tarfile.py179
-rw-r--r--Lib/test/README4
-rw-r--r--Lib/test/crashers/bogus_sre_bytecode.py47
-rw-r--r--Lib/test/crashers/infinite_loop_re.py16
-rw-r--r--Lib/test/crashers/loosing_mro_ref.py36
-rw-r--r--Lib/test/list_tests.py3
-rw-r--r--Lib/test/output/test_MimeWriter110
-rw-r--r--Lib/test/output/test_cgi42
-rw-r--r--Lib/test/output/test_cookie32
-rw-r--r--Lib/test/output/test_global5
-rw-r--r--Lib/test/output/test_grammar69
-rw-r--r--Lib/test/output/test_httplib13
-rw-r--r--Lib/test/output/test_math28
-rw-r--r--Lib/test/output/test_mmap38
-rw-r--r--Lib/test/output/test_nis2
-rw-r--r--Lib/test/output/test_opcodes6
-rw-r--r--Lib/test/output/test_openpty2
-rw-r--r--Lib/test/output/test_poll19
-rw-r--r--Lib/test/output/test_regex29
-rw-r--r--Lib/test/output/test_scope24
-rw-r--r--Lib/test/output/test_tokenize75
-rw-r--r--Lib/test/output/test_types15
-rw-r--r--Lib/test/output/test_xdrlib19
-rw-r--r--Lib/test/outstanding_bugs.py15
-rw-r--r--Lib/test/sgml_input.html212
-rw-r--r--Lib/test/string_tests.py2
-rw-r--r--Lib/test/test_MimeWriter.py249
-rw-r--r--Lib/test/test_StringIO.py23
-rw-r--r--Lib/test/test___future__.py108
-rwxr-xr-xLib/test/test_array.py7
-rwxr-xr-xLib/test/test_binascii.py2
-rw-r--r--Lib/test/test_bufio.py116
-rw-r--r--Lib/test/test_builtin.py17
-rw-r--r--Lib/test/test_cfgparser.py46
-rw-r--r--Lib/test/test_cgi.py260
-rw-r--r--Lib/test/test_class.py8
-rw-r--r--Lib/test/test_codecencodings_cn.py2
-rw-r--r--Lib/test/test_codecs.py60
-rw-r--r--Lib/test/test_complex_args.py91
-rw-r--r--Lib/test/test_contextlib.py26
-rw-r--r--Lib/test/test_cookie.py114
-rw-r--r--Lib/test/test_datetime.py1
-rw-r--r--Lib/test/test_decimal.py28
-rw-r--r--Lib/test/test_descr.py14
-rw-r--r--Lib/test/test_dict.py10
-rw-r--r--Lib/test/test_exceptions.py72
-rwxr-xr-xLib/test/test_fcntl.py2
-rw-r--r--Lib/test/test_format.py4
-rw-r--r--Lib/test/test_functools.py7
-rw-r--r--Lib/test/test_future.py21
-rw-r--r--Lib/test/test_genericpath.py184
-rw-r--r--Lib/test/test_global.py50
-rw-r--r--Lib/test/test_grammar.py1681
-rw-r--r--Lib/test/test_gzip.py11
-rw-r--r--Lib/test/test_httplib.py166
-rw-r--r--Lib/test/test_imp.py62
-rw-r--r--Lib/test/test_import.py397
-rw-r--r--Lib/test/test_inspect.py11
-rw-r--r--Lib/test/test_itertools.py5
-rw-r--r--Lib/test/test_long.py23
-rw-r--r--Lib/test/test_mailbox.py55
-rw-r--r--Lib/test/test_math.py435
-rw-r--r--Lib/test/test_mmap.py394
-rw-r--r--Lib/test/test_modulefinder.py11
-rw-r--r--Lib/test/test_multibytecodec.py16
-rw-r--r--Lib/test/test_mutants.py2
-rw-r--r--Lib/test/test_new.py8
-rw-r--r--Lib/test/test_nis.py67
-rw-r--r--Lib/test/test_opcodes.py207
-rw-r--r--Lib/test/test_openpty.py30
-rw-r--r--Lib/test/test_os.py17
-rw-r--r--Lib/test/test_parser.py38
-rw-r--r--Lib/test/test_peepholer.py35
-rw-r--r--Lib/test/test_pep352.py3
-rw-r--r--Lib/test/test_poll.py316
-rw-r--r--Lib/test/test_pyclbr.py3
-rw-r--r--Lib/test/test_scope.py675
-rw-r--r--Lib/test/test_set.py11
-rw-r--r--Lib/test/test_sgmllib.py28
-rw-r--r--Lib/test/test_sha.py19
-rw-r--r--Lib/test/test_structmembers.py80
-rw-r--r--Lib/test/test_subprocess.py6
-rw-r--r--Lib/test/test_support.py6
-rw-r--r--Lib/test/test_syntax.py132
-rw-r--r--Lib/test/test_tarfile.py49
-rw-r--r--Lib/test/test_tempfile.py2
-rw-r--r--Lib/test/test_time.py10
-rw-r--r--Lib/test/test_tokenize.py117
-rw-r--r--Lib/test/test_traceback.py4
-rw-r--r--Lib/test/test_types.py550
-rw-r--r--Lib/test/test_unicode.py3
-rw-r--r--Lib/test/test_xdrlib.py55
-rw-r--r--Lib/test/test_xmlrpc.py9
-rw-r--r--Lib/tokenize.py109
-rw-r--r--Lib/traceback.py5
-rw-r--r--Lib/urllib.py8
-rw-r--r--Lib/urllib2.py4
-rwxr-xr-xLib/uu.py4
-rw-r--r--Lib/webbrowser.py18
-rw-r--r--Lib/xdrlib.py58
-rw-r--r--Lib/xmlrpclib.py21
167 files changed, 5633 insertions, 4352 deletions
diff --git a/Lib/ConfigParser.py b/Lib/ConfigParser.py
index 6dc53b9..65c8ce5 100644
--- a/Lib/ConfigParser.py
+++ b/Lib/ConfigParser.py
@@ -199,11 +199,11 @@ class MissingSectionHeaderError(ParsingError):
self.line = line
-
class RawConfigParser:
- def __init__(self, defaults=None):
- self._sections = {}
- self._defaults = {}
+ def __init__(self, defaults=None, dict_type=dict):
+ self._dict = dict_type
+ self._sections = self._dict()
+ self._defaults = self._dict()
if defaults:
for key, value in defaults.items():
self._defaults[self.optionxform(key)] = value
@@ -224,7 +224,7 @@ class RawConfigParser:
"""
if section in self._sections:
raise DuplicateSectionError(section)
- self._sections[section] = {}
+ self._sections[section] = self._dict()
def has_section(self, section):
"""Indicate whether the named section is present in the configuration.
@@ -307,7 +307,7 @@ class RawConfigParser:
except KeyError:
if section != DEFAULTSECT:
raise NoSectionError(section)
- d2 = {}
+ d2 = self._dict()
d = self._defaults.copy()
d.update(d2)
if "__name__" in d:
@@ -453,7 +453,8 @@ class RawConfigParser:
elif sectname == DEFAULTSECT:
cursect = self._defaults
else:
- cursect = {'__name__': sectname}
+ cursect = self._dict()
+ cursect['__name__'] = sectname
self._sections[sectname] = cursect
# So sections can't start with a continuation line
optname = None
diff --git a/Lib/Queue.py b/Lib/Queue.py
index 0f80584..79b0abf 100644
--- a/Lib/Queue.py
+++ b/Lib/Queue.py
@@ -26,7 +26,7 @@ class Queue:
self._init(maxsize)
# mutex must be held whenever the queue is mutating. All methods
# that acquire mutex must release it before returning. mutex
- # is shared between the two conditions, so acquiring and
+ # is shared between the three conditions, so acquiring and
# releasing the conditions also acquires and releases mutex.
self.mutex = threading.Lock()
# Notify not_empty whenever an item is added to the queue; a
diff --git a/Lib/SimpleXMLRPCServer.py b/Lib/SimpleXMLRPCServer.py
index 3b0a6a5..c6f6958 100644
--- a/Lib/SimpleXMLRPCServer.py
+++ b/Lib/SimpleXMLRPCServer.py
@@ -264,8 +264,9 @@ class SimpleXMLRPCDispatcher:
encoding=self.encoding)
except:
# report exception back to server
+ exc_type, exc_value, exc_tb = sys.exc_info()
response = xmlrpclib.dumps(
- xmlrpclib.Fault(1, "%s:%s" % sys.exc_info()[:2]),
+ xmlrpclib.Fault(1, "%s:%s" % (exc_type, exc_value)),
encoding=self.encoding, allow_none=self.allow_none,
)
@@ -364,9 +365,10 @@ class SimpleXMLRPCDispatcher:
'faultString' : fault.faultString}
)
except:
+ exc_type, exc_value, exc_tb = sys.exc_info()
results.append(
{'faultCode' : 1,
- 'faultString' : "%s:%s" % sys.exc_info()[:2]}
+ 'faultString' : "%s:%s" % (exc_type, exc_value)}
)
return results
diff --git a/Lib/_strptime.py b/Lib/_strptime.py
index ce8525b..3fb5602 100644
--- a/Lib/_strptime.py
+++ b/Lib/_strptime.py
@@ -306,7 +306,7 @@ def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
_cache_lock.release()
found = format_regex.match(data_string)
if not found:
- raise ValueError("time data did not match format: data=%s fmt=%s" %
+ raise ValueError("time data %r does not match format %r" %
(data_string, format))
if len(data_string) != found.end():
raise ValueError("unconverted data remains: %s" %
diff --git a/Lib/atexit.py b/Lib/atexit.py
index c9f4cc6..93fddf7 100644
--- a/Lib/atexit.py
+++ b/Lib/atexit.py
@@ -40,8 +40,11 @@ def register(func, *targs, **kargs):
func - function to be called at exit
targs - optional arguments to pass to func
kargs - optional keyword arguments to pass to func
+
+ func is returned to facilitate usage as a decorator.
"""
_exithandlers.append((func, targs, kargs))
+ return func
if hasattr(sys, "exitfunc"):
# Assume it's another registered exit function - append it to our list
diff --git a/Lib/base64.py b/Lib/base64.py
index c196cd8..41a5e14 100755
--- a/Lib/base64.py
+++ b/Lib/base64.py
@@ -308,7 +308,7 @@ def decode(input, output):
def encodestring(s):
- """Encode a string."""
+ """Encode a string into multiple lines of base-64 data."""
pieces = []
for i in range(0, len(s), MAXBINSIZE):
chunk = s[i : i + MAXBINSIZE]
diff --git a/Lib/bsddb/test/test_dbobj.py b/Lib/bsddb/test/test_dbobj.py
index 1305883..bba6a5b 100644
--- a/Lib/bsddb/test/test_dbobj.py
+++ b/Lib/bsddb/test/test_dbobj.py
@@ -69,6 +69,10 @@ class dbobjTestCase(unittest.TestCase):
self.db.close()
self.env.close()
+ def test03_dbobj_type_before_open(self):
+ # Ensure this doesn't cause a segfault.
+ self.assertRaises(db.DBInvalidArgError, db.DB().type)
+
#----------------------------------------------------------------------
def test_suite():
diff --git a/Lib/cgi.py b/Lib/cgi.py
index fa8fd13..80b3b7a 100755
--- a/Lib/cgi.py
+++ b/Lib/cgi.py
@@ -799,8 +799,10 @@ class FormContentDict(UserDict.UserDict):
form.dict == {key: [val, val, ...], ...}
"""
- def __init__(self, environ=os.environ):
- self.dict = self.data = parse(environ=environ)
+ def __init__(self, environ=os.environ, keep_blank_values=0, strict_parsing=0):
+ self.dict = self.data = parse(environ=environ,
+ keep_blank_values=keep_blank_values,
+ strict_parsing=strict_parsing)
self.query_string = environ['QUERY_STRING']
diff --git a/Lib/codecs.py b/Lib/codecs.py
index 1518d75..f834b8d 100644
--- a/Lib/codecs.py
+++ b/Lib/codecs.py
@@ -329,6 +329,12 @@ class StreamWriter(Codec):
"""
return getattr(self.stream, name)
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, tb):
+ self.stream.close()
+
###
class StreamReader(Codec):
@@ -568,6 +574,12 @@ class StreamReader(Codec):
"""
return getattr(self.stream, name)
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, tb):
+ self.stream.close()
+
###
class StreamReaderWriter:
@@ -641,6 +653,14 @@ class StreamReaderWriter:
"""
return getattr(self.stream, name)
+ # these are needed to make "with codecs.open(...)" work properly
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, tb):
+ self.stream.close()
+
###
class StreamRecoder:
@@ -751,6 +771,12 @@ class StreamRecoder:
"""
return getattr(self.stream, name)
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, tb):
+ self.stream.close()
+
### Shortcuts
def open(filename, mode='rb', encoding=None, errors='strict', buffering=1):
@@ -824,9 +850,10 @@ def EncodedFile(file, data_encoding, file_encoding=None, errors='strict'):
"""
if file_encoding is None:
file_encoding = data_encoding
- info = lookup(data_encoding)
- sr = StreamRecoder(file, info.encode, info.decode,
- info.streamreader, info.streamwriter, errors)
+ data_info = lookup(data_encoding)
+ file_info = lookup(file_encoding)
+ sr = StreamRecoder(file, data_info.encode, data_info.decode,
+ file_info.streamreader, file_info.streamwriter, errors)
# Add attributes to simplify introspection
sr.data_encoding = data_encoding
sr.file_encoding = file_encoding
diff --git a/Lib/colorsys.py b/Lib/colorsys.py
index 39b4b16..851417b 100644
--- a/Lib/colorsys.py
+++ b/Lib/colorsys.py
@@ -117,7 +117,8 @@ def hsv_to_rgb(h, s, v):
p = v*(1.0 - s)
q = v*(1.0 - s*f)
t = v*(1.0 - s*(1.0-f))
- if i%6 == 0: return v, t, p
+ i = i%6
+ if i == 0: return v, t, p
if i == 1: return q, v, p
if i == 2: return p, v, t
if i == 3: return p, q, v
diff --git a/Lib/compiler/pycodegen.py b/Lib/compiler/pycodegen.py
index b08a307..353c2c9 100644
--- a/Lib/compiler/pycodegen.py
+++ b/Lib/compiler/pycodegen.py
@@ -577,12 +577,11 @@ class CodeGenerator:
def visitListComp(self, node):
self.set_lineno(node)
# setup list
- append = "$append%d" % self.__list_count
+ tmpname = "$list%d" % self.__list_count
self.__list_count = self.__list_count + 1
self.emit('BUILD_LIST', 0)
self.emit('DUP_TOP')
- self.emit('LOAD_ATTR', 'append')
- self._implicitNameOp('STORE', append)
+ self._implicitNameOp('STORE', tmpname)
stack = []
for i, for_ in zip(range(len(node.quals)), node.quals):
@@ -594,10 +593,9 @@ class CodeGenerator:
self.visit(if_, cont)
stack.insert(0, (start, cont, anchor))
- self._implicitNameOp('LOAD', append)
+ self._implicitNameOp('LOAD', tmpname)
self.visit(node.expr)
- self.emit('CALL_FUNCTION', 1)
- self.emit('POP_TOP')
+ self.emit('LIST_APPEND')
for start, cont, anchor in stack:
if cont:
@@ -608,7 +606,7 @@ class CodeGenerator:
self.nextBlock(skip_one)
self.emit('JUMP_ABSOLUTE', start)
self.startBlock(anchor)
- self._implicitNameOp('DELETE', append)
+ self._implicitNameOp('DELETE', tmpname)
self.__list_count = self.__list_count - 1
diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py
index 78a2ab8..eb5d97e 100644
--- a/Lib/ctypes/__init__.py
+++ b/Lib/ctypes/__init__.py
@@ -427,6 +427,8 @@ if sizeof(c_uint) == sizeof(c_void_p):
c_size_t = c_uint
elif sizeof(c_ulong) == sizeof(c_void_p):
c_size_t = c_ulong
+elif sizeof(c_ulonglong) == sizeof(c_void_p):
+ c_size_t = c_ulonglong
# functions
diff --git a/Lib/ctypes/test/__init__.py b/Lib/ctypes/test/__init__.py
index 2ae5405..2b745c2 100644
--- a/Lib/ctypes/test/__init__.py
+++ b/Lib/ctypes/test/__init__.py
@@ -37,7 +37,8 @@ def requires(resource, msg=None):
def find_package_modules(package, mask):
import fnmatch
- if hasattr(package, "__loader__"):
+ if (hasattr(package, "__loader__") and
+ hasattr(package.__loader__, '_files')):
path = package.__name__.replace(".", os.path.sep)
mask = os.path.join(path, mask)
for fnm in package.__loader__._files.iterkeys():
diff --git a/Lib/ctypes/test/test_bitfields.py b/Lib/ctypes/test/test_bitfields.py
index 92c4669..2867cbf 100644
--- a/Lib/ctypes/test/test_bitfields.py
+++ b/Lib/ctypes/test/test_bitfields.py
@@ -215,5 +215,14 @@ class BitFieldTest(unittest.TestCase):
("b", c_ubyte, 4)]
self.failUnlessEqual(sizeof(X), sizeof(c_byte))
+ def test_anon_bitfields(self):
+ # anonymous bit-fields gave a strange error message
+ class X(Structure):
+ _fields_ = [("a", c_byte, 4),
+ ("b", c_ubyte, 4)]
+ class Y(Structure):
+ _anonymous_ = ["_"]
+ _fields_ = [("_", X)]
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/ctypes/test/test_callbacks.py
index 9d96a54..f47fc37 100644
--- a/Lib/ctypes/test/test_callbacks.py
+++ b/Lib/ctypes/test/test_callbacks.py
@@ -101,6 +101,19 @@ class Callbacks(unittest.TestCase):
after = grc(o)
self.failUnlessEqual((after, o), (before, o))
+ def test_unsupported_restype_1(self):
+ # Only "fundamental" result types are supported for callback
+ # functions, the type must have a non-NULL stgdict->setfunc.
+ # POINTER(c_double), for example, is not supported.
+
+ prototype = self.functype.im_func(POINTER(c_double))
+ # The type is checked when the prototype is called
+ self.assertRaises(TypeError, prototype, lambda: None)
+
+ def test_unsupported_restype_2(self):
+ prototype = self.functype.im_func(object)
+ self.assertRaises(TypeError, prototype, lambda: None)
+
try:
WINFUNCTYPE
except NameError:
diff --git a/Lib/ctypes/test/test_cast.py b/Lib/ctypes/test/test_cast.py
index 09e928f..7371b0f 100644
--- a/Lib/ctypes/test/test_cast.py
+++ b/Lib/ctypes/test/test_cast.py
@@ -57,5 +57,21 @@ class Test(unittest.TestCase):
c_int()
self.failUnlessEqual(p[:4], [1, 2, 96, 4])
+ def test_char_p(self):
+ # This didn't work: bad argument to internal function
+ s = c_char_p("hiho")
+ self.failUnlessEqual(cast(cast(s, c_void_p), c_char_p).value,
+ "hiho")
+
+ try:
+ c_wchar_p
+ except NameError:
+ pass
+ else:
+ def test_wchar_p(self):
+ s = c_wchar_p("hiho")
+ self.failUnlessEqual(cast(cast(s, c_void_p), c_wchar_p).value,
+ "hiho")
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py
index 8a4531d..613163d 100644
--- a/Lib/ctypes/test/test_structures.py
+++ b/Lib/ctypes/test/test_structures.py
@@ -381,5 +381,35 @@ class PointerMemberTestCase(unittest.TestCase):
s.p = None
self.failUnlessEqual(s.x, 12345678)
+class TestRecursiveStructure(unittest.TestCase):
+ def test_contains_itself(self):
+ class Recursive(Structure):
+ pass
+
+ try:
+ Recursive._fields_ = [("next", Recursive)]
+ except AttributeError, details:
+ self.failUnless("Structure or union cannot contain itself" in
+ str(details))
+ else:
+ self.fail("Structure or union cannot contain itself")
+
+
+ def test_vice_versa(self):
+ class First(Structure):
+ pass
+ class Second(Structure):
+ pass
+
+ First._fields_ = [("second", Second)]
+
+ try:
+ Second._fields_ = [("first", First)]
+ except AttributeError, details:
+ self.failUnless("_fields_ is final" in
+ str(details))
+ else:
+ self.fail("AttributeError not raised")
+
if __name__ == '__main__':
unittest.main()
diff --git a/Lib/ctypes/test/test_win32.py b/Lib/ctypes/test/test_win32.py
index db530d3..10deaca 100644
--- a/Lib/ctypes/test/test_win32.py
+++ b/Lib/ctypes/test/test_win32.py
@@ -6,7 +6,8 @@ import unittest, sys
import _ctypes_test
-if sys.platform == "win32":
+if sys.platform == "win32" and sizeof(c_void_p) == sizeof(c_int):
+ # Only windows 32-bit has different calling conventions.
class WindowsTestCase(unittest.TestCase):
def test_callconv_1(self):
diff --git a/Lib/decimal.py b/Lib/decimal.py
index 2f2a617..86455f3 100644
--- a/Lib/decimal.py
+++ b/Lib/decimal.py
@@ -131,7 +131,7 @@ __all__ = [
'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN',
# Functions for manipulating contexts
- 'setcontext', 'getcontext'
+ 'setcontext', 'getcontext', 'localcontext'
]
import copy as _copy
@@ -458,6 +458,49 @@ else:
del threading, local # Don't contaminate the namespace
+def localcontext(ctx=None):
+ """Return a context manager for a copy of the supplied context
+
+ Uses a copy of the current context if no context is specified
+ The returned context manager creates a local decimal context
+ in a with statement:
+ def sin(x):
+ with localcontext() as ctx:
+ ctx.prec += 2
+ # Rest of sin calculation algorithm
+ # uses a precision 2 greater than normal
+ return +s # Convert result to normal precision
+
+ def sin(x):
+ with localcontext(ExtendedContext):
+ # Rest of sin calculation algorithm
+ # uses the Extended Context from the
+ # General Decimal Arithmetic Specification
+ return +s # Convert result to normal context
+
+ """
+ # The string below can't be included in the docstring until Python 2.6
+ # as the doctest module doesn't understand __future__ statements
+ """
+ >>> from __future__ import with_statement
+ >>> print getcontext().prec
+ 28
+ >>> with localcontext():
+ ... ctx = getcontext()
+ ... ctx.prec() += 2
+ ... print ctx.prec
+ ...
+ 30
+ >>> with localcontext(ExtendedContext):
+ ... print getcontext().prec
+ ...
+ 9
+ >>> print getcontext().prec
+ 28
+ """
+ if ctx is None: ctx = getcontext()
+ return _ContextManager(ctx)
+
##### Decimal class ###########################################
@@ -2192,23 +2235,14 @@ for name in rounding_functions:
del name, val, globalname, rounding_functions
-class ContextManager(object):
- """Helper class to simplify Context management.
-
- Sample usage:
-
- with decimal.ExtendedContext:
- s = ...
- return +s # Convert result to normal precision
-
- with decimal.getcontext() as ctx:
- ctx.prec += 2
- s = ...
- return +s
+class _ContextManager(object):
+ """Context manager class to support localcontext().
+ Sets a copy of the supplied context in __enter__() and restores
+ the previous decimal context in __exit__()
"""
def __init__(self, new_context):
- self.new_context = new_context
+ self.new_context = new_context.copy()
def __enter__(self):
self.saved_context = getcontext()
setcontext(self.new_context)
@@ -2267,9 +2301,6 @@ class Context(object):
s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
return ', '.join(s) + ')'
- def get_manager(self):
- return ContextManager(self.copy())
-
def clear_flags(self):
"""Reset all flags to zero"""
for flag in self.flags:
diff --git a/Lib/distutils/command/bdist_rpm.py b/Lib/distutils/command/bdist_rpm.py
index 5b09965..6f0e0d8 100644
--- a/Lib/distutils/command/bdist_rpm.py
+++ b/Lib/distutils/command/bdist_rpm.py
@@ -337,37 +337,47 @@ class bdist_rpm (Command):
if not self.keep_temp:
rpm_cmd.append('--clean')
rpm_cmd.append(spec_path)
+ # Determine the binary rpm names that should be built out of this spec
+ # file
+ # Note that some of these may not be really built (if the file
+ # list is empty)
+ nvr_string = "%{name}-%{version}-%{release}"
+ src_rpm = nvr_string + ".src.rpm"
+ non_src_rpm = "%{arch}/" + nvr_string + ".%{arch}.rpm"
+ q_cmd = r"rpm -q --qf '%s %s\n' --specfile '%s'" % (
+ src_rpm, non_src_rpm, spec_path)
+
+ out = os.popen(q_cmd)
+ binary_rpms = []
+ source_rpm = None
+ while 1:
+ line = out.readline()
+ if not line:
+ break
+ l = string.split(string.strip(line))
+ assert(len(l) == 2)
+ binary_rpms.append(l[1])
+ # The source rpm is named after the first entry in the spec file
+ if source_rpm is None:
+ source_rpm = l[0]
+
+ status = out.close()
+ if status:
+ raise DistutilsExecError("Failed to execute: %s" % repr(q_cmd))
+
self.spawn(rpm_cmd)
- # XXX this is a nasty hack -- we really should have a proper way to
- # find out the names of the RPM files created; also, this assumes
- # that RPM creates exactly one source and one binary RPM.
if not self.dry_run:
if not self.binary_only:
- srpms = glob.glob(os.path.join(rpm_dir['SRPMS'], "*.rpm"))
- assert len(srpms) == 1, \
- "unexpected number of SRPM files found: %s" % srpms
- dist_file = ('bdist_rpm', 'any',
- self._dist_path(srpms[0]))
- self.distribution.dist_files.append(dist_file)
- self.move_file(srpms[0], self.dist_dir)
+ srpm = os.path.join(rpm_dir['SRPMS'], source_rpm)
+ assert(os.path.exists(srpm))
+ self.move_file(srpm, self.dist_dir)
if not self.source_only:
- rpms = glob.glob(os.path.join(rpm_dir['RPMS'], "*/*.rpm"))
- debuginfo = glob.glob(os.path.join(rpm_dir['RPMS'],
- "*/*debuginfo*.rpm"))
- if debuginfo:
- rpms.remove(debuginfo[0])
- assert len(rpms) == 1, \
- "unexpected number of RPM files found: %s" % rpms
- dist_file = ('bdist_rpm', get_python_version(),
- self._dist_path(rpms[0]))
- self.distribution.dist_files.append(dist_file)
- self.move_file(rpms[0], self.dist_dir)
- if debuginfo:
- dist_file = ('bdist_rpm', get_python_version(),
- self._dist_path(debuginfo[0]))
- self.move_file(debuginfo[0], self.dist_dir)
+ for rpm in binary_rpms:
+ rpm = os.path.join(rpm_dir['RPMS'], rpm)
+ if os.path.exists(rpm):
+ self.move_file(rpm, self.dist_dir)
# run()
def _dist_path(self, path):
@@ -381,6 +391,7 @@ class bdist_rpm (Command):
spec_file = [
'%define name ' + self.distribution.get_name(),
'%define version ' + self.distribution.get_version().replace('-','_'),
+ '%define unmangled_version ' + self.distribution.get_version(),
'%define release ' + self.release.replace('-','_'),
'',
'Summary: ' + self.distribution.get_description(),
@@ -402,9 +413,9 @@ class bdist_rpm (Command):
# but only after it has run: and we create the spec file before
# running "sdist", in case of --spec-only.
if self.use_bzip2:
- spec_file.append('Source0: %{name}-%{version}.tar.bz2')
+ spec_file.append('Source0: %{name}-%{unmangled_version}.tar.bz2')
else:
- spec_file.append('Source0: %{name}-%{version}.tar.gz')
+ spec_file.append('Source0: %{name}-%{unmangled_version}.tar.gz')
spec_file.extend([
'License: ' + self.distribution.get_license(),
@@ -479,7 +490,7 @@ class bdist_rpm (Command):
# are just text that we drop in as-is. Hmmm.
script_options = [
- ('prep', 'prep_script', "%setup"),
+ ('prep', 'prep_script', "%setup -n %{name}-%{unmangled_version}"),
('build', 'build_script', def_build),
('install', 'install_script',
("%s install "
diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py
index cd67544..f79eee3 100644
--- a/Lib/distutils/command/build_ext.py
+++ b/Lib/distutils/command/build_ext.py
@@ -186,7 +186,7 @@ class build_ext (Command):
# for extensions under Cygwin and AtheOS Python's library directory must be
# appended to library_dirs
if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos' or \
- (sys.platform.startswith('linux') and
+ ((sys.platform.startswith('linux') or sys.platform.startswith('gnu')) and
sysconfig.get_config_var('Py_ENABLE_SHARED')):
if string.find(sys.executable, sys.exec_prefix) != -1:
# building third party extensions
diff --git a/Lib/distutils/command/install_egg_info.py b/Lib/distutils/command/install_egg_info.py
index c31ac29..c888031 100644
--- a/Lib/distutils/command/install_egg_info.py
+++ b/Lib/distutils/command/install_egg_info.py
@@ -35,6 +35,9 @@ class install_egg_info(Command):
dir_util.remove_tree(target, dry_run=self.dry_run)
elif os.path.exists(target):
self.execute(os.unlink,(self.target,),"Removing "+target)
+ elif not os.path.isdir(self.install_dir):
+ self.execute(os.makedirs, (self.install_dir,),
+ "Creating "+self.install_dir)
log.info("Writing %s", target)
if not self.dry_run:
f = open(target, 'w')
diff --git a/Lib/distutils/command/register.py b/Lib/distutils/command/register.py
index f891262..3177476 100644
--- a/Lib/distutils/command/register.py
+++ b/Lib/distutils/command/register.py
@@ -256,7 +256,7 @@ Your selection [default 1]: ''',
body = StringIO.StringIO()
for key, value in data.items():
# handle multiple entries for the same name
- if type(value) != type([]):
+ if type(value) not in (type([]), type( () )):
value = [value]
for value in value:
value = unicode(value).encode("utf-8")
diff --git a/Lib/distutils/command/wininst-8.exe b/Lib/distutils/command/wininst-8.exe
new file mode 100644
index 0000000..7403bfa
--- /dev/null
+++ b/Lib/distutils/command/wininst-8.exe
Binary files differ
diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py
index 96923bd..8989d92 100644
--- a/Lib/distutils/sysconfig.py
+++ b/Lib/distutils/sysconfig.py
@@ -509,7 +509,10 @@ def get_config_vars(*args):
# are in CFLAGS or LDFLAGS and remove them if they are.
# This is needed when building extensions on a 10.3 system
# using a universal build of python.
- for key in ('LDFLAGS', 'BASECFLAGS'):
+ for key in ('LDFLAGS', 'BASECFLAGS',
+ # a number of derived variables. These need to be
+ # patched up as well.
+ 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
flags = _config_vars[key]
flags = re.sub('-arch\s+\w+\s', ' ', flags)
flags = re.sub('-isysroot [^ \t]*', ' ', flags)
diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py
index 6cd14f7..75e8a53 100644
--- a/Lib/distutils/unixccompiler.py
+++ b/Lib/distutils/unixccompiler.py
@@ -82,6 +82,22 @@ def _darwin_compiler_fixup(compiler_so, cc_args):
except ValueError:
pass
+ # Check if the SDK that is used during compilation actually exists,
+ # the universal build requires the usage of a universal SDK and not all
+ # users have that installed by default.
+ sysroot = None
+ if '-isysroot' in cc_args:
+ idx = cc_args.index('-isysroot')
+ sysroot = cc_args[idx+1]
+ elif '-isysroot' in compiler_so:
+ idx = compiler_so.index('-isysroot')
+ sysroot = compiler_so[idx+1]
+
+ if sysroot and not os.path.isdir(sysroot):
+ log.warn("Compiling with an SDK that doesn't seem to exist: %s",
+ sysroot)
+ log.warn("Please check your Xcode installation")
+
return compiler_so
class UnixCCompiler(CCompiler):
diff --git a/Lib/email/utils.py b/Lib/email/utils.py
index 26ebb0e..ee952d3 100644
--- a/Lib/email/utils.py
+++ b/Lib/email/utils.py
@@ -235,10 +235,6 @@ def decode_rfc2231(s):
parts = s.split(TICK, 2)
if len(parts) <= 2:
return None, None, s
- if len(parts) > 3:
- charset, language = parts[:2]
- s = TICK.join(parts[2:])
- return charset, language, s
return parts
diff --git a/Lib/encodings/__init__.py b/Lib/encodings/__init__.py
index b0ca364..f1e7ecc 100644
--- a/Lib/encodings/__init__.py
+++ b/Lib/encodings/__init__.py
@@ -28,7 +28,7 @@ Written by Marc-Andre Lemburg (mal@lemburg.com).
"""#"
-import codecs, types
+import codecs
from . import aliases
_cache = {}
@@ -60,7 +60,7 @@ def normalize_encoding(encoding):
"""
# Make sure we have an 8-bit string, because .translate() works
# differently for Unicode strings.
- if type(encoding) is types.UnicodeType:
+ if isinstance(encoding, unicode):
# Note that .encode('latin-1') does *not* use the codec
# registry, so this call doesn't recurse. (See unicodeobject.c
# PyUnicode_AsEncodedString() for details)
@@ -90,7 +90,7 @@ def search_function(encoding):
else:
modnames = [norm_encoding]
for modname in modnames:
- if not modname:
+ if not modname or '.' in modname:
continue
try:
mod = __import__('encodings.' + modname,
diff --git a/Lib/encodings/bz2_codec.py b/Lib/encodings/bz2_codec.py
index 81e84b6..054b36b 100644
--- a/Lib/encodings/bz2_codec.py
+++ b/Lib/encodings/bz2_codec.py
@@ -52,14 +52,35 @@ class Codec(codecs.Codec):
return bz2_decode(input, errors)
class IncrementalEncoder(codecs.IncrementalEncoder):
+ def __init__(self, errors='strict'):
+ assert errors == 'strict'
+ self.errors = errors
+ self.compressobj = bz2.BZ2Compressor()
+
def encode(self, input, final=False):
- assert self.errors == 'strict'
- return bz2.compress(input)
+ if final:
+ c = self.compressobj.compress(input)
+ return c + self.compressobj.flush()
+ else:
+ return self.compressobj.compress(input)
+
+ def reset(self):
+ self.compressobj = bz2.BZ2Compressor()
class IncrementalDecoder(codecs.IncrementalDecoder):
+ def __init__(self, errors='strict'):
+ assert errors == 'strict'
+ self.errors = errors
+ self.decompressobj = bz2.BZ2Decompressor()
+
def decode(self, input, final=False):
- assert self.errors == 'strict'
- return bz2.decompress(input)
+ try:
+ return self.decompressobj.decompress(input)
+ except EOFError:
+ return ''
+
+ def reset(self):
+ self.decompressobj = bz2.BZ2Decompressor()
class StreamWriter(Codec,codecs.StreamWriter):
pass
diff --git a/Lib/encodings/utf_8_sig.py b/Lib/encodings/utf_8_sig.py
index f05f6b8..d751da6 100644
--- a/Lib/encodings/utf_8_sig.py
+++ b/Lib/encodings/utf_8_sig.py
@@ -16,7 +16,7 @@ def encode(input, errors='strict'):
def decode(input, errors='strict'):
prefix = 0
- if input.startswith(codecs.BOM_UTF8):
+ if input[:3] == codecs.BOM_UTF8:
input = input[3:]
prefix = 3
(output, consumed) = codecs.utf_8_decode(input, errors, True)
diff --git a/Lib/encodings/zlib_codec.py b/Lib/encodings/zlib_codec.py
index 2694f15..3419f9f 100644
--- a/Lib/encodings/zlib_codec.py
+++ b/Lib/encodings/zlib_codec.py
@@ -51,14 +51,36 @@ class Codec(codecs.Codec):
return zlib_decode(input, errors)
class IncrementalEncoder(codecs.IncrementalEncoder):
+ def __init__(self, errors='strict'):
+ assert errors == 'strict'
+ self.errors = errors
+ self.compressobj = zlib.compressobj()
+
def encode(self, input, final=False):
- assert self.errors == 'strict'
- return zlib.compress(input)
+ if final:
+ c = self.compressobj.compress(input)
+ return c + self.compressobj.flush()
+ else:
+ return self.compressobj.compress(input)
+
+ def reset(self):
+ self.compressobj = zlib.compressobj()
class IncrementalDecoder(codecs.IncrementalDecoder):
+ def __init__(self, errors='strict'):
+ assert errors == 'strict'
+ self.errors = errors
+ self.decompressobj = zlib.decompressobj()
+
def decode(self, input, final=False):
- assert self.errors == 'strict'
- return zlib.decompress(input)
+ if final:
+ c = self.decompressobj.decompress(input)
+ return c + self.decompressobj.flush()
+ else:
+ return self.decompressobj.decompress(input)
+
+ def reset(self):
+ self.decompressobj = zlib.decompressobj()
class StreamWriter(Codec,codecs.StreamWriter):
pass
diff --git a/Lib/ftplib.py b/Lib/ftplib.py
index 937ee4e..9cb67dd 100644
--- a/Lib/ftplib.py
+++ b/Lib/ftplib.py
@@ -325,6 +325,14 @@ class FTP:
if rest is not None:
self.sendcmd("REST %s" % rest)
resp = self.sendcmd(cmd)
+ # Some servers apparently send a 200 reply to
+ # a LIST or STOR command, before the 150 reply
+ # (and way before the 226 reply). This seems to
+ # be in violation of the protocol (which only allows
+ # 1xx or error messages for LIST), so we just discard
+ # this response.
+ if resp[0] == '2':
+ resp = self.getresp()
if resp[0] != '1':
raise error_reply, resp
else:
@@ -332,6 +340,9 @@ class FTP:
if rest is not None:
self.sendcmd("REST %s" % rest)
resp = self.sendcmd(cmd)
+ # See above.
+ if resp[0] == '2':
+ resp = self.getresp()
if resp[0] != '1':
raise error_reply, resp
conn, sockaddr = sock.accept()
diff --git a/Lib/functools.py b/Lib/functools.py
index 12a527e..a54f030 100644
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -25,14 +25,14 @@ def update_wrapper(wrapper,
assigned is a tuple naming the attributes assigned directly
from the wrapped function to the wrapper function (defaults to
functools.WRAPPER_ASSIGNMENTS)
- updated is a tuple naming the attributes off the wrapper that
+ updated is a tuple naming the attributes of the wrapper that
are updated with the corresponding attribute from the wrapped
function (defaults to functools.WRAPPER_UPDATES)
"""
for attr in assigned:
setattr(wrapper, attr, getattr(wrapped, attr))
for attr in updated:
- getattr(wrapper, attr).update(getattr(wrapped, attr))
+ getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
# Return the wrapper so this can be used as a decorator via partial()
return wrapper
diff --git a/Lib/genericpath.py b/Lib/genericpath.py
new file mode 100644
index 0000000..1574cef
--- /dev/null
+++ b/Lib/genericpath.py
@@ -0,0 +1,77 @@
+"""
+Path operations common to more than one OS
+Do not use directly. The OS specific modules import the appropriate
+functions from this module themselves.
+"""
+import os
+import stat
+
+__all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime',
+ 'getsize', 'isdir', 'isfile']
+
+
+# Does a path exist?
+# This is false for dangling symbolic links on systems that support them.
+def exists(path):
+ """Test whether a path exists. Returns False for broken symbolic links"""
+ try:
+ st = os.stat(path)
+ except os.error:
+ return False
+ return True
+
+
+# This follows symbolic links, so both islink() and isdir() can be true
+# for the same path ono systems that support symlinks
+def isfile(path):
+ """Test whether a path is a regular file"""
+ try:
+ st = os.stat(path)
+ except os.error:
+ return False
+ return stat.S_ISREG(st.st_mode)
+
+
+# Is a path a directory?
+# This follows symbolic links, so both islink() and isdir()
+# can be true for the same path on systems that support symlinks
+def isdir(s):
+ """Return true if the pathname refers to an existing directory."""
+ try:
+ st = os.stat(s)
+ except os.error:
+ return False
+ return stat.S_ISDIR(st.st_mode)
+
+
+def getsize(filename):
+ """Return the size of a file, reported by os.stat()."""
+ return os.stat(filename).st_size
+
+
+def getmtime(filename):
+ """Return the last modification time of a file, reported by os.stat()."""
+ return os.stat(filename).st_mtime
+
+
+def getatime(filename):
+ """Return the last access time of a file, reported by os.stat()."""
+ return os.stat(filename).st_atime
+
+
+def getctime(filename):
+ """Return the metadata change time of a file, reported by os.stat()."""
+ return os.stat(filename).st_ctime
+
+
+# Return the longest prefix of all list elements.
+def commonprefix(m):
+ "Given a list of pathnames, returns the longest common leading component"
+ if not m: return ''
+ s1 = min(m)
+ s2 = max(m)
+ n = min(len(s1), len(s2))
+ for i in xrange(n):
+ if s1[i] != s2[i]:
+ return s1[:i]
+ return s1[:n]
diff --git a/Lib/gzip.py b/Lib/gzip.py
index 0bf29e8..c37d5a1 100644
--- a/Lib/gzip.py
+++ b/Lib/gzip.py
@@ -371,7 +371,12 @@ class GzipFile:
self.extrasize = 0
self.offset = 0
- def seek(self, offset):
+ def seek(self, offset, whence=0):
+ if whence:
+ if whence == 1:
+ offset = self.offset + offset
+ else:
+ raise ValueError('Seek from end not supported')
if self.mode == WRITE:
if offset < self.offset:
raise IOError('Negative seek in write mode')
diff --git a/Lib/hashlib.py b/Lib/hashlib.py
index 789e24e..78b5c0e 100644
--- a/Lib/hashlib.py
+++ b/Lib/hashlib.py
@@ -18,8 +18,37 @@ md5(), sha1(), sha224(), sha256(), sha384(), and sha512()
More algorithms may be available on your platform but the above are
guaranteed to exist.
-Choose your hash function wisely. Some have known weaknesses.
+Choose your hash function wisely. Some have known collision weaknesses.
sha384 and sha512 will be slow on 32 bit platforms.
+
+Hash objects have these methods:
+ - update(arg): Update the hash object with the string arg. Repeated calls
+ are equivalent to a single call with the concatenation of all
+ the arguments.
+ - digest(): Return the digest of the strings passed to the update() method
+ so far. This may contain non-ASCII characters, including
+ NUL bytes.
+ - hexdigest(): Like digest() except the digest is returned as a string of
+ double length, containing only hexadecimal digits.
+ - copy(): Return a copy (clone) of the hash object. This can be used to
+ efficiently compute the digests of strings that share a common
+ initial substring.
+
+For example, to obtain the digest of the string 'Nobody inspects the
+spammish repetition':
+
+ >>> import hashlib
+ >>> m = hashlib.md5()
+ >>> m.update("Nobody inspects")
+ >>> m.update(" the spammish repetition")
+ >>> m.digest()
+ '\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
+
+More condensed:
+
+ >>> hashlib.sha224("Nobody inspects the spammish repetition").hexdigest()
+ 'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
+
"""
diff --git a/Lib/httplib.py b/Lib/httplib.py
index 5ae5efc..1e0037f 100644
--- a/Lib/httplib.py
+++ b/Lib/httplib.py
@@ -704,7 +704,15 @@ class HTTPConnection:
if self.debuglevel > 0:
print "send:", repr(str)
try:
- self.sock.sendall(str)
+ blocksize=8192
+ if hasattr(str,'read') :
+ if self.debuglevel > 0: print "sendIng a read()able"
+ data=str.read(blocksize)
+ while data:
+ self.sock.sendall(data)
+ data=str.read(blocksize)
+ else:
+ self.sock.sendall(str)
except socket.error, v:
if v[0] == 32: # Broken pipe
self.close()
@@ -879,7 +887,21 @@ class HTTPConnection:
self.putrequest(method, url, **skips)
if body and ('content-length' not in header_names):
- self.putheader('Content-Length', str(len(body)))
+ thelen=None
+ try:
+ thelen=str(len(body))
+ except TypeError, te:
+ # If this is a file-like object, try to
+ # fstat its file descriptor
+ import os
+ try:
+ thelen = str(os.fstat(body.fileno()).st_size)
+ except (AttributeError, OSError):
+ # Don't send a length if this failed
+ if self.debuglevel > 0: print "Cannot stat!!"
+
+ if thelen is not None:
+ self.putheader('Content-Length',thelen)
for hdr, value in headers.iteritems():
self.putheader(hdr, value)
self.endheaders()
diff --git a/Lib/idlelib/CodeContext.py b/Lib/idlelib/CodeContext.py
index 74d5b70..436206f 100644
--- a/Lib/idlelib/CodeContext.py
+++ b/Lib/idlelib/CodeContext.py
@@ -54,25 +54,68 @@ class CodeContext:
def toggle_code_context_event(self, event=None):
if not self.label:
- self.pad_frame = Tkinter.Frame(self.editwin.top,
- bg=self.bgcolor, border=2,
- relief="sunken")
- self.label = Tkinter.Label(self.pad_frame,
- text="\n" * (self.context_depth - 1),
- anchor="w", justify="left",
- font=self.textfont,
- bg=self.bgcolor, fg=self.fgcolor,
- border=0,
- width=1, # Don't request more than we get
- )
- self.label.pack(side="top", fill="x", expand=True,
- padx=4, pady=0)
- self.pad_frame.pack(side="top", fill="x", expand=False,
- padx=0, pady=0,
- after=self.editwin.status_bar)
+ # The following code attempts to figure out the required border
+ # width and vertical padding required for the CodeContext widget
+ # to be perfectly aligned with the text in the main Text widget.
+ # This is done by retrieving the appropriate attributes from the
+ # editwin.text and editwin.text_frame widgets.
+ #
+ # All values are passed through int(str(<value>)), since some
+ # values may be pixel objects, which can't simply be added added
+ # to ints.
+ #
+ # This code is considered somewhat unstable since it relies on
+ # some of Tk's inner workings. However its effect is merely
+ # cosmetic; failure will only cause the CodeContext text to be
+ # somewhat misaligned with the text in the main Text widget.
+ #
+ # To avoid possible errors, all references to the inner workings
+ # of Tk are executed inside try/except blocks.
+
+ widgets_for_width_calc = self.editwin.text, self.editwin.text_frame
+
+ # calculate the required vertical padding
+ padx = 0
+ for widget in widgets_for_width_calc:
+ try:
+ # retrieve the "padx" attribte from widget's pack info
+ padx += int(str( widget.pack_info()['padx'] ))
+ except:
+ pass
+ try:
+ # retrieve the widget's "padx" attribte
+ padx += int(str( widget.cget('padx') ))
+ except:
+ pass
+
+ # calculate the required border width
+ border_width = 0
+ for widget in widgets_for_width_calc:
+ try:
+ # retrieve the widget's "border" attribte
+ border_width += int(str( widget.cget('border') ))
+ except:
+ pass
+
+ self.label = Tkinter.Label(self.editwin.top,
+ text="\n" * (self.context_depth - 1),
+ anchor="w", justify="left",
+ font=self.textfont,
+ bg=self.bgcolor, fg=self.fgcolor,
+ width=1, #don't request more than we get
+ padx=padx, #line up with text widget
+ border=border_width, #match border width
+ relief="sunken",
+ )
+
+ # CodeContext's label widget is packed before and above the
+ # text_frame widget, thus ensuring that it will appear directly
+ # above it.
+ self.label.pack(side="top", fill="x", expand=False,
+ before=self.editwin.text_frame)
+
else:
self.label.destroy()
- self.pad_frame.destroy()
self.label = None
idleConf.SetOption("extensions", "CodeContext", "visible",
str(self.label is not None))
diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py
index bc61afb..1841b1c 100644
--- a/Lib/idlelib/EditorWindow.py
+++ b/Lib/idlelib/EditorWindow.py
@@ -102,8 +102,8 @@ class EditorWindow(object):
self.top.instance_dict = {}
self.recent_files_path = os.path.join(idleConf.GetUserCfgDir(),
'recent-files.lst')
- self.vbar = vbar = Scrollbar(top, name='vbar')
self.text_frame = text_frame = Frame(top)
+ self.vbar = vbar = Scrollbar(text_frame, name='vbar')
self.width = idleConf.GetOption('main','EditorWindow','width')
self.text = text = MultiCallCreator(Text)(
text_frame, name='text', padx=5, wrap='none',
diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt
index 3b3d79a..43e5b45 100644
--- a/Lib/idlelib/NEWS.txt
+++ b/Lib/idlelib/NEWS.txt
@@ -3,6 +3,13 @@ What's New in IDLE 2.6a1?
*Release date: XX-XXX-200X*
+- Patch #1362975: Rework CodeContext indentation algorithm to
+ avoid hard-coding pixel widths.
+
+- Some syntax errors were being caught by tokenize during the tabnanny
+ check, resulting in obscure error messages. Do the syntax check
+ first. Bug 1562716, 1562719
+
- IDLE's version number takes a big jump to match the version number of
the Python release of which it's a part.
diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py
index 709b3a7..20d00be 100644
--- a/Lib/idlelib/PyShell.py
+++ b/Lib/idlelib/PyShell.py
@@ -351,6 +351,8 @@ class ModifiedInterpreter(InteractiveInterpreter):
def build_subprocess_arglist(self):
w = ['-W' + s for s in sys.warnoptions]
+ if 1/2 > 0: # account for new division
+ w.append('-Qnew')
# Maybe IDLE is installed and is being accessed via sys.path,
# or maybe it's not installed and the idle.py script is being
# run from the IDLE source directory.
@@ -726,6 +728,8 @@ class ModifiedInterpreter(InteractiveInterpreter):
raise
except:
if use_subprocess:
+ # When run w/o subprocess, both user and IDLE errors
+ # are printed here; skip message in that case.
print >> self.tkconsole.stderr, \
"IDLE internal error in runcode()"
self.showtraceback()
diff --git a/Lib/idlelib/ScriptBinding.py b/Lib/idlelib/ScriptBinding.py
index f325ad1..3746eb8 100644
--- a/Lib/idlelib/ScriptBinding.py
+++ b/Lib/idlelib/ScriptBinding.py
@@ -57,9 +57,10 @@ class ScriptBinding:
filename = self.getfilename()
if not filename:
return
+ if not self.checksyntax(filename):
+ return
if not self.tabnanny(filename):
return
- self.checksyntax(filename)
def tabnanny(self, filename):
f = open(filename, 'r')
@@ -76,9 +77,6 @@ class ScriptBinding:
self.editwin.gotoline(nag.get_lineno())
self.errorbox("Tab/space error", indent_message)
return False
- except IndentationError:
- # From tokenize(), let compile() in checksyntax find it again.
- pass
return True
def checksyntax(self, filename):
@@ -139,11 +137,11 @@ class ScriptBinding:
filename = self.getfilename()
if not filename:
return
- if not self.tabnanny(filename):
- return
code = self.checksyntax(filename)
if not code:
return
+ if not self.tabnanny(filename):
+ return
shell = self.shell
interp = shell.interp
if PyShell.use_subprocess:
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 0b498b5..986a415 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -403,6 +403,7 @@ def getabsfile(object, _filename=None):
return os.path.normcase(os.path.abspath(_filename))
modulesbyfile = {}
+_filesbymodname = {}
def getmodule(object, _filename=None):
"""Return the module an object was defined in, or None if not found."""
@@ -410,19 +411,32 @@ def getmodule(object, _filename=None):
return object
if hasattr(object, '__module__'):
return sys.modules.get(object.__module__)
+ # Try the filename to modulename cache
+ if _filename is not None and _filename in modulesbyfile:
+ return sys.modules.get(modulesbyfile[_filename])
+ # Try the cache again with the absolute file name
try:
file = getabsfile(object, _filename)
except TypeError:
return None
if file in modulesbyfile:
return sys.modules.get(modulesbyfile[file])
- for module in sys.modules.values():
+ # Update the filename to module name cache and check yet again
+ # Copy sys.modules in order to cope with changes while iterating
+ for modname, module in sys.modules.items():
if ismodule(module) and hasattr(module, '__file__'):
+ f = module.__file__
+ if f == _filesbymodname.get(modname, None):
+ # Have already mapped this module, so skip it
+ continue
+ _filesbymodname[modname] = f
f = getabsfile(module)
+ # Always map to the name the module knows itself by
modulesbyfile[f] = modulesbyfile[
os.path.realpath(f)] = module.__name__
if file in modulesbyfile:
return sys.modules.get(modulesbyfile[file])
+ # Check the main module
main = sys.modules['__main__']
if not hasattr(object, '__name__'):
return None
@@ -430,6 +444,7 @@ def getmodule(object, _filename=None):
mainobject = getattr(main, object.__name__)
if mainobject is object:
return main
+ # Check builtins
builtin = sys.modules['__builtin__']
if hasattr(builtin, object.__name__):
builtinobject = getattr(builtin, object.__name__)
@@ -444,7 +459,7 @@ def findsource(object):
in the file and the line number indexes a line in that list. An IOError
is raised if the source code cannot be retrieved."""
file = getsourcefile(object) or getfile(object)
- module = getmodule(object)
+ module = getmodule(object, file)
if module:
lines = linecache.getlines(file, module.__dict__)
else:
@@ -457,9 +472,24 @@ def findsource(object):
if isclass(object):
name = object.__name__
- pat = re.compile(r'^\s*class\s*' + name + r'\b')
+ pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
+ # make some effort to find the best matching class definition:
+ # use the one with the least indentation, which is the one
+ # that's most probably not inside a function definition.
+ candidates = []
for i in range(len(lines)):
- if pat.match(lines[i]): return lines, i
+ match = pat.match(lines[i])
+ if match:
+ # if it's at toplevel, it's already the best one
+ if lines[i][0] == 'c':
+ return lines, i
+ # else add whitespace to candidate list
+ candidates.append((match.group(1), i))
+ if candidates:
+ # this will sort by whitespace, and by line number,
+ # less whitespace first
+ candidates.sort()
+ return lines, candidates[0][1]
else:
raise IOError('could not find class definition')
diff --git a/Lib/lib-tk/Tix.py b/Lib/lib-tk/Tix.py
index 1d2fdad..ad6126a 100755
--- a/Lib/lib-tk/Tix.py
+++ b/Lib/lib-tk/Tix.py
@@ -421,7 +421,7 @@ class TixSubWidget(TixWidget):
except:
plist = []
- if (not check_intermediate) or len(plist) < 2:
+ if not check_intermediate:
# immediate descendant
TixWidget.__init__(self, master, None, None, {'name' : name})
else:
@@ -437,6 +437,9 @@ class TixSubWidget(TixWidget):
parent = TixSubWidget(parent, plist[i],
destroy_physically=0,
check_intermediate=0)
+ # The Tk widget name is in plist, not in name
+ if plist:
+ name = plist[-1]
TixWidget.__init__(self, parent, None, None, {'name' : name})
self.destroy_physically = destroy_physically
diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py
index bea130c..f8538ed 100644
--- a/Lib/lib-tk/Tkinter.py
+++ b/Lib/lib-tk/Tkinter.py
@@ -3017,7 +3017,7 @@ class Text(Widget):
self.tk.call(self._w, 'scan', 'dragto', x, y)
def search(self, pattern, index, stopindex=None,
forwards=None, backwards=None, exact=None,
- regexp=None, nocase=None, count=None):
+ regexp=None, nocase=None, count=None, elide=None):
"""Search PATTERN beginning from INDEX until STOPINDEX.
Return the index of the first character of a match or an empty string."""
args = [self._w, 'search']
@@ -3026,6 +3026,7 @@ class Text(Widget):
if exact: args.append('-exact')
if regexp: args.append('-regexp')
if nocase: args.append('-nocase')
+ if elide: args.append('-elide')
if count: args.append('-count'); args.append(count)
if pattern[0] == '-': args.append('--')
args.append(pattern)
diff --git a/Lib/lib-tk/tkMessageBox.py b/Lib/lib-tk/tkMessageBox.py
index aff069b..d14ca86 100644
--- a/Lib/lib-tk/tkMessageBox.py
+++ b/Lib/lib-tk/tkMessageBox.py
@@ -102,6 +102,15 @@ def askyesno(title=None, message=None, **options):
s = _show(title, message, QUESTION, YESNO, **options)
return s == YES
+def askyesnocancel(title=None, message=None, **options):
+ "Ask a question; return true if the answer is yes, None if cancelled."
+ s = _show(title, message, QUESTION, YESNOCANCEL, **options)
+ # s might be a Tcl index object, so convert it to a string
+ s = str(s)
+ if s == CANCEL:
+ return None
+ return s == YES
+
def askretrycancel(title=None, message=None, **options):
"Ask if operation should be retried; return true if the answer is yes"
s = _show(title, message, WARNING, RETRYCANCEL, **options)
@@ -119,4 +128,5 @@ if __name__ == "__main__":
print "question", askquestion("Spam", "Question?")
print "proceed", askokcancel("Spam", "Proceed?")
print "yes/no", askyesno("Spam", "Got it?")
+ print "yes/no/cancel", askyesnocancel("Spam", "Want it?")
print "try again", askretrycancel("Spam", "Try again?")
diff --git a/Lib/lib-tk/tkSimpleDialog.py b/Lib/lib-tk/tkSimpleDialog.py
index 7b70411..3411d94 100644
--- a/Lib/lib-tk/tkSimpleDialog.py
+++ b/Lib/lib-tk/tkSimpleDialog.py
@@ -46,8 +46,13 @@ class Dialog(Toplevel):
title -- the dialog title
'''
Toplevel.__init__(self, parent)
- self.transient(parent)
+ # If the master is not viewable, don't
+ # make the child transient, or else it
+ # would be opened withdrawn
+ if parent.winfo_viewable():
+ self.transient(parent)
+
if title:
self.title(title)
@@ -124,9 +129,10 @@ class Dialog(Toplevel):
self.withdraw()
self.update_idletasks()
- self.apply()
-
- self.cancel()
+ try:
+ self.apply()
+ finally:
+ self.cancel()
def cancel(self, event=None):
diff --git a/Lib/lib-tk/turtle.py b/Lib/lib-tk/turtle.py
index 01a55b1..fcde9af 100644
--- a/Lib/lib-tk/turtle.py
+++ b/Lib/lib-tk/turtle.py
@@ -15,6 +15,7 @@ pictures can easily be drawn.
"""
from math import * # Also for export
+from time import sleep
import Tkinter
speeds = ['fastest', 'fast', 'normal', 'slow', 'slowest']
@@ -949,7 +950,6 @@ def demo2():
if __name__ == '__main__':
- from time import sleep
demo()
sleep(3)
demo2()
diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py
index 953afe9..b57a9af 100644
--- a/Lib/logging/__init__.py
+++ b/Lib/logging/__init__.py
@@ -214,7 +214,7 @@ class LogRecord:
information to be logged.
"""
def __init__(self, name, level, pathname, lineno,
- msg, args, exc_info, func):
+ msg, args, exc_info, func=None):
"""
Initialize a logging record with interesting information.
"""
@@ -910,10 +910,11 @@ class Manager:
Ensure that children of the placeholder ph are connected to the
specified logger.
"""
- #for c in ph.loggers:
+ name = alogger.name
+ namelen = len(name)
for c in ph.loggerMap.keys():
- # XXX Is the following correct? Shouldn't it be >= 0?
- if string.find(c.parent.name, alogger.name) != 0:
+ #The if means ... if not c.parent.name.startswith(nm)
+ if c.parent.name[:namelen] != name:
alogger.parent = c.parent
c.parent = alogger
diff --git a/Lib/logging/config.py b/Lib/logging/config.py
index a31e8d0..a9970d0 100644
--- a/Lib/logging/config.py
+++ b/Lib/logging/config.py
@@ -27,7 +27,7 @@ Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved.
To use, simply 'import logging' and log away!
"""
-import sys, logging, logging.handlers, string, socket, struct, os, traceback
+import sys, logging, logging.handlers, string, socket, struct, os, traceback, types
try:
import thread
@@ -110,7 +110,7 @@ def _create_formatters(cp):
flist = string.split(flist, ",")
formatters = {}
for form in flist:
- sectname = "formatter_%s" % form
+ sectname = "formatter_%s" % string.strip(form)
opts = cp.options(sectname)
if "format" in opts:
fs = cp.get(sectname, "format", 1)
@@ -139,7 +139,7 @@ def _install_handlers(cp, formatters):
handlers = {}
fixups = [] #for inter-handler references
for hand in hlist:
- sectname = "handler_%s" % hand
+ sectname = "handler_%s" % string.strip(hand)
klass = cp.get(sectname, "class")
opts = cp.options(sectname)
if "formatter" in opts:
@@ -176,6 +176,7 @@ def _install_loggers(cp, handlers):
# configure the root first
llist = cp.get("loggers", "keys")
llist = string.split(llist, ",")
+ llist = map(lambda x: string.strip(x), llist)
llist.remove("root")
sectname = "logger_root"
root = logging.root
@@ -190,7 +191,7 @@ def _install_loggers(cp, handlers):
if len(hlist):
hlist = string.split(hlist, ",")
for hand in hlist:
- log.addHandler(handlers[hand])
+ log.addHandler(handlers[string.strip(hand)])
#and now the others...
#we don't want to lose the existing loggers,
@@ -225,7 +226,7 @@ def _install_loggers(cp, handlers):
if len(hlist):
hlist = string.split(hlist, ",")
for hand in hlist:
- logger.addHandler(handlers[hand])
+ logger.addHandler(handlers[string.strip(hand)])
#Disable any old loggers. There's no point deleting
#them as other threads may continue to hold references
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index a0255ce..17eca8a 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -590,11 +590,11 @@ class SysLogHandler(logging.Handler):
self.address = address
self.facility = facility
if type(address) == types.StringType:
- self._connect_unixsocket(address)
self.unixsocket = 1
+ self._connect_unixsocket(address)
else:
- self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.unixsocket = 0
+ self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.formatter = None
diff --git a/Lib/macpath.py b/Lib/macpath.py
index f93ceb1..d389d70 100644
--- a/Lib/macpath.py
+++ b/Lib/macpath.py
@@ -2,6 +2,7 @@
import os
from stat import *
+from genericpath import *
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -101,31 +102,6 @@ def ismount(s):
components = split(s)
return len(components) == 2 and components[1] == ''
-def isdir(s):
- """Return true if the pathname refers to an existing directory."""
-
- try:
- st = os.stat(s)
- except os.error:
- return 0
- return S_ISDIR(st.st_mode)
-
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()."""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()."""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()."""
- return os.stat(filename).st_atime
-
-
def islink(s):
"""Return true if the pathname refers to a symbolic link."""
@@ -135,29 +111,6 @@ def islink(s):
except:
return False
-
-def isfile(s):
- """Return true if the pathname refers to an existing regular file."""
-
- try:
- st = os.stat(s)
- except os.error:
- return False
- return S_ISREG(st.st_mode)
-
-def getctime(filename):
- """Return the creation time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
-
-def exists(s):
- """Test whether a path exists. Returns False for broken symbolic links"""
-
- try:
- st = os.stat(s)
- except os.error:
- return False
- return True
-
# Is `stat`/`lstat` a meaningful difference on the Mac? This is safe in any
# case.
@@ -170,20 +123,6 @@ def lexists(path):
return False
return True
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-
def expandvars(path):
"""Dummy to retain interface-compatibility with other operating systems."""
return path
diff --git a/Lib/mailbox.py b/Lib/mailbox.py
index ed7c7d1..0843430 100755
--- a/Lib/mailbox.py
+++ b/Lib/mailbox.py
@@ -2,6 +2,12 @@
"""Read/write support for Maildir, mbox, MH, Babyl, and MMDF mailboxes."""
+# Notes for authors of new mailbox subclasses:
+#
+# Remember to fsync() changes to disk before closing a modified file
+# or returning from a flush() method. See functions _sync_flush() and
+# _sync_close().
+
import sys
import os
import time
@@ -235,7 +241,7 @@ class Maildir(Mailbox):
try:
self._dump_message(message, tmp_file)
finally:
- tmp_file.close()
+ _sync_close(tmp_file)
if isinstance(message, MaildirMessage):
subdir = message.get_subdir()
suffix = self.colon + message.get_info()
@@ -246,7 +252,19 @@ class Maildir(Mailbox):
suffix = ''
uniq = os.path.basename(tmp_file.name).split(self.colon)[0]
dest = os.path.join(self._path, subdir, uniq + suffix)
- os.rename(tmp_file.name, dest)
+ try:
+ if hasattr(os, 'link'):
+ os.link(tmp_file.name, dest)
+ os.remove(tmp_file.name)
+ else:
+ os.rename(tmp_file.name, dest)
+ except OSError, e:
+ os.remove(tmp_file.name)
+ if e.errno == errno.EEXIST:
+ raise ExternalClashError('Name clash with existing message: %s'
+ % dest)
+ else:
+ raise
if isinstance(message, MaildirMessage):
os.utime(dest, (os.path.getatime(dest), message.get_date()))
return uniq
@@ -364,12 +382,14 @@ class Maildir(Mailbox):
def get_folder(self, folder):
"""Return a Maildir instance for the named folder."""
- return Maildir(os.path.join(self._path, '.' + folder), create=False)
+ return Maildir(os.path.join(self._path, '.' + folder),
+ factory=self._factory,
+ create=False)
def add_folder(self, folder):
"""Create a folder and return a Maildir instance representing it."""
path = os.path.join(self._path, '.' + folder)
- result = Maildir(path)
+ result = Maildir(path, factory=self._factory)
maildirfolder_path = os.path.join(path, 'maildirfolder')
if not os.path.exists(maildirfolder_path):
os.close(os.open(maildirfolder_path, os.O_CREAT | os.O_WRONLY))
@@ -420,12 +440,17 @@ class Maildir(Mailbox):
except OSError, e:
if e.errno == errno.ENOENT:
Maildir._count += 1
- return open(path, 'wb+')
+ try:
+ return _create_carefully(path)
+ except OSError, e:
+ if e.errno != errno.EEXIST:
+ raise
else:
raise
- else:
- raise ExternalClashError('Name clash prevented file creation: %s' %
- path)
+
+ # Fall through to here if stat succeeded or open raised EEXIST.
+ raise ExternalClashError('Name clash prevented file creation: %s' %
+ path)
def _refresh(self):
"""Update table of contents mapping."""
@@ -560,7 +585,8 @@ class _singlefileMailbox(Mailbox):
new_file.close()
os.remove(new_file.name)
raise
- new_file.close()
+ _sync_close(new_file)
+ # self._file is about to get replaced, so no need to sync.
self._file.close()
try:
os.rename(new_file.name, self._path)
@@ -575,7 +601,7 @@ class _singlefileMailbox(Mailbox):
self._toc = new_toc
self._pending = False
if self._locked:
- _lock_file(new_file, dotlock=False)
+ _lock_file(self._file, dotlock=False)
def _pre_mailbox_hook(self, f):
"""Called before writing the mailbox to file f."""
@@ -594,7 +620,7 @@ class _singlefileMailbox(Mailbox):
self.flush()
if self._locked:
self.unlock()
- self._file.close()
+ self._file.close() # Sync has been done by self.flush() above.
def _lookup(self, key=None):
"""Return (start, stop) or raise KeyError."""
@@ -784,7 +810,7 @@ class MH(Mailbox):
if self._locked:
_unlock_file(f)
finally:
- f.close()
+ _sync_close(f)
return new_key
def remove(self, key):
@@ -831,7 +857,7 @@ class MH(Mailbox):
if self._locked:
_unlock_file(f)
finally:
- f.close()
+ _sync_close(f)
def get_message(self, key):
"""Return a Message representation or raise a KeyError."""
@@ -918,7 +944,7 @@ class MH(Mailbox):
"""Unlock the mailbox if it is locked."""
if self._locked:
_unlock_file(self._file)
- self._file.close()
+ _sync_close(self._file)
del self._file
self._locked = False
@@ -941,11 +967,13 @@ class MH(Mailbox):
def get_folder(self, folder):
"""Return an MH instance for the named folder."""
- return MH(os.path.join(self._path, folder), create=False)
+ return MH(os.path.join(self._path, folder),
+ factory=self._factory, create=False)
def add_folder(self, folder):
"""Create a folder and return an MH instance representing it."""
- return MH(os.path.join(self._path, folder))
+ return MH(os.path.join(self._path, folder),
+ factory=self._factory)
def remove_folder(self, folder):
"""Delete the named folder, which must be empty."""
@@ -1013,7 +1041,7 @@ class MH(Mailbox):
else:
f.write('\n')
finally:
- f.close()
+ _sync_close(f)
def pack(self):
"""Re-name messages to eliminate numbering gaps. Invalidates keys."""
@@ -1023,27 +1051,13 @@ class MH(Mailbox):
for key in self.iterkeys():
if key - 1 != prev:
changes.append((key, prev + 1))
- f = open(os.path.join(self._path, str(key)), 'r+')
- try:
- if self._locked:
- _lock_file(f)
- try:
- if hasattr(os, 'link'):
- os.link(os.path.join(self._path, str(key)),
- os.path.join(self._path, str(prev + 1)))
- if sys.platform == 'os2emx':
- # cannot unlink an open file on OS/2
- f.close()
- os.unlink(os.path.join(self._path, str(key)))
- else:
- f.close()
- os.rename(os.path.join(self._path, str(key)),
- os.path.join(self._path, str(prev + 1)))
- finally:
- if self._locked:
- _unlock_file(f)
- finally:
- f.close()
+ if hasattr(os, 'link'):
+ os.link(os.path.join(self._path, str(key)),
+ os.path.join(self._path, str(prev + 1)))
+ os.unlink(os.path.join(self._path, str(key)))
+ else:
+ os.rename(os.path.join(self._path, str(key)),
+ os.path.join(self._path, str(prev + 1)))
prev += 1
self._next_key = prev + 1
if len(changes) == 0:
@@ -1867,6 +1881,15 @@ def _create_temporary(path):
socket.gethostname(),
os.getpid()))
+def _sync_flush(f):
+ """Ensure changes to file f are physically on disk."""
+ f.flush()
+ os.fsync(f.fileno())
+
+def _sync_close(f):
+ """Close file f, ensuring all changes are physically on disk."""
+ _sync_flush(f)
+ f.close()
## Start: classes from the original module (for backward compatibility).
diff --git a/Lib/ntpath.py b/Lib/ntpath.py
index 7a79b53..b32ec16 100644
--- a/Lib/ntpath.py
+++ b/Lib/ntpath.py
@@ -8,6 +8,7 @@ module as os.path.
import os
import stat
import sys
+from genericpath import *
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -206,86 +207,18 @@ def dirname(p):
"""Returns the directory component of a pathname"""
return split(p)[0]
-
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()"""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()"""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()"""
- return os.stat(filename).st_atime
-
-def getctime(filename):
- """Return the creation time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
-
# Is a path a symbolic link?
# This will always return false on systems where posix.lstat doesn't exist.
def islink(path):
- """Test for symbolic link. On WindowsNT/95 always returns false"""
+ """Test for symbolic link.
+ On WindowsNT/95 and OS/2 always returns false
+ """
return False
-
-# Does a path exist?
-
-def exists(path):
- """Test whether a path exists"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return True
-
+# alias exists to lexists
lexists = exists
-
-# Is a path a dos directory?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isdir(path):
- """Test whether a path is a directory"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISDIR(st.st_mode)
-
-
-# Is a path a regular file?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isfile(path):
- """Test whether a path is a regular file"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISREG(st.st_mode)
-
-
# Is a path a mount point? Either a root (with or without drive letter)
# or an UNC path with at most a / or \ after the mount point.
diff --git a/Lib/os.py b/Lib/os.py
index 5ee3d4b..35f97fb 100644
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -156,11 +156,17 @@ def makedirs(name, mode=0777):
recursive.
"""
+ from errno import EEXIST
head, tail = path.split(name)
if not tail:
head, tail = path.split(head)
if head and tail and not path.exists(head):
- makedirs(head, mode)
+ try:
+ makedirs(head, mode)
+ except OSError, e:
+ # be happy if someone already created the path
+ if e.errno != EEXIST:
+ raise
if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists
return
mkdir(name, mode)
diff --git a/Lib/os2emxpath.py b/Lib/os2emxpath.py
index a841422..4e85c4d 100644
--- a/Lib/os2emxpath.py
+++ b/Lib/os2emxpath.py
@@ -7,6 +7,9 @@ module as os.path.
import os
import stat
+from genericpath import *
+from ntpath import (expanduser, expandvars, isabs, islink, splitdrive,
+ splitext, split, walk)
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -36,18 +39,6 @@ def normcase(s):
return s.replace('\\', '/').lower()
-# Return whether a path is absolute.
-# Trivial in Posix, harder on the Mac or MS-DOS.
-# For DOS it is absolute if it starts with a slash or backslash (current
-# volume), or if a pathname after the volume letter and colon / UNC resource
-# starts with a slash or backslash.
-
-def isabs(s):
- """Test whether a path is absolute"""
- s = splitdrive(s)[1]
- return s != '' and s[:1] in '/\\'
-
-
# Join two (or more) paths.
def join(a, *p):
@@ -63,17 +54,6 @@ def join(a, *p):
return path
-# Split a path in a drive specification (a drive letter followed by a
-# colon) and the path specification.
-# It is always true that drivespec + pathspec == p
-def splitdrive(p):
- """Split a pathname into drive and path specifiers. Returns a 2-tuple
-"(drive,path)"; either part may be empty"""
- if p[1:2] == ':':
- return p[0:2], p[2:]
- return '', p
-
-
# Parse UNC paths
def splitunc(p):
"""Split a pathname into UNC mount point and relative path specifiers.
@@ -103,57 +83,6 @@ def splitunc(p):
return '', p
-# Split a path in head (everything up to the last '/') and tail (the
-# rest). After the trailing '/' is stripped, the invariant
-# join(head, tail) == p holds.
-# The resulting head won't end in '/' unless it is the root.
-
-def split(p):
- """Split a pathname.
-
- Return tuple (head, tail) where tail is everything after the final slash.
- Either part may be empty."""
-
- d, p = splitdrive(p)
- # set i to index beyond p's last slash
- i = len(p)
- while i and p[i-1] not in '/\\':
- i = i - 1
- head, tail = p[:i], p[i:] # now tail has no slashes
- # remove trailing slashes from head, unless it's all slashes
- head2 = head
- while head2 and head2[-1] in '/\\':
- head2 = head2[:-1]
- head = head2 or head
- return d + head, tail
-
-
-# Split a path in root and extension.
-# The extension is everything starting at the last dot in the last
-# pathname component; the root is everything before that.
-# It is always true that root + ext == p.
-
-def splitext(p):
- """Split the extension from a pathname.
-
- Extension is everything from the last dot to the end.
- Return (root, ext), either part may be empty."""
- root, ext = '', ''
- for c in p:
- if c in ['/','\\']:
- root, ext = root + ext + c, ''
- elif c == '.':
- if ext:
- root, ext = root + ext, c
- else:
- ext = c
- elif ext:
- ext = ext + c
- else:
- root = root + c
- return root, ext
-
-
# Return the tail (basename) part of a path.
def basename(p):
@@ -168,84 +97,12 @@ def dirname(p):
return split(p)[0]
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()"""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()"""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()"""
- return os.stat(filename).st_atime
-
-def getctime(filename):
- """Return the creation time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
-
-# Is a path a symbolic link?
-# This will always return false on systems where posix.lstat doesn't exist.
-
-def islink(path):
- """Test for symbolic link. On OS/2 always returns false"""
- return False
-
-
-# Does a path exist?
-# This is false for dangling symbolic links.
-
-def exists(path):
- """Test whether a path exists"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return True
-
+# alias exists to lexists
lexists = exists
# Is a path a directory?
-def isdir(path):
- """Test whether a path is a directory"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISDIR(st.st_mode)
-
-
-# Is a path a regular file?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isfile(path):
- """Test whether a path is a regular file"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISREG(st.st_mode)
-
-
# Is a path a mount point? Either a root (with or without drive letter)
# or an UNC path with at most a / or \ after the mount point.
@@ -258,131 +115,6 @@ def ismount(path):
return len(p) == 1 and p[0] in '/\\'
-# Directory tree walk.
-# For each directory under top (including top itself, but excluding
-# '.' and '..'), func(arg, dirname, filenames) is called, where
-# dirname is the name of the directory and filenames is the list
-# of files (and subdirectories etc.) in the directory.
-# The func may modify the filenames list, to implement a filter,
-# or to impose a different order of visiting.
-
-def walk(top, func, arg):
- """Directory tree walk whth callback function.
-
- walk(top, func, arg) calls func(arg, d, files) for each directory d
- in the tree rooted at top (including top itself); files is a list
- of all the files and subdirs in directory d."""
- try:
- names = os.listdir(top)
- except os.error:
- return
- func(arg, top, names)
- exceptions = ('.', '..')
- for name in names:
- if name not in exceptions:
- name = join(top, name)
- if isdir(name):
- walk(name, func, arg)
-
-
-# Expand paths beginning with '~' or '~user'.
-# '~' means $HOME; '~user' means that user's home directory.
-# If the path doesn't begin with '~', or if the user or $HOME is unknown,
-# the path is returned unchanged (leaving error reporting to whatever
-# function is called with the expanded path as argument).
-# See also module 'glob' for expansion of *, ? and [...] in pathnames.
-# (A function should also be defined to do full *sh-style environment
-# variable expansion.)
-
-def expanduser(path):
- """Expand ~ and ~user constructs.
-
- If user or $HOME is unknown, do nothing."""
- if path[:1] != '~':
- return path
- i, n = 1, len(path)
- while i < n and path[i] not in '/\\':
- i = i + 1
- if i == 1:
- if 'HOME' in os.environ:
- userhome = os.environ['HOME']
- elif not 'HOMEPATH' in os.environ:
- return path
- else:
- try:
- drive = os.environ['HOMEDRIVE']
- except KeyError:
- drive = ''
- userhome = join(drive, os.environ['HOMEPATH'])
- else:
- return path
- return userhome + path[i:]
-
-
-# Expand paths containing shell variable substitutions.
-# The following rules apply:
-# - no expansion within single quotes
-# - no escape character, except for '$$' which is translated into '$'
-# - ${varname} is accepted.
-# - varnames can be made out of letters, digits and the character '_'
-# XXX With COMMAND.COM you can use any characters in a variable name,
-# XXX except '^|<>='.
-
-def expandvars(path):
- """Expand shell variables of form $var and ${var}.
-
- Unknown variables are left unchanged."""
- if '$' not in path:
- return path
- import string
- varchars = string.letters + string.digits + '_-'
- res = ''
- index = 0
- pathlen = len(path)
- while index < pathlen:
- c = path[index]
- if c == '\'': # no expansion within single quotes
- path = path[index + 1:]
- pathlen = len(path)
- try:
- index = path.index('\'')
- res = res + '\'' + path[:index + 1]
- except ValueError:
- res = res + path
- index = pathlen - 1
- elif c == '$': # variable or '$$'
- if path[index + 1:index + 2] == '$':
- res = res + c
- index = index + 1
- elif path[index + 1:index + 2] == '{':
- path = path[index+2:]
- pathlen = len(path)
- try:
- index = path.index('}')
- var = path[:index]
- if var in os.environ:
- res = res + os.environ[var]
- except ValueError:
- res = res + path
- index = pathlen - 1
- else:
- var = ''
- index = index + 1
- c = path[index:index + 1]
- while c != '' and c in varchars:
- var = var + c
- index = index + 1
- c = path[index:index + 1]
- if var in os.environ:
- res = res + os.environ[var]
- if c != '':
- res = res + c
- else:
- res = res + c
- index = index + 1
- return res
-
-
# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
def normpath(path):
diff --git a/Lib/pdb.py b/Lib/pdb.py
index 2bc836f..88303d0 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -28,7 +28,7 @@ def raw_input(prompt):
return sys.stdin.readline()
def find_function(funcname, filename):
- cre = re.compile(r'def\s+%s\s*[(]' % funcname)
+ cre = re.compile(r'def\s+%s\s*[(]' % re.escape(funcname))
try:
fp = open(filename)
except IOError:
diff --git a/Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py b/Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py
index 5d02ea3..773d1d7 100644
--- a/Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py
+++ b/Lib/plat-mac/lib-scriptpackages/StdSuites/AppleScript_Suite.py
@@ -301,7 +301,7 @@ class AppleScript_Suite_Events:
return _arguments['----']
def as_(self, _object, _attributes={}, **_arguments):
- """as_: Coercion
+ """as: Coercion
Required argument: an AE object reference
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: anything
diff --git a/Lib/plat-sunos5/STROPTS.py b/Lib/plat-sunos5/STROPTS.py
index e95db93..4970bd7 100644
--- a/Lib/plat-sunos5/STROPTS.py
+++ b/Lib/plat-sunos5/STROPTS.py
@@ -1550,7 +1550,7 @@ IE_NOMEM = -1
AS_PAGLCK = 0x80
AS_CLAIMGAP = 0x40
AS_UNMAPWAIT = 0x20
-def AS_TYPE_64BIT(as): return \
+def AS_TYPE_64BIT(as_): return \
AS_LREP_LINKEDLIST = 0
AS_LREP_SKIPLIST = 1
diff --git a/Lib/posixpath.py b/Lib/posixpath.py
index 9eac6bc..1521236 100644
--- a/Lib/posixpath.py
+++ b/Lib/posixpath.py
@@ -12,6 +12,7 @@ for manipulation of the pathname component of URLs.
import os
import stat
+from genericpath import *
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -105,50 +106,24 @@ def splitdrive(p):
return '', p
-# Return the tail (basename) part of a path.
+# Return the tail (basename) part of a path, same as split(path)[1].
def basename(p):
"""Returns the final component of a pathname"""
- return split(p)[1]
+ i = p.rfind('/') + 1
+ return p[i:]
-# Return the head (dirname) part of a path.
+# Return the head (dirname) part of a path, same as split(path)[0].
def dirname(p):
"""Returns the directory component of a pathname"""
- return split(p)[0]
-
-
-# Return the longest prefix of all list elements.
-
-def commonprefix(m):
- "Given a list of pathnames, returns the longest common leading component"
- if not m: return ''
- s1 = min(m)
- s2 = max(m)
- n = min(len(s1), len(s2))
- for i in xrange(n):
- if s1[i] != s2[i]:
- return s1[:i]
- return s1[:n]
-
-# Get size, mtime, atime of files.
-
-def getsize(filename):
- """Return the size of a file, reported by os.stat()."""
- return os.stat(filename).st_size
-
-def getmtime(filename):
- """Return the last modification time of a file, reported by os.stat()."""
- return os.stat(filename).st_mtime
-
-def getatime(filename):
- """Return the last access time of a file, reported by os.stat()."""
- return os.stat(filename).st_atime
+ i = p.rfind('/') + 1
+ head = p[:i]
+ if head and head != '/'*len(head):
+ head = head.rstrip('/')
+ return head
-def getctime(filename):
- """Return the metadata change time of a file, reported by os.stat()."""
- return os.stat(filename).st_ctime
# Is a path a symbolic link?
# This will always return false on systems where os.lstat doesn't exist.
@@ -161,19 +136,6 @@ def islink(path):
return False
return stat.S_ISLNK(st.st_mode)
-
-# Does a path exist?
-# This is false for dangling symbolic links.
-
-def exists(path):
- """Test whether a path exists. Returns False for broken symbolic links"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return True
-
-
# Being true for dangling symbolic links is also useful.
def lexists(path):
@@ -185,32 +147,6 @@ def lexists(path):
return True
-# Is a path a directory?
-# This follows symbolic links, so both islink() and isdir() can be true
-# for the same path.
-
-def isdir(path):
- """Test whether a path is a directory"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISDIR(st.st_mode)
-
-
-# Is a path a regular file?
-# This follows symbolic links, so both islink() and isfile() can be true
-# for the same path.
-
-def isfile(path):
- """Test whether a path is a regular file"""
- try:
- st = os.stat(path)
- except os.error:
- return False
- return stat.S_ISREG(st.st_mode)
-
-
# Are two filenames really pointing to the same file?
def samefile(f1, f2):
@@ -328,8 +264,7 @@ def expanduser(path):
except KeyError:
return path
userhome = pwent.pw_dir
- if userhome.endswith('/'):
- i += 1
+ userhome = userhome.rstrip('/')
return userhome + path[i:]
diff --git a/Lib/pstats.py b/Lib/pstats.py
index 2acdadc..ba0b804 100644
--- a/Lib/pstats.py
+++ b/Lib/pstats.py
@@ -116,7 +116,7 @@ class Stats:
def load_stats(self, arg):
if not arg: self.stats = {}
- elif type(arg) == type(""):
+ elif isinstance(arg, basestring):
f = open(arg, 'rb')
self.stats = marshal.load(f)
f.close()
diff --git a/Lib/pty.py b/Lib/pty.py
index fae162d..889113c 100644
--- a/Lib/pty.py
+++ b/Lib/pty.py
@@ -118,6 +118,10 @@ def fork():
if (slave_fd > STDERR_FILENO):
os.close (slave_fd)
+ # Explicitly open the tty to make it become a controlling tty.
+ tmp_fd = os.open(os.ttyname(STDOUT_FILENO), os.O_RDWR)
+ os.close(tmp_fd)
+
# Parent and child process.
return pid, master_fd
diff --git a/Lib/pyclbr.py b/Lib/pyclbr.py
index 0731224..079b38c 100644
--- a/Lib/pyclbr.py
+++ b/Lib/pyclbr.py
@@ -172,7 +172,7 @@ def _readmodule(module, path, inpackage=None):
# else it's a nested def
else:
# it's a function
- dict[meth_name] = Function(module, meth_name, file, lineno)
+ dict[meth_name] = Function(fullmodule, meth_name, file, lineno)
stack.append((None, thisindent)) # Marker for nested fns
elif token == 'class':
lineno, thisindent = start
diff --git a/Lib/sgmllib.py b/Lib/sgmllib.py
index 3020d11..3ab57c2 100644
--- a/Lib/sgmllib.py
+++ b/Lib/sgmllib.py
@@ -29,12 +29,7 @@ starttagopen = re.compile('<[>a-zA-Z]')
shorttagopen = re.compile('<[a-zA-Z][-.a-zA-Z0-9]*/')
shorttag = re.compile('<([a-zA-Z][-.a-zA-Z0-9]*)/([^/]*)/')
piclose = 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'</?[a-zA-Z][-_.:a-zA-Z0-9]*\s*/?\s*(?=[<>])')
+endbracket = re.compile('[<>]')
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*'
@@ -254,10 +249,14 @@ class SGMLParser(markupbase.ParserBase):
self.finish_shorttag(tag, data)
self.__starttag_text = rawdata[start_pos:match.end(1) + 1]
return k
- match = starttag.match(rawdata, i)
+ # 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)
if not match:
return -1
- j = match.end(0)
+ j = match.start(0)
# Now parse the data between i+1 and j into a tag and attrs
attrs = []
if rawdata[i:i+2] == '<>':
@@ -306,10 +305,10 @@ class SGMLParser(markupbase.ParserBase):
# Internal -- parse endtag
def parse_endtag(self, i):
rawdata = self.rawdata
- match = endtag.match(rawdata, i)
+ match = endbracket.search(rawdata, i+1)
if not match:
return -1
- j = match.end(0)
+ j = match.start(0)
tag = rawdata[i+2:j].strip().lower()
if rawdata[j] == '>':
j = j+1
diff --git a/Lib/smtplib.py b/Lib/smtplib.py
index 9c8c4fa..a7305ce 100755
--- a/Lib/smtplib.py
+++ b/Lib/smtplib.py
@@ -52,9 +52,10 @@ from sys import stderr
__all__ = ["SMTPException","SMTPServerDisconnected","SMTPResponseException",
"SMTPSenderRefused","SMTPRecipientsRefused","SMTPDataError",
"SMTPConnectError","SMTPHeloError","SMTPAuthenticationError",
- "quoteaddr","quotedata","SMTP"]
+ "quoteaddr","quotedata","SMTP","SMTP_SSL"]
SMTP_PORT = 25
+SMTP_SSL_PORT = 465
CRLF="\r\n"
OLDSTYLE_AUTH = re.compile(r"auth=(.*)", re.I)
@@ -240,6 +241,7 @@ class SMTP:
"""
self.esmtp_features = {}
+ self.default_port = SMTP_PORT
if host:
(code, msg) = self.connect(host, port)
if code != 220:
@@ -271,6 +273,13 @@ class SMTP:
"""
self.debuglevel = debuglevel
+ def _get_socket(self,af, socktype, proto,sa):
+ # This makes it simpler for SMTP_SSL to use the SMTP connect code
+ # and just alter the socket connection bit.
+ self.sock = socket.socket(af, socktype, proto)
+ if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
+ self.sock.connect(sa)
+
def connect(self, host='localhost', port = 0):
"""Connect to a host on a given port.
@@ -289,16 +298,14 @@ class SMTP:
try: port = int(port)
except ValueError:
raise socket.error, "nonnumeric port"
- if not port: port = SMTP_PORT
+ if not port: port = self.default_port
if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
msg = "getaddrinfo returns an empty list"
self.sock = None
for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
- self.sock = socket.socket(af, socktype, proto)
- if self.debuglevel > 0: print>>stderr, 'connect:', sa
- self.sock.connect(sa)
+ self._get_socket(af,socktype,proto,sa)
except socket.error, msg:
if self.debuglevel > 0: print>>stderr, 'connect fail:', msg
if self.sock:
@@ -716,6 +723,28 @@ class SMTP:
self.docmd("quit")
self.close()
+class SMTP_SSL(SMTP):
+ """ This is a subclass derived from SMTP that connects over an SSL encrypted
+ socket (to use this class you need a socket module that was compiled with SSL
+ support). If host is not specified, '' (the local host) is used. If port is
+ omitted, the standard SMTP-over-SSL port (465) is used. keyfile and certfile
+ are also optional - they can contain a PEM formatted private key and
+ certificate chain file for the SSL connection.
+ """
+ def __init__(self, host = '', port = 0, local_hostname = None,
+ keyfile = None, certfile = None):
+ self.keyfile = keyfile
+ self.certfile = certfile
+ SMTP.__init__(self,host,port,local_hostname)
+ self.default_port = SMTP_SSL_PORT
+
+ def _get_socket(self,af, socktype, proto,sa):
+ self.sock = socket.socket(af, socktype, proto)
+ if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
+ self.sock.connect(sa)
+ sslobj = socket.ssl(self.sock, self.keyfile, self.certfile)
+ self.sock = SSLFakeSocket(self.sock, sslobj)
+ self.file = SSLFakeFile(sslobj)
# Test the sendmail method, which tests most of the others.
# Note: This always sends to localhost.
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 55e267f..68ab05e 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -966,6 +966,8 @@ class Popen(object):
if isinstance(args, types.StringTypes):
args = [args]
+ else:
+ args = list(args)
if shell:
args = ["/bin/sh", "-c"] + args
@@ -1001,14 +1003,10 @@ class Popen(object):
if errwrite:
os.dup2(errwrite, 2)
- # Close pipe fds. Make sure we doesn't close the same
- # fd more than once.
- if p2cread:
- os.close(p2cread)
- if c2pwrite and c2pwrite not in (p2cread,):
- os.close(c2pwrite)
- if errwrite and errwrite not in (p2cread, c2pwrite):
- os.close(errwrite)
+ # Close pipe fds. Make sure we don't close the same
+ # fd more than once, or standard fds.
+ for fd in set((p2cread, c2pwrite, errwrite))-set((0,1,2)):
+ if fd: os.close(fd)
# Close all other fds, if asked for
if close_fds:
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index d238063..14553a7 100644
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -49,6 +49,7 @@ import stat
import errno
import time
import struct
+import copy
if sys.platform == 'mac':
# This module needs work for MacOS9, especially in the area of pathname
@@ -138,7 +139,7 @@ TOEXEC = 0001 # execute/search by other
def stn(s, length):
"""Convert a python string to a null-terminated string buffer.
"""
- return s[:length-1] + (length - len(s) - 1) * NUL + NUL
+ return s[:length] + (length - len(s)) * NUL
def nti(s):
"""Convert a number field to a python number.
@@ -146,7 +147,7 @@ def nti(s):
# There are two possible encodings for a number field, see
# itn() below.
if s[0] != chr(0200):
- n = int(s.rstrip(NUL) or "0", 8)
+ n = int(s.rstrip(NUL + " ") or "0", 8)
else:
n = 0L
for i in xrange(len(s) - 1):
@@ -795,7 +796,6 @@ class TarInfo(object):
"""Construct a TarInfo object. name is the optional name
of the member.
"""
-
self.name = name # member name (dirnames must end with '/')
self.mode = 0666 # file permissions
self.uid = 0 # user id
@@ -809,8 +809,6 @@ class TarInfo(object):
self.gname = "group" # group name
self.devmajor = 0 # device major number
self.devminor = 0 # device minor number
- self.prefix = "" # prefix to filename or information
- # about sparse files
self.offset = 0 # the tar header starts here
self.offset_data = 0 # the file's data starts here
@@ -842,24 +840,74 @@ class TarInfo(object):
tarinfo.gname = buf[297:329].rstrip(NUL)
tarinfo.devmajor = nti(buf[329:337])
tarinfo.devminor = nti(buf[337:345])
- tarinfo.prefix = buf[345:500]
+ prefix = buf[345:500].rstrip(NUL)
+
+ if prefix and not tarinfo.issparse():
+ tarinfo.name = prefix + "/" + tarinfo.name
if tarinfo.chksum not in calc_chksums(buf):
raise ValueError("invalid header")
return tarinfo
def tobuf(self, posix=False):
- """Return a tar header block as a 512 byte string.
+ """Return a tar header as a string of 512 byte blocks.
"""
+ buf = ""
+ type = self.type
+ prefix = ""
+
+ if self.name.endswith("/"):
+ type = DIRTYPE
+
+ if type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK):
+ # Prevent "././@LongLink" from being normalized.
+ name = self.name
+ else:
+ name = normpath(self.name)
+
+ if type == DIRTYPE:
+ # directories should end with '/'
+ name += "/"
+
+ linkname = self.linkname
+ if linkname:
+ # if linkname is empty we end up with a '.'
+ linkname = normpath(linkname)
+
+ if posix:
+ if self.size > MAXSIZE_MEMBER:
+ raise ValueError("file is too large (>= 8 GB)")
+
+ if len(self.linkname) > LENGTH_LINK:
+ raise ValueError("linkname is too long (>%d)" % (LENGTH_LINK))
+
+ if len(name) > LENGTH_NAME:
+ prefix = name[:LENGTH_PREFIX + 1]
+ while prefix and prefix[-1] != "/":
+ prefix = prefix[:-1]
+
+ name = name[len(prefix):]
+ prefix = prefix[:-1]
+
+ if not prefix or len(name) > LENGTH_NAME:
+ raise ValueError("name is too long")
+
+ else:
+ if len(self.linkname) > LENGTH_LINK:
+ buf += self._create_gnulong(self.linkname, GNUTYPE_LONGLINK)
+
+ if len(name) > LENGTH_NAME:
+ buf += self._create_gnulong(name, GNUTYPE_LONGNAME)
+
parts = [
- stn(self.name, 100),
+ stn(name, 100),
itn(self.mode & 07777, 8, posix),
itn(self.uid, 8, posix),
itn(self.gid, 8, posix),
itn(self.size, 12, posix),
itn(self.mtime, 12, posix),
" ", # checksum field
- self.type,
+ type,
stn(self.linkname, 100),
stn(MAGIC, 6),
stn(VERSION, 2),
@@ -867,15 +915,38 @@ class TarInfo(object):
stn(self.gname, 32),
itn(self.devmajor, 8, posix),
itn(self.devminor, 8, posix),
- stn(self.prefix, 155)
+ stn(prefix, 155)
]
- buf = struct.pack("%ds" % BLOCKSIZE, "".join(parts))
- chksum = calc_chksums(buf)[0]
- buf = buf[:148] + "%06o\0" % chksum + buf[155:]
+ buf += struct.pack("%ds" % BLOCKSIZE, "".join(parts))
+ chksum = calc_chksums(buf[-BLOCKSIZE:])[0]
+ buf = buf[:-364] + "%06o\0" % chksum + buf[-357:]
self.buf = buf
return buf
+ def _create_gnulong(self, name, type):
+ """Create a GNU longname/longlink header from name.
+ It consists of an extended tar header, with the length
+ of the longname as size, followed by data blocks,
+ which contain the longname as a null terminated string.
+ """
+ name += NUL
+
+ tarinfo = self.__class__()
+ tarinfo.name = "././@LongLink"
+ tarinfo.type = type
+ tarinfo.mode = 0
+ tarinfo.size = len(name)
+
+ # create extended header
+ buf = tarinfo.tobuf()
+ # create name blocks
+ buf += name
+ blocks, remainder = divmod(len(name), BLOCKSIZE)
+ if remainder > 0:
+ buf += (BLOCKSIZE - remainder) * NUL
+ return buf
+
def isreg(self):
return self.type in REGULAR_TYPES
def isfile(self):
@@ -1379,50 +1450,11 @@ class TarFile(object):
"""
self._check("aw")
- tarinfo.name = normpath(tarinfo.name)
- if tarinfo.isdir():
- # directories should end with '/'
- tarinfo.name += "/"
-
- if tarinfo.linkname:
- tarinfo.linkname = normpath(tarinfo.linkname)
-
- if tarinfo.size > MAXSIZE_MEMBER:
- if self.posix:
- raise ValueError("file is too large (>= 8 GB)")
- else:
- self._dbg(2, "tarfile: Created GNU tar largefile header")
-
-
- if len(tarinfo.linkname) > LENGTH_LINK:
- if self.posix:
- raise ValueError("linkname is too long (>%d)" % (LENGTH_LINK))
- else:
- self._create_gnulong(tarinfo.linkname, GNUTYPE_LONGLINK)
- tarinfo.linkname = tarinfo.linkname[:LENGTH_LINK -1]
- self._dbg(2, "tarfile: Created GNU tar extension LONGLINK")
-
- if len(tarinfo.name) > LENGTH_NAME:
- if self.posix:
- prefix = tarinfo.name[:LENGTH_PREFIX + 1]
- while prefix and prefix[-1] != "/":
- prefix = prefix[:-1]
-
- name = tarinfo.name[len(prefix):]
- prefix = prefix[:-1]
-
- if not prefix or len(name) > LENGTH_NAME:
- raise ValueError("name is too long (>%d)" % (LENGTH_NAME))
-
- tarinfo.name = name
- tarinfo.prefix = prefix
- else:
- self._create_gnulong(tarinfo.name, GNUTYPE_LONGNAME)
- tarinfo.name = tarinfo.name[:LENGTH_NAME - 1]
- self._dbg(2, "tarfile: Created GNU tar extension LONGNAME")
+ tarinfo = copy.copy(tarinfo)
- self.fileobj.write(tarinfo.tobuf(self.posix))
- self.offset += BLOCKSIZE
+ buf = tarinfo.tobuf(self.posix)
+ self.fileobj.write(buf)
+ self.offset += len(buf)
# If there's data to follow, append it.
if fileobj is not None:
@@ -1781,12 +1813,6 @@ class TarFile(object):
if tarinfo.isreg() and tarinfo.name.endswith("/"):
tarinfo.type = DIRTYPE
- # The prefix field is used for filenames > 100 in
- # the POSIX standard.
- # name = prefix + '/' + name
- tarinfo.name = normpath(os.path.join(tarinfo.prefix.rstrip(NUL),
- tarinfo.name))
-
# Directory names should have a '/' at the end.
if tarinfo.isdir():
tarinfo.name += "/"
@@ -1911,10 +1937,6 @@ class TarFile(object):
self.offset += self._block(tarinfo.size)
tarinfo.size = origsize
- # Clear the prefix field so that it is not used
- # as a pathname in next().
- tarinfo.prefix = ""
-
return tarinfo
#--------------------------------------------------------------------------
@@ -1972,31 +1994,6 @@ class TarFile(object):
else:
return TarIter(self)
- def _create_gnulong(self, name, type):
- """Write a GNU longname/longlink member to the TarFile.
- It consists of an extended tar header, with the length
- of the longname as size, followed by data blocks,
- which contain the longname as a null terminated string.
- """
- name += NUL
-
- tarinfo = TarInfo()
- tarinfo.name = "././@LongLink"
- tarinfo.type = type
- tarinfo.mode = 0
- tarinfo.size = len(name)
-
- # write extended header
- self.fileobj.write(tarinfo.tobuf())
- self.offset += BLOCKSIZE
- # write name blocks
- self.fileobj.write(name)
- blocks, remainder = divmod(tarinfo.size, BLOCKSIZE)
- if remainder > 0:
- self.fileobj.write(NUL * (BLOCKSIZE - remainder))
- blocks += 1
- self.offset += blocks * BLOCKSIZE
-
def _dbg(self, level, msg):
"""Write debugging output to sys.stderr.
"""
diff --git a/Lib/test/README b/Lib/test/README
index 496c400..27f696c 100644
--- a/Lib/test/README
+++ b/Lib/test/README
@@ -379,8 +379,8 @@ test_support provides the following useful objects:
point numbers when you expect them to only be approximately equal
withing a fuzz factor (``test_support.FUZZ``, which defaults to 1e-6).
- * ``check_syntax(statement)`` - make sure that the statement is *not*
- correct Python syntax.
+ * ``check_syntax_error(testcase, statement)`` - make sure that the
+ statement is *not* correct Python syntax.
Python and C statement coverage results are currently available at
diff --git a/Lib/test/crashers/bogus_sre_bytecode.py b/Lib/test/crashers/bogus_sre_bytecode.py
new file mode 100644
index 0000000..4bfc730
--- /dev/null
+++ b/Lib/test/crashers/bogus_sre_bytecode.py
@@ -0,0 +1,47 @@
+"""
+The regular expression engine in '_sre' can segfault when interpreting
+bogus bytecode.
+
+It is unclear whether this is a real bug or a "won't fix" case like
+bogus_code_obj.py, because it requires bytecode that is built by hand,
+as opposed to compiled by 're' from a string-source regexp. The
+difference with bogus_code_obj, though, is that the only existing regexp
+compiler is written in Python, so that the C code has no choice but
+accept arbitrary bytecode from Python-level.
+
+The test below builds and runs random bytecodes until 'match' crashes
+Python. I have not investigated why exactly segfaults occur nor how
+hard they would be to fix. Here are a few examples of 'code' that
+segfault for me:
+
+ [21, 50814, 8, 29, 16]
+ [21, 3967, 26, 10, 23, 54113]
+ [29, 23, 0, 2, 5]
+ [31, 64351, 0, 28, 3, 22281, 20, 4463, 9, 25, 59154, 15245, 2,
+ 16343, 3, 11600, 24380, 10, 37556, 10, 31, 15, 31]
+
+Here is also a 'code' that triggers an infinite uninterruptible loop:
+
+ [29, 1, 8, 21, 1, 43083, 6]
+
+"""
+
+import _sre, random
+
+def pick():
+ n = random.randrange(-65536, 65536)
+ if n < 0:
+ n &= 31
+ return n
+
+ss = ["", "world", "x" * 500]
+
+while 1:
+ code = [pick() for i in range(random.randrange(5, 25))]
+ print code
+ pat = _sre.compile(None, 0, code)
+ for s in ss:
+ try:
+ pat.match(s)
+ except RuntimeError:
+ pass
diff --git a/Lib/test/crashers/infinite_loop_re.py b/Lib/test/crashers/infinite_loop_re.py
new file mode 100644
index 0000000..9aecc56
--- /dev/null
+++ b/Lib/test/crashers/infinite_loop_re.py
@@ -0,0 +1,16 @@
+
+# This was taken from http://python.org/sf/1541697
+# It's not technically a crasher. It may not even truly be infinite,
+# however, I haven't waited a long time to see the result. It takes
+# 100% of CPU while running this and should be fixed.
+
+import re
+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*(?=[<>])')
+
+if __name__ == '__main__':
+ foo = '<table cellspacing="0" cellpadding="0" style="border-collapse'
+ starttag.match(foo)
diff --git a/Lib/test/crashers/loosing_mro_ref.py b/Lib/test/crashers/loosing_mro_ref.py
new file mode 100644
index 0000000..f0b8047
--- /dev/null
+++ b/Lib/test/crashers/loosing_mro_ref.py
@@ -0,0 +1,36 @@
+"""
+There is a way to put keys of any type in a type's dictionary.
+I think this allows various kinds of crashes, but so far I have only
+found a convoluted attack of _PyType_Lookup(), which uses the mro of the
+type without holding a strong reference to it. Probably works with
+super.__getattribute__() too, which uses the same kind of code.
+"""
+
+class MyKey(object):
+ def __hash__(self):
+ return hash('mykey')
+
+ def __cmp__(self, other):
+ # the following line decrefs the previous X.__mro__
+ X.__bases__ = (Base2,)
+ # trash all tuples of length 3, to make sure that the items of
+ # the previous X.__mro__ are really garbage
+ z = []
+ for i in range(1000):
+ z.append((i, None, None))
+ return -1
+
+
+class Base(object):
+ mykey = 'from Base'
+
+class Base2(object):
+ mykey = 'from Base2'
+
+class X(Base):
+ # you can't add a non-string key to X.__dict__, but it can be
+ # there from the beginning :-)
+ locals()[MyKey()] = 5
+
+print X.mykey
+# I get a segfault, or a slightly wrong assertion error in a debug build.
diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py
index 453c51c..fc1a6c3 100644
--- a/Lib/test/list_tests.py
+++ b/Lib/test/list_tests.py
@@ -269,7 +269,6 @@ class CommonTest(seq_tests.CommonTest):
self.assertRaises(TypeError, a.insert)
def test_pop(self):
- from decimal import Decimal
a = self.type2test([-1, 0, 1])
a.pop()
self.assertEqual(a, [-1, 0])
@@ -281,8 +280,6 @@ class CommonTest(seq_tests.CommonTest):
self.assertRaises(IndexError, a.pop)
self.assertRaises(TypeError, a.pop, 42, 42)
a = self.type2test([0, 10, 20, 30, 40])
- self.assertEqual(a.pop(Decimal(2)), 20)
- self.assertRaises(IndexError, a.pop, Decimal(25))
def test_remove(self):
a = self.type2test([0, 0, 1])
diff --git a/Lib/test/output/test_MimeWriter b/Lib/test/output/test_MimeWriter
deleted file mode 100644
index 9b97d93..0000000
--- a/Lib/test/output/test_MimeWriter
+++ /dev/null
@@ -1,110 +0,0 @@
-test_MimeWriter
-From: bwarsaw@cnri.reston.va.us
-Date: Mon Feb 12 17:21:48 EST 1996
-To: kss-submit@cnri.reston.va.us
-MIME-Version: 1.0
-Content-Type: multipart/knowbot;
- boundary="801spam999";
- version="0.1"
-
-This is a multi-part message in MIME format.
-
---801spam999
-Content-Type: multipart/knowbot-metadata;
- boundary="802spam999"
-
-
---802spam999
-Content-Type: message/rfc822
-KP-Metadata-Type: simple
-KP-Access: read-only
-
-KPMD-Interpreter: python
-KPMD-Interpreter-Version: 1.3
-KPMD-Owner-Name: Barry Warsaw
-KPMD-Owner-Rendezvous: bwarsaw@cnri.reston.va.us
-KPMD-Home-KSS: kss.cnri.reston.va.us
-KPMD-Identifier: hdl://cnri.kss/my_first_knowbot
-KPMD-Launch-Date: Mon Feb 12 16:39:03 EST 1996
-
---802spam999
-Content-Type: text/isl
-KP-Metadata-Type: complex
-KP-Metadata-Key: connection
-KP-Access: read-only
-KP-Connection-Description: Barry's Big Bass Business
-KP-Connection-Id: B4
-KP-Connection-Direction: client
-
-INTERFACE Seller-1;
-
-TYPE Seller = OBJECT
- DOCUMENTATION "A simple Seller interface to test ILU"
- METHODS
- price():INTEGER,
- END;
-
---802spam999
-Content-Type: message/external-body;
- access-type="URL";
- URL="hdl://cnri.kss/generic-knowbot"
-
-Content-Type: text/isl
-KP-Metadata-Type: complex
-KP-Metadata-Key: generic-interface
-KP-Access: read-only
-KP-Connection-Description: Generic Interface for All Knowbots
-KP-Connection-Id: generic-kp
-KP-Connection-Direction: client
-
-
---802spam999--
-
---801spam999
-Content-Type: multipart/knowbot-code;
- boundary="803spam999"
-
-
---803spam999
-Content-Type: text/plain
-KP-Module-Name: BuyerKP
-
-class Buyer:
- def __setup__(self, maxprice):
- self._maxprice = maxprice
-
- def __main__(self, kos):
- """Entry point upon arrival at a new KOS."""
- broker = kos.broker()
- # B4 == Barry's Big Bass Business :-)
- seller = broker.lookup('Seller_1.Seller', 'B4')
- if seller:
- price = seller.price()
- print 'Seller wants $', price, '... '
- if price > self._maxprice:
- print 'too much!'
- else:
- print "I'll take it!"
- else:
- print 'no seller found here'
-
---803spam999--
-
---801spam999
-Content-Type: multipart/knowbot-state;
- boundary="804spam999"
-KP-Main-Module: main
-
-
---804spam999
-Content-Type: text/plain
-KP-Module-Name: main
-
-# instantiate a buyer instance and put it in a magic place for the KOS
-# to find.
-__kp__ = Buyer()
-__kp__.__setup__(500)
-
---804spam999--
-
---801spam999--
diff --git a/Lib/test/output/test_cgi b/Lib/test/output/test_cgi
deleted file mode 100644
index 26eddfa..0000000
--- a/Lib/test/output/test_cgi
+++ /dev/null
@@ -1,42 +0,0 @@
-test_cgi
-'' => []
-'&' => []
-'&&' => []
-'=' => [('', '')]
-'=a' => [('', 'a')]
-'a' => [('a', '')]
-'a=' => [('a', '')]
-'a=' => [('a', '')]
-'&a=b' => [('a', 'b')]
-'a=a+b&b=b+c' => [('a', 'a b'), ('b', 'b c')]
-'a=1&a=2' => [('a', '1'), ('a', '2')]
-''
-'&'
-'&&'
-';'
-';&;'
-'='
-'=&='
-'=;='
-'=a'
-'&=a'
-'=a&'
-'=&a'
-'b=a'
-'b+=a'
-'a=b=a'
-'a=+b=a'
-'&b=a'
-'b&=a'
-'a=a+b&b=b+c'
-'a=a+b&a=b+a'
-'x=1&y=2.0&z=2-3.%2b0'
-'x=1;y=2.0&z=2-3.%2b0'
-'x=1;y=2.0;z=2-3.%2b0'
-'Hbc5161168c542333633315dee1182227:key_store_seqid=400006&cuyer=r&view=bustomer&order_id=0bb2e248638833d48cb7fed300000f1b&expire=964546263&lobale=en-US&kid=130003.300038&ss=env'
-'group_id=5470&set=custom&_assigned_to=31392&_status=1&_category=100&SUBMIT=Browse'
-Testing log
-Testing initlog 1
-Testing log 2
-Test FieldStorage methods that use readline
-Test basic FieldStorage multipart parsing
diff --git a/Lib/test/output/test_cookie b/Lib/test/output/test_cookie
deleted file mode 100644
index 95c7328..0000000
--- a/Lib/test/output/test_cookie
+++ /dev/null
@@ -1,32 +0,0 @@
-test_cookie
-<SimpleCookie: chips='ahoy' vienna='finger'>
-Set-Cookie: chips=ahoy
-Set-Cookie: vienna=finger
- chips 'ahoy' 'ahoy'
-Set-Cookie: chips=ahoy
- vienna 'finger' 'finger'
-Set-Cookie: vienna=finger
-<SimpleCookie: keebler='E=mc2; L="Loves"; fudge=\n;'>
-Set-Cookie: keebler="E=mc2; L=\"Loves\"; fudge=\012;"
- keebler 'E=mc2; L="Loves"; fudge=\n;' 'E=mc2; L="Loves"; fudge=\n;'
-Set-Cookie: keebler="E=mc2; L=\"Loves\"; fudge=\012;"
-<SimpleCookie: keebler='E=mc2'>
-Set-Cookie: keebler=E=mc2
- keebler 'E=mc2' 'E=mc2'
-Set-Cookie: keebler=E=mc2
-Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme
-
- <script type="text/javascript">
- <!-- begin hiding
- document.cookie = "Customer="WILE_E_COYOTE"; Path=/acme; Version=1";
- // end hiding -->
- </script>
-
-
- <script type="text/javascript">
- <!-- begin hiding
- document.cookie = "Customer="WILE_E_COYOTE"; Path=/acme";
- // end hiding -->
- </script>
-
-If anything blows up after this line, it's from Cookie's doctest.
diff --git a/Lib/test/output/test_global b/Lib/test/output/test_global
deleted file mode 100644
index a427a29..0000000
--- a/Lib/test/output/test_global
+++ /dev/null
@@ -1,5 +0,0 @@
-test_global
-got SyntaxError as expected
-got SyntaxError as expected
-got SyntaxError as expected
-as expected, no SyntaxError
diff --git a/Lib/test/output/test_grammar b/Lib/test/output/test_grammar
deleted file mode 100644
index 5033276..0000000
--- a/Lib/test/output/test_grammar
+++ /dev/null
@@ -1,69 +0,0 @@
-test_grammar
-1. Parser
-1.1 Tokens
-1.1.1 Backslashes
-1.1.2 Numeric literals
-1.1.2.1 Plain integers
-1.1.2.2 Long integers
-1.1.2.3 Floating point
-1.1.3 String literals
-1.1.4 Ellipsis literal
-1.2 Grammar
-single_input
-file_input
-expr_input
-eval_input
-funcdef
-lambdef
-simple_stmt
-expr_stmt
-print_stmt
-1 2 3
-1 2 3
-1 1 1
-extended print_stmt
-1 2 3
-1 2 3
-1 1 1
-hello world
-del_stmt
-pass_stmt
-flow_stmt
-break_stmt
-continue_stmt
-continue + try/except ok
-continue + try/finally ok
-testing continue and break in try/except in loop
-return_stmt
-yield_stmt
-raise_stmt
-import_name
-import_from
-global_stmt
-assert_stmt
-if_stmt
-while_stmt
-for_stmt
-try_stmt
-suite
-test
-comparison
-binary mask ops
-shift ops
-additive ops
-multiplicative ops
-unary ops
-selectors
-
-[1, (1,), (1, 2), (1, 2, 3)]
-atoms
-classdef
-['Apple', 'Banana', 'Coco nut']
-[3, 6, 9, 12, 15]
-[3, 4, 5]
-[(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]
-[(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), (5, 'Banana'), (5, 'Coconut')]
-[[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]
-[False, False, False]
-[[1, 2], [3, 4], [5, 6]]
-[('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ('Macdonalds', 'Cheeseburger')]
diff --git a/Lib/test/output/test_httplib b/Lib/test/output/test_httplib
deleted file mode 100644
index 302b876..0000000
--- a/Lib/test/output/test_httplib
+++ /dev/null
@@ -1,13 +0,0 @@
-test_httplib
-reply: 'HTTP/1.1 200 Ok\r\n'
-Text
-reply: 'HTTP/1.1 400.100 Not Ok\r\n'
-BadStatusLine raised as expected
-InvalidURL raised as expected
-InvalidURL raised as expected
-reply: 'HTTP/1.1 200 OK\r\n'
-header: Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"
-header: Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"
-reply: 'HTTP/1.1 200 OK\r\n'
-header: Content-Length: 14432
-
diff --git a/Lib/test/output/test_math b/Lib/test/output/test_math
deleted file mode 100644
index 4c8f77c..0000000
--- a/Lib/test/output/test_math
+++ /dev/null
@@ -1,28 +0,0 @@
-test_math
-math module, testing with eps 1e-05
-constants
-acos
-asin
-atan
-atan2
-ceil
-cos
-cosh
-degrees
-exp
-fabs
-floor
-fmod
-frexp
-hypot
-ldexp
-log
-log10
-modf
-pow
-radians
-sin
-sinh
-sqrt
-tan
-tanh
diff --git a/Lib/test/output/test_mmap b/Lib/test/output/test_mmap
deleted file mode 100644
index 605f840..0000000
--- a/Lib/test/output/test_mmap
+++ /dev/null
@@ -1,38 +0,0 @@
-test_mmap
-<type 'mmap.mmap'>
- Position of foo: 1.0 pages
- Length of file: 2.0 pages
- Contents of byte 0: '\x00'
- Contents of first 3 bytes: '\x00\x00\x00'
-
- Modifying file's content...
- Contents of byte 0: '3'
- Contents of first 3 bytes: '3\x00\x00'
- Contents of second page: '\x00foobar\x00'
- Regex match on mmap (page start, length of match): 1.0 6
- Seek to zeroth byte
- Seek to 42nd byte
- Seek to last byte
- Try to seek to negative position...
- Try to seek beyond end of mmap...
- Try to seek to negative position...
- Attempting resize()
- Creating 10 byte test data file.
- Opening mmap with access=ACCESS_READ
- Ensuring that readonly mmap can't be slice assigned.
- Ensuring that readonly mmap can't be item assigned.
- Ensuring that readonly mmap can't be write() to.
- Ensuring that readonly mmap can't be write_byte() to.
- Ensuring that readonly mmap can't be resized.
- Opening mmap with size too big
- Opening mmap with access=ACCESS_WRITE
- Modifying write-through memory map.
- Opening mmap with access=ACCESS_COPY
- Modifying copy-on-write memory map.
- Ensuring copy-on-write maps cannot be resized.
- Ensuring invalid access parameter raises exception.
- Try opening a bad file descriptor...
- Ensuring that passing 0 as map length sets map size to current file size.
- Ensuring that passing 0 as map length sets map size to current file size.
- anonymous mmap.mmap(-1, PAGESIZE)...
- Test passed
diff --git a/Lib/test/output/test_nis b/Lib/test/output/test_nis
deleted file mode 100644
index 0853ab4..0000000
--- a/Lib/test/output/test_nis
+++ /dev/null
@@ -1,2 +0,0 @@
-test_nis
-nis.maps()
diff --git a/Lib/test/output/test_opcodes b/Lib/test/output/test_opcodes
deleted file mode 100644
index 4685571..0000000
--- a/Lib/test/output/test_opcodes
+++ /dev/null
@@ -1,6 +0,0 @@
-test_opcodes
-2. Opcodes
-XXX Not yet fully implemented
-2.1 try inside for loop
-2.2 raise class exceptions
-2.3 comparing function objects
diff --git a/Lib/test/output/test_openpty b/Lib/test/output/test_openpty
deleted file mode 100644
index a8b8b5e..0000000
--- a/Lib/test/output/test_openpty
+++ /dev/null
@@ -1,2 +0,0 @@
-test_openpty
-Ping!
diff --git a/Lib/test/output/test_poll b/Lib/test/output/test_poll
deleted file mode 100644
index ca61d37..0000000
--- a/Lib/test/output/test_poll
+++ /dev/null
@@ -1,19 +0,0 @@
-test_poll
-Running poll test 1
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
- This is a test.
-Poll test 1 complete
-Running poll test 2
-Poll test 2 complete
-Running poll test 3
-Poll test 3 complete
diff --git a/Lib/test/output/test_regex b/Lib/test/output/test_regex
deleted file mode 100644
index 1deb26f..0000000
--- a/Lib/test/output/test_regex
+++ /dev/null
@@ -1,29 +0,0 @@
-test_regex
-no match: -1
-successful search: 6
-caught expected exception
-failed awk syntax: -1
-successful awk syntax: 2
-failed awk syntax: -1
-matching with group names and compile()
--1
-caught expected exception
-matching with group names and symcomp()
-7
-801 999
-801
-('801', '999')
-('801', '999')
-realpat: \([0-9]+\) *\([0-9]+\)
-groupindex: {'one': 1, 'two': 2}
-not case folded search: -1
-case folded search: 6
-__members__: ['last', 'regs', 'translate', 'groupindex', 'realpat', 'givenpat']
-regs: ((6, 11), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1), (-1, -1))
-last: HELLO WORLD
-translate: 256
-givenpat: world
-match with pos: -1
-search with pos: 18
-bogus group: ('world', None, None)
-no name: caught expected exception
diff --git a/Lib/test/output/test_scope b/Lib/test/output/test_scope
deleted file mode 100644
index a439e44..0000000
--- a/Lib/test/output/test_scope
+++ /dev/null
@@ -1,24 +0,0 @@
-test_scope
-1. simple nesting
-2. extra nesting
-3. simple nesting + rebinding
-4. nesting with global but no free
-5. nesting through class
-6. nesting plus free ref to global
-7. nearest enclosing scope
-8. mixed freevars and cellvars
-9. free variable in method
-10. recursion
-11. unoptimized namespaces
-12. lambdas
-13. UnboundLocal
-14. complex definitions
-15. scope of global statements
-16. check leaks
-17. class and global
-18. verify that locals() works
-19. var is bound and free in class
-20. interaction with trace function
-20. eval and exec with free variables
-21. list comprehension with local variables
-22. eval with free variables
diff --git a/Lib/test/output/test_tokenize b/Lib/test/output/test_tokenize
index 0c14308..4a3d58c 100644
--- a/Lib/test/output/test_tokenize
+++ b/Lib/test/output/test_tokenize
@@ -1,15 +1,23 @@
test_tokenize
-1,0-1,35: COMMENT "# Tests for the 'tokenize' module.\n"
-2,0-2,43: COMMENT '# Large bits stolen from test_grammar.py. \n'
+1,0-1,34: COMMENT "# Tests for the 'tokenize' module."
+1,34-1,35: NL '\n'
+2,0-2,42: COMMENT '# Large bits stolen from test_grammar.py. '
+2,42-2,43: NL '\n'
3,0-3,1: NL '\n'
-4,0-4,11: COMMENT '# Comments\n'
+4,0-4,10: COMMENT '# Comments'
+4,10-4,11: NL '\n'
5,0-5,3: STRING '"#"'
5,3-5,4: NEWLINE '\n'
-6,0-6,3: COMMENT "#'\n"
-7,0-7,3: COMMENT '#"\n'
-8,0-8,3: COMMENT '#\\\n'
-9,7-9,9: COMMENT '#\n'
-10,4-10,10: COMMENT '# abc\n'
+6,0-6,2: COMMENT "#'"
+6,2-6,3: NL '\n'
+7,0-7,2: COMMENT '#"'
+7,2-7,3: NL '\n'
+8,0-8,2: COMMENT '#\\'
+8,2-8,3: NL '\n'
+9,7-9,8: COMMENT '#'
+9,8-9,9: NL '\n'
+10,4-10,9: COMMENT '# abc'
+10,9-10,10: NL '\n'
11,0-12,4: STRING "'''#\n#'''"
12,4-12,5: NEWLINE '\n'
13,0-13,1: NL '\n'
@@ -19,7 +27,8 @@ test_tokenize
14,7-14,8: COMMENT '#'
14,8-14,9: NEWLINE '\n'
15,0-15,1: NL '\n'
-16,0-16,25: COMMENT '# Balancing continuation\n'
+16,0-16,24: COMMENT '# Balancing continuation'
+16,24-16,25: NL '\n'
17,0-17,1: NL '\n'
18,0-18,1: NAME 'a'
18,2-18,3: OP '='
@@ -93,7 +102,8 @@ test_tokenize
29,2-29,3: OP ')'
29,3-29,4: NEWLINE '\n'
30,0-30,1: NL '\n'
-31,0-31,37: COMMENT '# Backslash means line continuation:\n'
+31,0-31,36: COMMENT '# Backslash means line continuation:'
+31,36-31,37: NL '\n'
32,0-32,1: NAME 'x'
32,2-32,3: OP '='
32,4-32,5: NUMBER '1'
@@ -101,13 +111,15 @@ test_tokenize
33,2-33,3: NUMBER '1'
33,3-33,4: NEWLINE '\n'
34,0-34,1: NL '\n'
-35,0-35,55: COMMENT '# Backslash does not means continuation in comments :\\\n'
+35,0-35,54: COMMENT '# Backslash does not means continuation in comments :\\'
+35,54-35,55: NL '\n'
36,0-36,1: NAME 'x'
36,2-36,3: OP '='
36,4-36,5: NUMBER '0'
36,5-36,6: NEWLINE '\n'
37,0-37,1: NL '\n'
-38,0-38,20: COMMENT '# Ordinary integers\n'
+38,0-38,19: COMMENT '# Ordinary integers'
+38,19-38,20: NL '\n'
39,0-39,4: NUMBER '0xff'
39,5-39,7: OP '!='
39,8-39,11: NUMBER '255'
@@ -138,7 +150,8 @@ test_tokenize
44,15-44,16: NUMBER '1'
44,16-44,17: NEWLINE '\n'
45,0-45,1: NL '\n'
-46,0-46,16: COMMENT '# Long integers\n'
+46,0-46,15: COMMENT '# Long integers'
+46,15-46,16: NL '\n'
47,0-47,1: NAME 'x'
47,2-47,3: OP '='
47,4-47,6: NUMBER '0L'
@@ -172,7 +185,8 @@ test_tokenize
54,4-54,35: NUMBER '123456789012345678901234567890l'
54,35-54,36: NEWLINE '\n'
55,0-55,1: NL '\n'
-56,0-56,25: COMMENT '# Floating-point numbers\n'
+56,0-56,24: COMMENT '# Floating-point numbers'
+56,24-56,25: NL '\n'
57,0-57,1: NAME 'x'
57,2-57,3: OP '='
57,4-57,8: NUMBER '3.14'
@@ -185,7 +199,8 @@ test_tokenize
59,2-59,3: OP '='
59,4-59,9: NUMBER '0.314'
59,9-59,10: NEWLINE '\n'
-60,0-60,18: COMMENT '# XXX x = 000.314\n'
+60,0-60,17: COMMENT '# XXX x = 000.314'
+60,17-60,18: NL '\n'
61,0-61,1: NAME 'x'
61,2-61,3: OP '='
61,4-61,8: NUMBER '.314'
@@ -219,7 +234,8 @@ test_tokenize
68,4-68,9: NUMBER '3.1e4'
68,9-68,10: NEWLINE '\n'
69,0-69,1: NL '\n'
-70,0-70,18: COMMENT '# String literals\n'
+70,0-70,17: COMMENT '# String literals'
+70,17-70,18: NL '\n'
71,0-71,1: NAME 'x'
71,2-71,3: OP '='
71,4-71,6: STRING "''"
@@ -367,7 +383,8 @@ test_tokenize
125,6-126,3: STRING "uR'''spam\n'''"
126,3-126,4: NEWLINE '\n'
127,0-127,1: NL '\n'
-128,0-128,14: COMMENT '# Indentation\n'
+128,0-128,13: COMMENT '# Indentation'
+128,13-128,14: NL '\n'
129,0-129,2: NAME 'if'
129,3-129,4: NUMBER '1'
129,4-129,5: OP ':'
@@ -439,7 +456,8 @@ test_tokenize
142,14-142,15: NUMBER '2'
142,15-142,16: NEWLINE '\n'
143,0-143,1: NL '\n'
-144,0-144,12: COMMENT '# Operators\n'
+144,0-144,11: COMMENT '# Operators'
+144,11-144,12: NL '\n'
145,0-145,1: NL '\n'
146,0-146,0: DEDENT ''
146,0-146,0: DEDENT ''
@@ -501,7 +519,8 @@ test_tokenize
149,27-149,28: OP ')'
149,28-149,29: NEWLINE '\n'
150,0-150,1: NL '\n'
-151,0-151,13: COMMENT '# comparison\n'
+151,0-151,12: COMMENT '# comparison'
+151,12-151,13: NL '\n'
152,0-152,2: NAME 'if'
152,3-152,4: NUMBER '1'
152,5-152,6: OP '<'
@@ -532,7 +551,8 @@ test_tokenize
152,67-152,71: NAME 'pass'
152,71-152,72: NEWLINE '\n'
153,0-153,1: NL '\n'
-154,0-154,9: COMMENT '# binary\n'
+154,0-154,8: COMMENT '# binary'
+154,8-154,9: NL '\n'
155,0-155,1: NAME 'x'
155,2-155,3: OP '='
155,4-155,5: NUMBER '1'
@@ -552,7 +572,8 @@ test_tokenize
157,8-157,9: NUMBER '1'
157,9-157,10: NEWLINE '\n'
158,0-158,1: NL '\n'
-159,0-159,8: COMMENT '# shift\n'
+159,0-159,7: COMMENT '# shift'
+159,7-159,8: NL '\n'
160,0-160,1: NAME 'x'
160,2-160,3: OP '='
160,4-160,5: NUMBER '1'
@@ -562,7 +583,8 @@ test_tokenize
160,14-160,15: NUMBER '1'
160,15-160,16: NEWLINE '\n'
161,0-161,1: NL '\n'
-162,0-162,11: COMMENT '# additive\n'
+162,0-162,10: COMMENT '# additive'
+162,10-162,11: NL '\n'
163,0-163,1: NAME 'x'
163,2-163,3: OP '='
163,4-163,5: NUMBER '1'
@@ -576,7 +598,8 @@ test_tokenize
163,20-163,21: NUMBER '1'
163,21-163,22: NEWLINE '\n'
164,0-164,1: NL '\n'
-165,0-165,17: COMMENT '# multiplicative\n'
+165,0-165,16: COMMENT '# multiplicative'
+165,16-165,17: NL '\n'
166,0-166,1: NAME 'x'
166,2-166,3: OP '='
166,4-166,5: NUMBER '1'
@@ -588,7 +611,8 @@ test_tokenize
166,16-166,17: NUMBER '1'
166,17-166,18: NEWLINE '\n'
167,0-167,1: NL '\n'
-168,0-168,8: COMMENT '# unary\n'
+168,0-168,7: COMMENT '# unary'
+168,7-168,8: NL '\n'
169,0-169,1: NAME 'x'
169,2-169,3: OP '='
169,4-169,5: OP '~'
@@ -626,7 +650,8 @@ test_tokenize
170,24-170,25: NUMBER '1'
170,25-170,26: NEWLINE '\n'
171,0-171,1: NL '\n'
-172,0-172,11: COMMENT '# selector\n'
+172,0-172,10: COMMENT '# selector'
+172,10-172,11: NL '\n'
173,0-173,6: NAME 'import'
173,7-173,10: NAME 'sys'
173,10-173,11: OP ','
diff --git a/Lib/test/output/test_types b/Lib/test/output/test_types
deleted file mode 100644
index b49ce0d..0000000
--- a/Lib/test/output/test_types
+++ /dev/null
@@ -1,15 +0,0 @@
-test_types
-6. Built-in types
-6.1 Truth value testing
-6.2 Boolean operations
-6.3 Comparisons
-6.4 Numeric types (mostly conversions)
-6.4.1 32-bit integers
-6.4.2 Long integers
-6.4.3 Floating point numbers
-6.5 Sequence types
-6.5.1 Strings
-6.5.2 Tuples [see test_tuple.py]
-6.5.3 Lists [see test_list.py]
-6.6 Mappings == Dictionaries [see test_dict.py]
-Buffers
diff --git a/Lib/test/output/test_xdrlib b/Lib/test/output/test_xdrlib
deleted file mode 100644
index d86caa9..0000000
--- a/Lib/test/output/test_xdrlib
+++ /dev/null
@@ -1,19 +0,0 @@
-test_xdrlib
-pack test 0 succeeded
-pack test 1 succeeded
-pack test 2 succeeded
-pack test 3 succeeded
-pack test 4 succeeded
-pack test 5 succeeded
-pack test 6 succeeded
-pack test 7 succeeded
-pack test 8 succeeded
-unpack test 0 succeeded : 9
-unpack test 1 succeeded : True
-unpack test 2 succeeded : False
-unpack test 3 succeeded : 45
-unpack test 4 succeeded : 1.89999997616
-unpack test 5 succeeded : 1.9
-unpack test 6 succeeded : hello world
-unpack test 7 succeeded : [0, 1, 2, 3, 4]
-unpack test 8 succeeded : ['what', 'is', 'hapnin', 'doctor']
diff --git a/Lib/test/outstanding_bugs.py b/Lib/test/outstanding_bugs.py
index 7e37c85..04afcbd 100644
--- a/Lib/test/outstanding_bugs.py
+++ b/Lib/test/outstanding_bugs.py
@@ -9,19 +9,14 @@
import unittest
from test import test_support
-class TestBug1385040(unittest.TestCase):
- def testSyntaxError(self):
- import compiler
-
- # The following snippet gives a SyntaxError in the interpreter
- #
- # If you compile and exec it, the call foo(7) returns (7, 1)
- self.assertRaises(SyntaxError, compiler.compile,
- "def foo(a=1, b): return a, b\n\n", "<string>", "exec")
+#
+# No test cases for outstanding bugs at the moment.
+#
def test_main():
- test_support.run_unittest(TestBug1385040)
+ #test_support.run_unittest()
+ pass
if __name__ == "__main__":
test_main()
diff --git a/Lib/test/sgml_input.html b/Lib/test/sgml_input.html
new file mode 100644
index 0000000..f4d2e6c
--- /dev/null
+++ b/Lib/test/sgml_input.html
@@ -0,0 +1,212 @@
+<html>
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+ <link rel="stylesheet" type="text/css" href="http://ogame182.de/epicblue/formate.css">
+ <script language="JavaScript" src="js/flotten.js"></script>
+ </head>
+ <body>
+ <script language=JavaScript> if (parent.frames.length == 0) { top.location.href = "http://es.ogame.org/"; } </script> <script language="JavaScript">
+function haha(z1) {
+ eval("location='"+z1.options[z1.selectedIndex].value+"'");
+}
+</script>
+<center>
+<table>
+ <tr>
+ <td></td>
+ <td>
+ <center>
+ <table>
+ <tr>
+ <td><img src="http://ogame182.de/epicblue/planeten/small/s_dschjungelplanet04.jpg" width="50" height="50"></td>
+ <td>
+ <table border="1">
+ <select size="1" onchange="haha(this)">
+ <option value="/game/flotten1.php?session=8912ae912fec&cp=33875341&mode=Flotte&gid=&messageziel=&re=0" selected>Alien sex friend [2:250:6]</option>
+ <option value="/game/flotten1.php?session=8912ae912fec&cp=33905100&mode=Flotte&gid=&messageziel=&re=0" >1989 [2:248:14]</option>
+ <option value="/game/flotten1.php?session=8912ae912fec&cp=34570808&mode=Flotte&gid=&messageziel=&re=0" >1990 [2:248:6]</option>
+ <option value="/game/flotten1.php?session=8912ae912fec&cp=34570858&mode=Flotte&gid=&messageziel=&re=0" >1991 [2:254:6]</option>
+ <option value="/game/flotten1.php?session=8912ae912fec&cp=34572929&mode=Flotte&gid=&messageziel=&re=0" >Colonia [2:253:12]</option>
+ </select>
+ </table>
+ </td>
+ </tr>
+ </table>
+ </center>
+ </td>
+ <td>
+ <table border="0" width="100%" cellspacing="0" cellpadding="0">
+ <tr>
+ <td align="center"></td>
+ <td align="center" width="85">
+ <img border="0" src="http://ogame182.de/epicblue/images/metall.gif" width="42" height="22">
+ </td>
+ <td align="center" width="85">
+ <img border="0" src="http://ogame182.de/epicblue/images/kristall.gif" width="42" height="22">
+ </td>
+ <td align="center" width="85">
+ <img border="0" src="http://ogame182.de/epicblue/images/deuterium.gif" width="42" height="22">
+ </td>
+ <td align="center" width="85">
+ <img border="0" src="http://ogame182.de/epicblue/images/energie.gif" width="42" height="22">
+ </td>
+ <td align="center"></td>
+ </tr>
+ <tr>
+ <td align="center"><i><b>&nbsp;&nbsp;</b></i></td>
+ <td align="center" width="85"><i><b><font color="#ffffff">Metal</font></b></i></td>
+ <td align="center" width="85"><i><b><font color="#ffffff">Cristal</font></b></i></td>
+ <td align="center" width="85"><i><b><font color="#ffffff">Deuterio</font></b></i></td>
+ <td align="center" width="85"><i><b><font color="#ffffff">Energía</font></b></i></td>
+ <td align="center"><i><b>&nbsp;&nbsp;</b></i></td>
+ </tr>
+ <tr>
+ <td align="center"></td>
+ <td align="center" width="85">160.636</td>
+ <td align="center" width="85">3.406</td>
+ <td align="center" width="85">39.230</td>
+ <td align="center" width="85"><font color=#ff0000>-80</font>/3.965</td>
+ <td align="center"></td>
+ </tr>
+ </table>
+ </tr>
+ </table>
+ </center>
+<br />
+ <script language="JavaScript">
+ <!--
+ function link_to_gamepay() {
+ self.location = "https://www.gamepay.de/?lang=es&serverID=8&userID=129360&gameID=ogame&gui=v2&chksum=a9751afa9e37e6b1b826356bcca45675";
+ }
+//-->
+ </script>
+<center>
+ <table width="519" border="0" cellpadding="0" cellspacing="1">
+ <tr height="20">
+ <td colspan="8" class="c">Flotas (max. 9)</td>
+ </tr>
+ <tr height="20">
+ <th>Num.</th>
+ <th>Misión</th>
+ <th>Cantidad</th>
+ <th>Comienzo</th>
+ <th>Salida</th>
+ <th>Objetivo</th>
+ <th>Llegada</th>
+ <th>Orden</th>
+ </tr>
+ <tr height="20">
+ <th>1</th>
+ <th>
+ <a title="">Espionaje</a>
+ <a title="Flota en el planeta">(F)</a>
+ </th>
+ <th> <a title="Sonda de espionaje: 3
+">3</a></th>
+ <th>[2:250:6]</th>
+ <th>Wed Aug 9 18:00:02</th>
+ <th>[2:242:5]</th>
+ <th>Wed Aug 9 18:01:02</th>
+ <th>
+ <form action="flotten1.php?session=8912ae912fec" method="POST">
+ <input type="hidden" name="order_return" value="25054490" />
+ <input type="submit" value="Enviar de regreso" />
+ </form>
+ </th>
+ </tr>
+ <tr height="20">
+ <th>2</th>
+ <th>
+ <a title="">Espionaje</a>
+ <a title="Volver al planeta">(V)</a>
+ </th>
+ <th> <a title="Sonda de espionaje: 3
+">3</a></th>
+ <th>[2:250:6]</th>
+ <th>Wed Aug 9 17:59:55</th>
+ <th>[2:242:1]</th>
+ <th>Wed Aug 9 18:01:55</th>
+ <th>
+ </th>
+ </tr>
+ </table>
+
+
+
+<form action="flotten2.php?session=8912ae912fec" method="POST">
+ <table width="519" border="0" cellpadding="0" cellspacing="1">
+ <tr height="20">
+ <td colspan="4" class="c">Nueva misión: elegir naves</td>
+ </tr>
+ <tr height="20">
+ <th>Naves</th>
+ <th>Disponibles</th>
+<!-- <th>Gesch.</th> -->
+ <th>-</th>
+ <th>-</th>
+ </tr>
+ <tr height="20">
+ <th><a title="Velocidad: 8500">Nave pequeña de carga</a></th>
+ <th>10<input type="hidden" name="maxship202" value="10"/></th>
+<!-- <th>8500 -->
+ <input type="hidden" name="consumption202" value="10"/>
+ <input type="hidden" name="speed202" value="8500" /></th>
+ <input type="hidden" name="capacity202" value="5000" /></th>
+ <th><a href="javascript:maxShip('ship202');" >máx</a> </th>
+ <th><input name="ship202" size="10" value="0" alt="Nave pequeña de carga 10"/></th>
+ </tr>
+ <tr height="20">
+ <th><a title="Velocidad: 12750">Nave grande de carga</a></th>
+ <th>19<input type="hidden" name="maxship203" value="19"/></th>
+<!-- <th>12750 -->
+ <input type="hidden" name="consumption203" value="50"/>
+ <input type="hidden" name="speed203" value="12750" /></th>
+ <input type="hidden" name="capacity203" value="25000" /></th>
+ <th><a href="javascript:maxShip('ship203');" >máx</a> </th>
+ <th><input name="ship203" size="10" value="0" alt="Nave grande de carga 19"/></th>
+ </tr>
+ <tr height="20">
+ <th><a title="Velocidad: 27000">Crucero</a></th>
+ <th>6<input type="hidden" name="maxship206" value="6"/></th>
+<!-- <th>27000 -->
+ <input type="hidden" name="consumption206" value="300"/>
+ <input type="hidden" name="speed206" value="27000" /></th>
+ <input type="hidden" name="capacity206" value="800" /></th>
+ <th><a href="javascript:maxShip('ship206');" >máx</a> </th>
+ <th><input name="ship206" size="10" value="0" alt="Crucero 6"/></th>
+ </tr>
+ <tr height="20">
+ <th><a title="Velocidad: 3400">Reciclador</a></th>
+ <th>1<input type="hidden" name="maxship209" value="1"/></th>
+<!-- <th>3400 -->
+ <input type="hidden" name="consumption209" value="300"/>
+ <input type="hidden" name="speed209" value="3400" /></th>
+ <input type="hidden" name="capacity209" value="20000" /></th>
+ <th><a href="javascript:maxShip('ship209');" >máx</a> </th>
+ <th><input name="ship209" size="10" value="0" alt="Reciclador 1"/></th>
+ </tr>
+ <tr height="20">
+ <th><a title="Velocidad: 170000000">Sonda de espionaje</a></th>
+ <th>139<input type="hidden" name="maxship210" value="139"/></th>
+<!-- <th>170000000 -->
+ <input type="hidden" name="consumption210" value="1"/>
+ <input type="hidden" name="speed210" value="170000000" /></th>
+ <input type="hidden" name="capacity210" value="5" /></th>
+ <th><a href="javascript:maxShip('ship210');" >máx</a> </th>
+ <th><input name="ship210" size="10" value="0" alt="Sonda de espionaje 139"/></th>
+ </tr>
+ <tr height="20">
+ <th colspan="2"><a href="javascript:noShips();" >Ninguna nave</a></th>
+ <th colspan="2"><a href="javascript:maxShips();" >Todas las naves</a></th>
+ </tr>
+ <tr height="20">
+ <th colspan="4"><input type="submit" value="Continuar" /></th>
+ </tr>
+<tr><th colspan=4>
+<iframe id='a44fb522' name='a44fb522' src='http://ads.gameforgeads.de/adframe.php?n=a44fb522&amp;what=zone:578' framespacing='0' frameborder='no' scrolling='no' width='468' height='60'></iframe>
+<br><center></center></br>
+</th></tr>
+</form>
+</table>
+ </body>
+</html>
diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py
index 73447ad..1aa68de 100644
--- a/Lib/test/string_tests.py
+++ b/Lib/test/string_tests.py
@@ -1069,7 +1069,7 @@ class MixinStrUnicodeUserStringTest:
# from raymond's original specification
S = 'http://www.python.org'
self.checkequal(('http', '://', 'www.python.org'), S, 'rpartition', '://')
- self.checkequal(('http://www.python.org', '', ''), S, 'rpartition', '?')
+ self.checkequal(('', '', 'http://www.python.org'), S, 'rpartition', '?')
self.checkequal(('', 'http://', 'www.python.org'), S, 'rpartition', 'http://')
self.checkequal(('http://www.python.', 'org', ''), S, 'rpartition', 'org')
diff --git a/Lib/test/test_MimeWriter.py b/Lib/test/test_MimeWriter.py
index 5041105..feca163 100644
--- a/Lib/test/test_MimeWriter.py
+++ b/Lib/test/test_MimeWriter.py
@@ -7,6 +7,8 @@ This should generate Barry's example, modulo some quotes and newlines.
"""
+import unittest, sys, StringIO
+from test.test_support import run_unittest
from MimeWriter import MimeWriter
@@ -77,94 +79,213 @@ EXTERNAL_METADATA = [
]
-def main():
- import sys
+OUTPUT = '''\
+From: bwarsaw@cnri.reston.va.us
+Date: Mon Feb 12 17:21:48 EST 1996
+To: kss-submit@cnri.reston.va.us
+MIME-Version: 1.0
+Content-Type: multipart/knowbot;
+ boundary="801spam999";
+ version="0.1"
+
+This is a multi-part message in MIME format.
+
+--801spam999
+Content-Type: multipart/knowbot-metadata;
+ boundary="802spam999"
+
+
+--802spam999
+Content-Type: message/rfc822
+KP-Metadata-Type: simple
+KP-Access: read-only
+
+KPMD-Interpreter: python
+KPMD-Interpreter-Version: 1.3
+KPMD-Owner-Name: Barry Warsaw
+KPMD-Owner-Rendezvous: bwarsaw@cnri.reston.va.us
+KPMD-Home-KSS: kss.cnri.reston.va.us
+KPMD-Identifier: hdl://cnri.kss/my_first_knowbot
+KPMD-Launch-Date: Mon Feb 12 16:39:03 EST 1996
+
+--802spam999
+Content-Type: text/isl
+KP-Metadata-Type: complex
+KP-Metadata-Key: connection
+KP-Access: read-only
+KP-Connection-Description: Barry's Big Bass Business
+KP-Connection-Id: B4
+KP-Connection-Direction: client
- # Toplevel headers
+INTERFACE Seller-1;
+
+TYPE Seller = OBJECT
+ DOCUMENTATION "A simple Seller interface to test ILU"
+ METHODS
+ price():INTEGER,
+ END;
+
+--802spam999
+Content-Type: message/external-body;
+ access-type="URL";
+ URL="hdl://cnri.kss/generic-knowbot"
+
+Content-Type: text/isl
+KP-Metadata-Type: complex
+KP-Metadata-Key: generic-interface
+KP-Access: read-only
+KP-Connection-Description: Generic Interface for All Knowbots
+KP-Connection-Id: generic-kp
+KP-Connection-Direction: client
+
+
+--802spam999--
+
+--801spam999
+Content-Type: multipart/knowbot-code;
+ boundary="803spam999"
+
+
+--803spam999
+Content-Type: text/plain
+KP-Module-Name: BuyerKP
+
+class Buyer:
+ def __setup__(self, maxprice):
+ self._maxprice = maxprice
+
+ def __main__(self, kos):
+ """Entry point upon arrival at a new KOS."""
+ broker = kos.broker()
+ # B4 == Barry's Big Bass Business :-)
+ seller = broker.lookup('Seller_1.Seller', 'B4')
+ if seller:
+ price = seller.price()
+ print 'Seller wants $', price, '... '
+ if price > self._maxprice:
+ print 'too much!'
+ else:
+ print "I'll take it!"
+ else:
+ print 'no seller found here'
+
+--803spam999--
+
+--801spam999
+Content-Type: multipart/knowbot-state;
+ boundary="804spam999"
+KP-Main-Module: main
+
+
+--804spam999
+Content-Type: text/plain
+KP-Module-Name: main
+
+# instantiate a buyer instance and put it in a magic place for the KOS
+# to find.
+__kp__ = Buyer()
+__kp__.__setup__(500)
+
+--804spam999--
+
+--801spam999--
+'''
+
+class MimewriterTest(unittest.TestCase):
+
+ def test(self):
+ buf = StringIO.StringIO()
+
+ # Toplevel headers
+
+ toplevel = MimeWriter(buf)
+ toplevel.addheader("From", "bwarsaw@cnri.reston.va.us")
+ toplevel.addheader("Date", "Mon Feb 12 17:21:48 EST 1996")
+ toplevel.addheader("To", "kss-submit@cnri.reston.va.us")
+ toplevel.addheader("MIME-Version", "1.0")
- toplevel = MimeWriter(sys.stdout)
- toplevel.addheader("From", "bwarsaw@cnri.reston.va.us")
- toplevel.addheader("Date", "Mon Feb 12 17:21:48 EST 1996")
- toplevel.addheader("To", "kss-submit@cnri.reston.va.us")
- toplevel.addheader("MIME-Version", "1.0")
+ # Toplevel body parts
- # Toplevel body parts
+ f = toplevel.startmultipartbody("knowbot", "801spam999",
+ [("version", "0.1")], prefix=0)
+ f.write("This is a multi-part message in MIME format.\n")
- f = toplevel.startmultipartbody("knowbot", "801spam999",
- [("version", "0.1")], prefix=0)
- f.write("This is a multi-part message in MIME format.\n")
+ # First toplevel body part: metadata
- # First toplevel body part: metadata
+ md = toplevel.nextpart()
+ md.startmultipartbody("knowbot-metadata", "802spam999")
- md = toplevel.nextpart()
- md.startmultipartbody("knowbot-metadata", "802spam999")
+ # Metadata part 1
- # Metadata part 1
+ md1 = md.nextpart()
+ md1.addheader("KP-Metadata-Type", "simple")
+ md1.addheader("KP-Access", "read-only")
+ m = MimeWriter(md1.startbody("message/rfc822"))
+ for key, value in SIMPLE_METADATA:
+ m.addheader("KPMD-" + key, value)
+ m.flushheaders()
+ del md1
- md1 = md.nextpart()
- md1.addheader("KP-Metadata-Type", "simple")
- md1.addheader("KP-Access", "read-only")
- m = MimeWriter(md1.startbody("message/rfc822"))
- for key, value in SIMPLE_METADATA:
- m.addheader("KPMD-" + key, value)
- m.flushheaders()
- del md1
+ # Metadata part 2
- # Metadata part 2
+ md2 = md.nextpart()
+ for key, value in COMPLEX_METADATA:
+ md2.addheader("KP-" + key, value)
+ f = md2.startbody("text/isl")
+ f.write(SELLER)
+ del md2
- md2 = md.nextpart()
- for key, value in COMPLEX_METADATA:
- md2.addheader("KP-" + key, value)
- f = md2.startbody("text/isl")
- f.write(SELLER)
- del md2
+ # Metadata part 3
- # Metadata part 3
+ md3 = md.nextpart()
+ f = md3.startbody("message/external-body",
+ [("access-type", "URL"),
+ ("URL", "hdl://cnri.kss/generic-knowbot")])
+ m = MimeWriter(f)
+ for key, value in EXTERNAL_METADATA:
+ md3.addheader("KP-" + key, value)
+ md3.startbody("text/isl")
+ # Phantom body doesn't need to be written
- md3 = md.nextpart()
- f = md3.startbody("message/external-body",
- [("access-type", "URL"),
- ("URL", "hdl://cnri.kss/generic-knowbot")])
- m = MimeWriter(f)
- for key, value in EXTERNAL_METADATA:
- md3.addheader("KP-" + key, value)
- md3.startbody("text/isl")
- # Phantom body doesn't need to be written
+ md.lastpart()
- md.lastpart()
+ # Second toplevel body part: code
- # Second toplevel body part: code
+ code = toplevel.nextpart()
+ code.startmultipartbody("knowbot-code", "803spam999")
- code = toplevel.nextpart()
- code.startmultipartbody("knowbot-code", "803spam999")
+ # Code: buyer program source
- # Code: buyer program source
+ buyer = code.nextpart()
+ buyer.addheader("KP-Module-Name", "BuyerKP")
+ f = buyer.startbody("text/plain")
+ f.write(BUYER)
- buyer = code.nextpart()
- buyer.addheader("KP-Module-Name", "BuyerKP")
- f = buyer.startbody("text/plain")
- f.write(BUYER)
+ code.lastpart()
- code.lastpart()
+ # Third toplevel body part: state
- # Third toplevel body part: state
+ state = toplevel.nextpart()
+ state.addheader("KP-Main-Module", "main")
+ state.startmultipartbody("knowbot-state", "804spam999")
- state = toplevel.nextpart()
- state.addheader("KP-Main-Module", "main")
- state.startmultipartbody("knowbot-state", "804spam999")
+ # State: a bunch of assignments
- # State: a bunch of assignments
+ st = state.nextpart()
+ st.addheader("KP-Module-Name", "main")
+ f = st.startbody("text/plain")
+ f.write(STATE)
- st = state.nextpart()
- st.addheader("KP-Module-Name", "main")
- f = st.startbody("text/plain")
- f.write(STATE)
+ state.lastpart()
- state.lastpart()
+ # End toplevel body parts
- # End toplevel body parts
+ toplevel.lastpart()
- toplevel.lastpart()
+ self.assertEqual(buf.getvalue(), OUTPUT)
+def test_main():
+ run_unittest(MimewriterTest)
-main()
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_StringIO.py b/Lib/test/test_StringIO.py
index cc3367f..9f79b02 100644
--- a/Lib/test/test_StringIO.py
+++ b/Lib/test/test_StringIO.py
@@ -62,6 +62,7 @@ class TestGenericStringIO(unittest.TestCase):
eq(f.getvalue(), 'abcde')
f.write('xyz')
eq(f.getvalue(), 'abcdexyz')
+ self.assertRaises(IOError, f.truncate, -1)
f.close()
self.assertRaises(ValueError, f.write, 'frobnitz')
@@ -120,6 +121,28 @@ class TestStringIO(TestGenericStringIO):
class TestcStringIO(TestGenericStringIO):
MODULE = cStringIO
+ def test_unicode(self):
+
+ if not test_support.have_unicode: return
+
+ # The cStringIO module converts Unicode strings to character
+ # strings when writing them to cStringIO objects.
+ # Check that this works.
+
+ f = self.MODULE.StringIO()
+ f.write(unicode(self._line[:5]))
+ s = f.getvalue()
+ self.assertEqual(s, 'abcde')
+ self.assertEqual(type(s), types.StringType)
+
+ f = self.MODULE.StringIO(unicode(self._line[:5]))
+ s = f.getvalue()
+ self.assertEqual(s, 'abcde')
+ self.assertEqual(type(s), types.StringType)
+
+ self.assertRaises(UnicodeEncodeError, self.MODULE.StringIO,
+ unicode('\xf4', 'latin-1'))
+
import sys
if sys.platform.startswith('java'):
# Jython doesn't have a buffer object, so we just do a useless
diff --git a/Lib/test/test___future__.py b/Lib/test/test___future__.py
index 7d2b2ae..50a2c74 100644
--- a/Lib/test/test___future__.py
+++ b/Lib/test/test___future__.py
@@ -1,59 +1,63 @@
#! /usr/bin/env python
-from test.test_support import verbose, verify
-from types import TupleType, StringType, IntType
+import unittest
+from test import test_support
import __future__
GOOD_SERIALS = ("alpha", "beta", "candidate", "final")
features = __future__.all_feature_names
-# Verify that all_feature_names appears correct.
-given_feature_names = features[:]
-for name in dir(__future__):
- obj = getattr(__future__, name, None)
- if obj is not None and isinstance(obj, __future__._Feature):
- verify(name in given_feature_names,
- "%r should have been in all_feature_names" % name)
- given_feature_names.remove(name)
-verify(len(given_feature_names) == 0,
- "all_feature_names has too much: %r" % given_feature_names)
-del given_feature_names
-
-for feature in features:
- value = getattr(__future__, feature)
- if verbose:
- print "Checking __future__ ", feature, "value", value
-
- optional = value.getOptionalRelease()
- mandatory = value.getMandatoryRelease()
-
- verify(type(optional) is TupleType, "optional isn't tuple")
- verify(len(optional) == 5, "optional isn't 5-tuple")
- major, minor, micro, level, serial = optional
- verify(type(major) is IntType, "optional major isn't int")
- verify(type(minor) is IntType, "optional minor isn't int")
- verify(type(micro) is IntType, "optional micro isn't int")
- verify(isinstance(level, basestring), "optional level isn't string")
- verify(level in GOOD_SERIALS,
- "optional level string has unknown value")
- verify(type(serial) is IntType, "optional serial isn't int")
-
- verify(type(mandatory) is TupleType or
- mandatory is None, "mandatory isn't tuple or None")
- if mandatory is not None:
- verify(len(mandatory) == 5, "mandatory isn't 5-tuple")
- major, minor, micro, level, serial = mandatory
- verify(type(major) is IntType, "mandatory major isn't int")
- verify(type(minor) is IntType, "mandatory minor isn't int")
- verify(type(micro) is IntType, "mandatory micro isn't int")
- verify(isinstance(level, basestring), "mandatory level isn't string")
- verify(level in GOOD_SERIALS,
- "mandatory serial string has unknown value")
- verify(type(serial) is IntType, "mandatory serial isn't int")
- verify(optional < mandatory,
- "optional not less than mandatory, and mandatory not None")
-
- verify(hasattr(value, "compiler_flag"),
- "feature is missing a .compiler_flag attr")
- verify(type(getattr(value, "compiler_flag")) is IntType,
- ".compiler_flag isn't int")
+class FutureTest(unittest.TestCase):
+
+ def test_names(self):
+ # Verify that all_feature_names appears correct.
+ given_feature_names = features[:]
+ for name in dir(__future__):
+ obj = getattr(__future__, name, None)
+ if obj is not None and isinstance(obj, __future__._Feature):
+ self.assert_(
+ name in given_feature_names,
+ "%r should have been in all_feature_names" % name
+ )
+ given_feature_names.remove(name)
+ self.assertEqual(len(given_feature_names), 0,
+ "all_feature_names has too much: %r" % given_feature_names)
+
+ def test_attributes(self):
+ for feature in features:
+ value = getattr(__future__, feature)
+
+ optional = value.getOptionalRelease()
+ mandatory = value.getMandatoryRelease()
+
+ a = self.assert_
+ e = self.assertEqual
+ def check(t, name):
+ a(isinstance(t, tuple), "%s isn't tuple" % name)
+ e(len(t), 5, "%s isn't 5-tuple" % name)
+ (major, minor, micro, level, serial) = t
+ a(isinstance(major, int), "%s major isn't int" % name)
+ a(isinstance(minor, int), "%s minor isn't int" % name)
+ a(isinstance(micro, int), "%s micro isn't int" % name)
+ a(isinstance(level, basestring),
+ "%s level isn't string" % name)
+ a(level in GOOD_SERIALS,
+ "%s level string has unknown value" % name)
+ a(isinstance(serial, int), "%s serial isn't int" % name)
+
+ check(optional, "optional")
+ if mandatory is not None:
+ check(mandatory, "mandatory")
+ a(optional < mandatory,
+ "optional not less than mandatory, and mandatory not None")
+
+ a(hasattr(value, "compiler_flag"),
+ "feature is missing a .compiler_flag attr")
+ a(isinstance(getattr(value, "compiler_flag"), int),
+ ".compiler_flag isn't int")
+
+def test_main():
+ test_support.run_unittest(FutureTest)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py
index 6adbf33..5c79b48 100755
--- a/Lib/test/test_array.py
+++ b/Lib/test/test_array.py
@@ -85,6 +85,13 @@ class BaseTest(unittest.TestCase):
self.assertNotEqual(id(a), id(b))
self.assertEqual(a, b)
+ def test_deepcopy(self):
+ import copy
+ a = array.array(self.typecode, self.example)
+ b = copy.deepcopy(a)
+ self.assertNotEqual(id(a), id(b))
+ self.assertEqual(a, b)
+
def test_pickle(self):
for protocol in (0, 1, 2):
a = array.array(self.typecode, self.example)
diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py
index 8df4504..8272ad9 100755
--- a/Lib/test/test_binascii.py
+++ b/Lib/test/test_binascii.py
@@ -134,7 +134,7 @@ class BinASCIITest(unittest.TestCase):
pass
else:
self.fail("binascii.a2b_qp(**{1:1}) didn't raise TypeError")
- self.assertEqual(binascii.a2b_qp("= "), "")
+ self.assertEqual(binascii.a2b_qp("= "), "= ")
self.assertEqual(binascii.a2b_qp("=="), "=")
self.assertEqual(binascii.a2b_qp("=AX"), "=AX")
self.assertRaises(TypeError, binascii.b2a_qp, foo="bar")
diff --git a/Lib/test/test_bufio.py b/Lib/test/test_bufio.py
index 611cd69..14a926a 100644
--- a/Lib/test/test_bufio.py
+++ b/Lib/test/test_bufio.py
@@ -1,60 +1,66 @@
-from test.test_support import verify, TestFailed, TESTFN
+import unittest
+from test import test_support
# Simple test to ensure that optimizations in fileobject.c deliver
# the expected results. For best testing, run this under a debug-build
# Python too (to exercise asserts in the C code).
-# Repeat string 'pattern' as often as needed to reach total length
-# 'length'. Then call try_one with that string, a string one larger
-# than that, and a string one smaller than that. The main driver
-# feeds this all small sizes and various powers of 2, so we exercise
-# all likely stdio buffer sizes, and "off by one" errors on both
-# sides.
-def drive_one(pattern, length):
- q, r = divmod(length, len(pattern))
- teststring = pattern * q + pattern[:r]
- verify(len(teststring) == length)
- try_one(teststring)
- try_one(teststring + "x")
- try_one(teststring[:-1])
-
-# Write s + "\n" + s to file, then open it and ensure that successive
-# .readline()s deliver what we wrote.
-def try_one(s):
- # Since C doesn't guarantee we can write/read arbitrary bytes in text
- # files, use binary mode.
- f = open(TESTFN, "wb")
- # write once with \n and once without
- f.write(s)
- f.write("\n")
- f.write(s)
- f.close()
- f = open(TESTFN, "rb")
- line = f.readline()
- if line != s + "\n":
- raise TestFailed("Expected %r got %r" % (s + "\n", line))
- line = f.readline()
- if line != s:
- raise TestFailed("Expected %r got %r" % (s, line))
- line = f.readline()
- if line:
- raise TestFailed("Expected EOF but got %r" % line)
- f.close()
-
-# A pattern with prime length, to avoid simple relationships with
-# stdio buffer sizes.
-primepat = "1234567890\00\01\02\03\04\05\06"
-
-nullpat = "\0" * 1000
-
-try:
- for size in range(1, 257) + [512, 1000, 1024, 2048, 4096, 8192, 10000,
- 16384, 32768, 65536, 1000000]:
- drive_one(primepat, size)
- drive_one(nullpat, size)
-finally:
- try:
- import os
- os.unlink(TESTFN)
- except:
- pass
+lengths = range(1, 257) + [512, 1000, 1024, 2048, 4096, 8192, 10000,
+ 16384, 32768, 65536, 1000000]
+
+class BufferSizeTest(unittest.TestCase):
+ def try_one(self, s):
+ # Write s + "\n" + s to file, then open it and ensure that successive
+ # .readline()s deliver what we wrote.
+
+ # Since C doesn't guarantee we can write/read arbitrary bytes in text
+ # files, use binary mode.
+ f = open(test_support.TESTFN, "wb")
+ try:
+ # write once with \n and once without
+ f.write(s)
+ f.write("\n")
+ f.write(s)
+ f.close()
+ f = open(test_support.TESTFN, "rb")
+ line = f.readline()
+ self.assertEqual(line, s + "\n")
+ line = f.readline()
+ self.assertEqual(line, s)
+ line = f.readline()
+ self.assert_(not line) # Must be at EOF
+ f.close()
+ finally:
+ try:
+ import os
+ os.unlink(test_support.TESTFN)
+ except:
+ pass
+
+ def drive_one(self, pattern):
+ for length in lengths:
+ # Repeat string 'pattern' as often as needed to reach total length
+ # 'length'. Then call try_one with that string, a string one larger
+ # than that, and a string one smaller than that. Try this with all
+ # small sizes and various powers of 2, so we exercise all likely
+ # stdio buffer sizes, and "off by one" errors on both sides.
+ q, r = divmod(length, len(pattern))
+ teststring = pattern * q + pattern[:r]
+ self.assertEqual(len(teststring), length)
+ self.try_one(teststring)
+ self.try_one(teststring + "x")
+ self.try_one(teststring[:-1])
+
+ def test_primepat(self):
+ # A pattern with prime length, to avoid simple relationships with
+ # stdio buffer sizes.
+ self.drive_one("1234567890\00\01\02\03\04\05\06")
+
+ def test_nullpat(self):
+ self.drive_one("\0" * 1000)
+
+def test_main():
+ test_support.run_unittest(BufferSizeTest)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 7b245d1..385031f 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -116,6 +116,7 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(abs(0), 0)
self.assertEqual(abs(1234), 1234)
self.assertEqual(abs(-1234), 1234)
+ self.assertTrue(abs(-sys.maxint-1) > 0)
# float
self.assertEqual(abs(0.0), 0.0)
self.assertEqual(abs(3.14), 3.14)
@@ -155,6 +156,11 @@ class BuiltinTest(unittest.TestCase):
S = [10, 20, 30]
self.assertEqual(any(x > 42 for x in S), False)
+ def test_neg(self):
+ x = -sys.maxint-1
+ self.assert_(isinstance(x, int))
+ self.assertEqual(-x, sys.maxint+1)
+
def test_callable(self):
self.assert_(callable(len))
def f(): pass
@@ -686,9 +692,11 @@ class BuiltinTest(unittest.TestCase):
pass
s = repr(-1-sys.maxint)
- self.assertEqual(int(s)+1, -sys.maxint)
+ x = int(s)
+ self.assertEqual(x+1, -sys.maxint)
+ self.assert_(isinstance(x, int))
# should return long
- int(s[1:])
+ self.assertEqual(int(s[1:]), sys.maxint+1)
# should return long
x = int(1e100)
@@ -706,6 +714,11 @@ class BuiltinTest(unittest.TestCase):
self.assertRaises(ValueError, int, '123\0')
self.assertRaises(ValueError, int, '53', 40)
+ # SF bug 1545497: embedded NULs were not detected with
+ # explicit base
+ self.assertRaises(ValueError, int, '123\0', 10)
+ self.assertRaises(ValueError, int, '123\x00 245', 20)
+
x = int('1' * 600)
self.assert_(isinstance(x, long))
diff --git a/Lib/test/test_cfgparser.py b/Lib/test/test_cfgparser.py
index 66fecf1..3979f15 100644
--- a/Lib/test/test_cfgparser.py
+++ b/Lib/test/test_cfgparser.py
@@ -1,9 +1,29 @@
import ConfigParser
import StringIO
import unittest
+import UserDict
from test import test_support
+class SortedDict(UserDict.UserDict):
+ def items(self):
+ result = self.data.items()
+ result.sort()
+ return result
+
+ def keys(self):
+ result = self.data.keys()
+ result.sort()
+ return result
+
+ def values(self):
+ result = self.items()
+ return [i[1] for i in values]
+
+ def iteritems(self): return iter(self.items())
+ def iterkeys(self): return iter(self.keys())
+ __iter__ = iterkeys
+ def itervalues(self): return iter(self.values())
class TestCaseBase(unittest.TestCase):
def newconfig(self, defaults=None):
@@ -414,12 +434,36 @@ class SafeConfigParserTestCase(ConfigParserTestCase):
self.assertRaises(TypeError, cf.set, "sect", "option2", 1.0)
self.assertRaises(TypeError, cf.set, "sect", "option2", object())
+class SortedTestCase(RawConfigParserTestCase):
+ def newconfig(self, defaults=None):
+ self.cf = self.config_class(defaults=defaults, dict_type=SortedDict)
+ return self.cf
+
+ def test_sorted(self):
+ self.fromstring("[b]\n"
+ "o4=1\n"
+ "o3=2\n"
+ "o2=3\n"
+ "o1=4\n"
+ "[a]\n"
+ "k=v\n")
+ output = StringIO.StringIO()
+ self.cf.write(output)
+ self.assertEquals(output.getvalue(),
+ "[a]\n"
+ "k = v\n\n"
+ "[b]\n"
+ "o1 = 4\n"
+ "o2 = 3\n"
+ "o3 = 2\n"
+ "o4 = 1\n\n")
def test_main():
test_support.run_unittest(
ConfigParserTestCase,
RawConfigParserTestCase,
- SafeConfigParserTestCase
+ SafeConfigParserTestCase,
+ SortedTestCase
)
if __name__ == "__main__":
diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py
index f93fa55..52e5e91 100644
--- a/Lib/test/test_cgi.py
+++ b/Lib/test/test_cgi.py
@@ -1,8 +1,9 @@
-from test.test_support import verify, verbose
+from test.test_support import run_unittest
import cgi
import os
import sys
import tempfile
+import unittest
from StringIO import StringIO
class HackedSysModule:
@@ -127,119 +128,124 @@ def first_elts(list):
def first_second_elts(list):
return map(lambda p:(p[0], p[1][0]), list)
-def main():
- for orig, expect in parse_qsl_test_cases:
- result = cgi.parse_qsl(orig, keep_blank_values=True)
- print repr(orig), '=>', result
- verify(result == expect, "Error parsing %s" % repr(orig))
-
- for orig, expect in parse_strict_test_cases:
- # Test basic parsing
- print repr(orig)
- d = do_test(orig, "GET")
- verify(d == expect, "Error parsing %s" % repr(orig))
- d = do_test(orig, "POST")
- verify(d == expect, "Error parsing %s" % repr(orig))
-
- env = {'QUERY_STRING': orig}
- fcd = cgi.FormContentDict(env)
- sd = cgi.SvFormContentDict(env)
- fs = cgi.FieldStorage(environ=env)
- if type(expect) == type({}):
- # test dict interface
- verify(len(expect) == len(fcd))
- verify(norm(expect.keys()) == norm(fcd.keys()))
- verify(norm(expect.values()) == norm(fcd.values()))
- verify(norm(expect.items()) == norm(fcd.items()))
- verify(fcd.get("nonexistent field", "default") == "default")
- verify(len(sd) == len(fs))
- verify(norm(sd.keys()) == norm(fs.keys()))
- verify(fs.getvalue("nonexistent field", "default") == "default")
- # test individual fields
- for key in expect.keys():
- expect_val = expect[key]
- verify(key in fcd)
- verify(norm(fcd[key]) == norm(expect[key]))
- verify(fcd.get(key, "default") == fcd[key])
- verify(key in fs)
- if len(expect_val) > 1:
- single_value = 0
+class CgiTests(unittest.TestCase):
+
+ def test_qsl(self):
+ for orig, expect in parse_qsl_test_cases:
+ result = cgi.parse_qsl(orig, keep_blank_values=True)
+ self.assertEqual(result, expect, "Error parsing %s" % repr(orig))
+
+ def test_strict(self):
+ for orig, expect in parse_strict_test_cases:
+ # Test basic parsing
+ d = do_test(orig, "GET")
+ self.assertEqual(d, expect, "Error parsing %s" % repr(orig))
+ d = do_test(orig, "POST")
+ self.assertEqual(d, expect, "Error parsing %s" % repr(orig))
+
+ env = {'QUERY_STRING': orig}
+ fcd = cgi.FormContentDict(env)
+ sd = cgi.SvFormContentDict(env)
+ fs = cgi.FieldStorage(environ=env)
+ if type(expect) == type({}):
+ # test dict interface
+ self.assertEqual(len(expect), len(fcd))
+ self.assertEqual(norm(expect.keys()), norm(fcd.keys()))
+ self.assertEqual(norm(expect.values()), norm(fcd.values()))
+ self.assertEqual(norm(expect.items()), norm(fcd.items()))
+ self.assertEqual(fcd.get("nonexistent field", "default"), "default")
+ self.assertEqual(len(sd), len(fs))
+ self.assertEqual(norm(sd.keys()), norm(fs.keys()))
+ self.assertEqual(fs.getvalue("nonexistent field", "default"), "default")
+ # test individual fields
+ for key in expect.keys():
+ expect_val = expect[key]
+ self.assert_(key in fcd)
+ self.assertEqual(norm(fcd[key]), norm(expect[key]))
+ self.assertEqual(fcd.get(key, "default"), fcd[key])
+ self.assert_(key in fs)
+ if len(expect_val) > 1:
+ single_value = 0
+ else:
+ single_value = 1
+ try:
+ val = sd[key]
+ except IndexError:
+ self.failIf(single_value)
+ self.assertEqual(fs.getvalue(key), expect_val)
+ else:
+ self.assert_(single_value)
+ self.assertEqual(val, expect_val[0])
+ self.assertEqual(fs.getvalue(key), expect_val[0])
+ self.assertEqual(norm(sd.getlist(key)), norm(expect_val))
+ if single_value:
+ self.assertEqual(norm(sd.values()),
+ first_elts(norm(expect.values())))
+ self.assertEqual(norm(sd.items()),
+ first_second_elts(norm(expect.items())))
+
+ def test_weird_formcontentdict(self):
+ # Test the weird FormContentDict classes
+ env = {'QUERY_STRING': "x=1&y=2.0&z=2-3.%2b0&1=1abc"}
+ expect = {'x': 1, 'y': 2.0, 'z': '2-3.+0', '1': '1abc'}
+ d = cgi.InterpFormContentDict(env)
+ for k, v in expect.items():
+ self.assertEqual(d[k], v)
+ for k, v in d.items():
+ self.assertEqual(expect[k], v)
+ self.assertEqual(norm(expect.values()), norm(d.values()))
+
+ def test_log(self):
+ cgi.log("Testing")
+
+ cgi.logfp = StringIO()
+ cgi.initlog("%s", "Testing initlog 1")
+ cgi.log("%s", "Testing log 2")
+ self.assertEqual(cgi.logfp.getvalue(), "Testing initlog 1\nTesting log 2\n")
+ if os.path.exists("/dev/null"):
+ cgi.logfp = None
+ cgi.logfile = "/dev/null"
+ cgi.initlog("%s", "Testing log 3")
+ cgi.log("Testing log 4")
+
+ def test_fieldstorage_readline(self):
+ # FieldStorage uses readline, which has the capacity to read all
+ # contents of the input file into memory; we use readline's size argument
+ # to prevent that for files that do not contain any newlines in
+ # non-GET/HEAD requests
+ class TestReadlineFile:
+ def __init__(self, file):
+ self.file = file
+ self.numcalls = 0
+
+ def readline(self, size=None):
+ self.numcalls += 1
+ if size:
+ return self.file.readline(size)
else:
- single_value = 1
- try:
- val = sd[key]
- except IndexError:
- verify(not single_value)
- verify(fs.getvalue(key) == expect_val)
- else:
- verify(single_value)
- verify(val == expect_val[0])
- verify(fs.getvalue(key) == expect_val[0])
- verify(norm(sd.getlist(key)) == norm(expect_val))
- if single_value:
- verify(norm(sd.values()) == \
- first_elts(norm(expect.values())))
- verify(norm(sd.items()) == \
- first_second_elts(norm(expect.items())))
-
- # Test the weird FormContentDict classes
- env = {'QUERY_STRING': "x=1&y=2.0&z=2-3.%2b0&1=1abc"}
- expect = {'x': 1, 'y': 2.0, 'z': '2-3.+0', '1': '1abc'}
- d = cgi.InterpFormContentDict(env)
- for k, v in expect.items():
- verify(d[k] == v)
- for k, v in d.items():
- verify(expect[k] == v)
- verify(norm(expect.values()) == norm(d.values()))
-
- print "Testing log"
- cgi.log("Testing")
- cgi.logfp = sys.stdout
- cgi.initlog("%s", "Testing initlog 1")
- cgi.log("%s", "Testing log 2")
- if os.path.exists("/dev/null"):
- cgi.logfp = None
- cgi.logfile = "/dev/null"
- cgi.initlog("%s", "Testing log 3")
- cgi.log("Testing log 4")
-
- print "Test FieldStorage methods that use readline"
- # FieldStorage uses readline, which has the capacity to read all
- # contents of the input file into memory; we use readline's size argument
- # to prevent that for files that do not contain any newlines in
- # non-GET/HEAD requests
- class TestReadlineFile:
- def __init__(self, file):
- self.file = file
- self.numcalls = 0
-
- def readline(self, size=None):
- self.numcalls += 1
- if size:
- return self.file.readline(size)
- else:
- return self.file.readline()
-
- def __getattr__(self, name):
- file = self.__dict__['file']
- a = getattr(file, name)
- if not isinstance(a, int):
- setattr(self, name, a)
- return a
-
- f = TestReadlineFile(tempfile.TemporaryFile())
- f.write('x' * 256 * 1024)
- f.seek(0)
- env = {'REQUEST_METHOD':'PUT'}
- fs = cgi.FieldStorage(fp=f, environ=env)
- # if we're not chunking properly, readline is only called twice
- # (by read_binary); if we are chunking properly, it will be called 5 times
- # as long as the chunksize is 1 << 16.
- verify(f.numcalls > 2)
-
- print "Test basic FieldStorage multipart parsing"
- env = {'REQUEST_METHOD':'POST', 'CONTENT_TYPE':'multipart/form-data; boundary=---------------------------721837373350705526688164684', 'CONTENT_LENGTH':'558'}
- postdata = """-----------------------------721837373350705526688164684
+ return self.file.readline()
+
+ def __getattr__(self, name):
+ file = self.__dict__['file']
+ a = getattr(file, name)
+ if not isinstance(a, int):
+ setattr(self, name, a)
+ return a
+
+ f = TestReadlineFile(tempfile.TemporaryFile())
+ f.write('x' * 256 * 1024)
+ f.seek(0)
+ env = {'REQUEST_METHOD':'PUT'}
+ fs = cgi.FieldStorage(fp=f, environ=env)
+ # if we're not chunking properly, readline is only called twice
+ # (by read_binary); if we are chunking properly, it will be called 5 times
+ # as long as the chunksize is 1 << 16.
+ self.assert_(f.numcalls > 2)
+
+ def test_fieldstorage_multipart(self):
+ #Test basic FieldStorage multipart parsing
+ env = {'REQUEST_METHOD':'POST', 'CONTENT_TYPE':'multipart/form-data; boundary=---------------------------721837373350705526688164684', 'CONTENT_LENGTH':'558'}
+ postdata = """-----------------------------721837373350705526688164684
Content-Disposition: form-data; name="id"
1234
@@ -259,15 +265,19 @@ Content-Disposition: form-data; name="submit"
Add\x20
-----------------------------721837373350705526688164684--
"""
- fs = cgi.FieldStorage(fp=StringIO(postdata), environ=env)
- verify(len(fs.list) == 4)
- expect = [{'name':'id', 'filename':None, 'value':'1234'},
- {'name':'title', 'filename':None, 'value':''},
- {'name':'file', 'filename':'test.txt','value':'Testing 123.\n'},
- {'name':'submit', 'filename':None, 'value':' Add '}]
- for x in range(len(fs.list)):
- for k, exp in expect[x].items():
- got = getattr(fs.list[x], k)
- verify(got == exp)
-
-main()
+ fs = cgi.FieldStorage(fp=StringIO(postdata), environ=env)
+ self.assertEquals(len(fs.list), 4)
+ expect = [{'name':'id', 'filename':None, 'value':'1234'},
+ {'name':'title', 'filename':None, 'value':''},
+ {'name':'file', 'filename':'test.txt','value':'Testing 123.\n'},
+ {'name':'submit', 'filename':None, 'value':' Add '}]
+ for x in range(len(fs.list)):
+ for k, exp in expect[x].items():
+ got = getattr(fs.list[x], k)
+ self.assertEquals(got, exp)
+
+def test_main():
+ run_unittest(CgiTests)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py
index f33462a..3201dd8 100644
--- a/Lib/test/test_class.py
+++ b/Lib/test/test_class.py
@@ -186,6 +186,14 @@ testme ^ 1
# List/dict operations
+class Empty: pass
+
+try:
+ 1 in Empty()
+ print 'failed, should have raised TypeError'
+except TypeError:
+ pass
+
1 in testme
testme[1]
diff --git a/Lib/test/test_codecencodings_cn.py b/Lib/test/test_codecencodings_cn.py
index 1bf8583..c558f1b 100644
--- a/Lib/test/test_codecencodings_cn.py
+++ b/Lib/test/test_codecencodings_cn.py
@@ -32,6 +32,7 @@ class Test_GBK(test_multibytecodec_support.TestBase, unittest.TestCase):
("abc\x80\x80\xc1\xc4\xc8", "replace", u"abc\ufffd\u804a\ufffd"),
("abc\x80\x80\xc1\xc4", "ignore", u"abc\u804a"),
("\x83\x34\x83\x31", "strict", None),
+ (u"\u30fb", "strict", None),
)
class Test_GB18030(test_multibytecodec_support.TestBase, unittest.TestCase):
@@ -45,6 +46,7 @@ class Test_GB18030(test_multibytecodec_support.TestBase, unittest.TestCase):
("abc\x80\x80\xc1\xc4\xc8", "replace", u"abc\ufffd\u804a\ufffd"),
("abc\x80\x80\xc1\xc4", "ignore", u"abc\u804a"),
("abc\x84\x39\x84\x39\xc1\xc4", "replace", u"abc\ufffd\u804a"),
+ (u"\u30fb", "strict", "\x819\xa79"),
)
has_iso10646 = True
diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py
index 8153979..3c800f8 100644
--- a/Lib/test/test_codecs.py
+++ b/Lib/test/test_codecs.py
@@ -425,6 +425,10 @@ class UTF8SigTest(ReadTest):
]
)
+ def test_bug1601501(self):
+ # SF bug #1601501: check that the codec works with a buffer
+ unicode("\xef\xbb\xbf", "utf-8-sig")
+
class EscapeDecodeTest(unittest.TestCase):
def test_empty(self):
self.assertEquals(codecs.escape_decode(""), ("", 0))
@@ -910,6 +914,18 @@ class StreamReaderTest(unittest.TestCase):
f = self.reader(self.stream)
self.assertEquals(f.readlines(), [u'\ud55c\n', u'\uae00'])
+class EncodedFileTest(unittest.TestCase):
+
+ def test_basic(self):
+ f = StringIO.StringIO('\xed\x95\x9c\n\xea\xb8\x80')
+ ef = codecs.EncodedFile(f, 'utf-16-le', 'utf-8')
+ self.assertEquals(ef.read(), '\\\xd5\n\x00\x00\xae')
+
+ f = StringIO.StringIO()
+ ef = codecs.EncodedFile(f, 'utf-8', 'latin1')
+ ef.write('\xc3\xbc')
+ self.assertEquals(f.getvalue(), '\xfc')
+
class Str2StrTest(unittest.TestCase):
def test_read(self):
@@ -1050,6 +1066,14 @@ broken_unicode_with_streams = [
"punycode",
"unicode_internal"
]
+broken_incremental_coders = broken_unicode_with_streams[:]
+
+# The following encodings only support "strict" mode
+only_strict_mode = [
+ "idna",
+ "zlib_codec",
+ "bz2_codec",
+]
try:
import bz2
@@ -1099,6 +1123,7 @@ class BasicUnicodeTest(unittest.TestCase):
decodedresult += reader.read()
self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
+ if encoding not in broken_incremental_coders:
# check incremental decoder/encoder (fetched via the Python
# and C API) and iterencode()/iterdecode()
try:
@@ -1139,6 +1164,24 @@ class BasicUnicodeTest(unittest.TestCase):
result = u"".join(codecs.iterdecode(codecs.iterencode(u"", encoding), encoding))
self.assertEqual(result, u"")
+ if encoding not in only_strict_mode:
+ # check incremental decoder/encoder with errors argument
+ try:
+ encoder = codecs.getincrementalencoder(encoding)("ignore")
+ cencoder = _testcapi.codec_incrementalencoder(encoding, "ignore")
+ except LookupError: # no IncrementalEncoder
+ pass
+ else:
+ encodedresult = "".join(encoder.encode(c) for c in s)
+ decoder = codecs.getincrementaldecoder(encoding)("ignore")
+ decodedresult = u"".join(decoder.decode(c) for c in encodedresult)
+ self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
+
+ encodedresult = "".join(cencoder.encode(c) for c in s)
+ cdecoder = _testcapi.codec_incrementaldecoder(encoding, "ignore")
+ decodedresult = u"".join(cdecoder.decode(c) for c in encodedresult)
+ self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding))
+
def test_seek(self):
# all codecs should be able to encode these
s = u"%s\n%s\n" % (100*u"abc123", 100*u"def456")
@@ -1214,6 +1257,19 @@ class CharmapTest(unittest.TestCase):
(u"", len(allbytes))
)
+class WithStmtTest(unittest.TestCase):
+ def test_encodedfile(self):
+ f = StringIO.StringIO("\xc3\xbc")
+ with codecs.EncodedFile(f, "latin-1", "utf-8") as ef:
+ self.assertEquals(ef.read(), "\xfc")
+
+ def test_streamreaderwriter(self):
+ f = StringIO.StringIO("\xc3\xbc")
+ info = codecs.lookup("utf-8")
+ with codecs.StreamReaderWriter(f, info.streamreader,
+ info.streamwriter, 'strict') as srw:
+ self.assertEquals(srw.read(), u"\xfc")
+
def test_main():
test_support.run_unittest(
@@ -1234,10 +1290,12 @@ def test_main():
IDNACodecTest,
CodecsModuleTest,
StreamReaderTest,
+ EncodedFileTest,
Str2StrTest,
BasicUnicodeTest,
BasicStrTest,
- CharmapTest
+ CharmapTest,
+ WithStmtTest,
)
diff --git a/Lib/test/test_complex_args.py b/Lib/test/test_complex_args.py
new file mode 100644
index 0000000..c6d50a9
--- /dev/null
+++ b/Lib/test/test_complex_args.py
@@ -0,0 +1,91 @@
+
+import unittest
+from test import test_support
+
+class ComplexArgsTestCase(unittest.TestCase):
+
+ def check(self, func, expected, *args):
+ self.assertEqual(func(*args), expected)
+
+ # These functions are tested below as lambdas too. If you add a function test,
+ # also add a similar lambda test.
+
+ def test_func_parens_no_unpacking(self):
+ def f(((((x))))): return x
+ self.check(f, 1, 1)
+ # Inner parens are elided, same as: f(x,)
+ def f(((x)),): return x
+ self.check(f, 2, 2)
+
+ def test_func_1(self):
+ def f(((((x),)))): return x
+ self.check(f, 3, (3,))
+ def f(((((x)),))): return x
+ self.check(f, 4, (4,))
+ def f(((((x))),)): return x
+ self.check(f, 5, (5,))
+ def f(((x),)): return x
+ self.check(f, 6, (6,))
+
+ def test_func_2(self):
+ def f(((((x)),),)): return x
+ self.check(f, 2, ((2,),))
+
+ def test_func_3(self):
+ def f((((((x)),),),)): return x
+ self.check(f, 3, (((3,),),))
+
+ def test_func_complex(self):
+ def f((((((x)),),),), a, b, c): return x, a, b, c
+ self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
+
+ def f(((((((x)),)),),), a, b, c): return x, a, b, c
+ self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
+
+ def f(a, b, c, ((((((x)),)),),)): return a, b, c, x
+ self.check(f, (9, 8, 7, 3), 9, 8, 7, (((3,),),))
+
+ # Duplicate the tests above, but for lambda. If you add a lambda test,
+ # also add a similar function test above.
+
+ def test_lambda_parens_no_unpacking(self):
+ f = lambda (((((x))))): x
+ self.check(f, 1, 1)
+ # Inner parens are elided, same as: f(x,)
+ f = lambda ((x)),: x
+ self.check(f, 2, 2)
+
+ def test_lambda_1(self):
+ f = lambda (((((x),)))): x
+ self.check(f, 3, (3,))
+ f = lambda (((((x)),))): x
+ self.check(f, 4, (4,))
+ f = lambda (((((x))),)): x
+ self.check(f, 5, (5,))
+ f = lambda (((x),)): x
+ self.check(f, 6, (6,))
+
+ def test_lambda_2(self):
+ f = lambda (((((x)),),)): x
+ self.check(f, 2, ((2,),))
+
+ def test_lambda_3(self):
+ f = lambda ((((((x)),),),)): x
+ self.check(f, 3, (((3,),),))
+
+ def test_lambda_complex(self):
+ f = lambda (((((x)),),),), a, b, c: (x, a, b, c)
+ self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
+
+ f = lambda ((((((x)),)),),), a, b, c: (x, a, b, c)
+ self.check(f, (3, 9, 8, 7), (((3,),),), 9, 8, 7)
+
+ f = lambda a, b, c, ((((((x)),)),),): (a, b, c, x)
+ self.check(f, (9, 8, 7, 3), 9, 8, 7, (((3,),),))
+
+
+def test_main():
+ test_support.run_unittest(ComplexArgsTestCase)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py
index 2cf39ae..747785d 100644
--- a/Lib/test/test_contextlib.py
+++ b/Lib/test/test_contextlib.py
@@ -330,32 +330,6 @@ class LockContextTestCase(unittest.TestCase):
return True
self.boilerPlate(lock, locked)
-class DecimalContextTestCase(unittest.TestCase):
-
- # XXX Somebody should write more thorough tests for this
-
- def testBasic(self):
- ctx = decimal.getcontext()
- orig_context = ctx.copy()
- try:
- ctx.prec = save_prec = decimal.ExtendedContext.prec + 5
- with decimal.ExtendedContext.get_manager():
- self.assertEqual(decimal.getcontext().prec,
- decimal.ExtendedContext.prec)
- self.assertEqual(decimal.getcontext().prec, save_prec)
- try:
- with decimal.ExtendedContext.get_manager():
- self.assertEqual(decimal.getcontext().prec,
- decimal.ExtendedContext.prec)
- 1/0
- except ZeroDivisionError:
- self.assertEqual(decimal.getcontext().prec, save_prec)
- else:
- self.fail("Didn't raise ZeroDivisionError")
- finally:
- decimal.setcontext(orig_context)
-
-
# This is needed to make the test actually run under regrtest.py!
def test_main():
run_suite(
diff --git a/Lib/test/test_cookie.py b/Lib/test/test_cookie.py
index c20beee..e7c0cf1 100644
--- a/Lib/test/test_cookie.py
+++ b/Lib/test/test_cookie.py
@@ -1,6 +1,7 @@
# Simple test suite for Cookie.py
-from test.test_support import verify, verbose, run_doctest
+from test.test_support import run_unittest, run_doctest
+import unittest
import Cookie
import warnings
@@ -8,43 +9,74 @@ warnings.filterwarnings("ignore",
".* class is insecure.*",
DeprecationWarning)
-# Currently this only tests SimpleCookie
-
-cases = [
- ('chips=ahoy; vienna=finger', {'chips':'ahoy', 'vienna':'finger'}),
- ('keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"',
- {'keebler' : 'E=mc2; L="Loves"; fudge=\012;'}),
-
- # Check illegal cookies that have an '=' char in an unquoted value
- ('keebler=E=mc2', {'keebler' : 'E=mc2'})
- ]
-
-for data, dict in cases:
- C = Cookie.SimpleCookie() ; C.load(data)
- print repr(C)
- print C.output(sep='\n')
- for k, v in sorted(dict.iteritems()):
- print ' ', k, repr( C[k].value ), repr(v)
- verify(C[k].value == v)
- print C[k]
-
-C = Cookie.SimpleCookie()
-C.load('Customer="WILE_E_COYOTE"; Version=1; Path=/acme')
-
-verify(C['Customer'].value == 'WILE_E_COYOTE')
-verify(C['Customer']['version'] == '1')
-verify(C['Customer']['path'] == '/acme')
-
-print C.output(['path'])
-print C.js_output()
-print C.js_output(['path'])
-
-# Try cookie with quoted meta-data
-C = Cookie.SimpleCookie()
-C.load('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"')
-verify(C['Customer'].value == 'WILE_E_COYOTE')
-verify(C['Customer']['version'] == '1')
-verify(C['Customer']['path'] == '/acme')
-
-print "If anything blows up after this line, it's from Cookie's doctest."
-run_doctest(Cookie)
+class CookieTests(unittest.TestCase):
+ # Currently this only tests SimpleCookie
+ def test_basic(self):
+ cases = [
+ { 'data': 'chips=ahoy; vienna=finger',
+ 'dict': {'chips':'ahoy', 'vienna':'finger'},
+ 'repr': "<SimpleCookie: chips='ahoy' vienna='finger'>",
+ 'output': 'Set-Cookie: chips=ahoy\nSet-Cookie: vienna=finger',
+ },
+
+ { 'data': 'keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"',
+ 'dict': {'keebler' : 'E=mc2; L="Loves"; fudge=\012;'},
+ 'repr': '''<SimpleCookie: keebler='E=mc2; L="Loves"; fudge=\\n;'>''',
+ 'output': 'Set-Cookie: keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"',
+ },
+
+ # Check illegal cookies that have an '=' char in an unquoted value
+ { 'data': 'keebler=E=mc2',
+ 'dict': {'keebler' : 'E=mc2'},
+ 'repr': "<SimpleCookie: keebler='E=mc2'>",
+ 'output': 'Set-Cookie: keebler=E=mc2',
+ }
+ ]
+
+ for case in cases:
+ C = Cookie.SimpleCookie()
+ C.load(case['data'])
+ self.assertEqual(repr(C), case['repr'])
+ self.assertEqual(C.output(sep='\n'), case['output'])
+ for k, v in sorted(case['dict'].iteritems()):
+ self.assertEqual(C[k].value, v)
+
+ def test_load(self):
+ C = Cookie.SimpleCookie()
+ C.load('Customer="WILE_E_COYOTE"; Version=1; Path=/acme')
+
+ self.assertEqual(C['Customer'].value, 'WILE_E_COYOTE')
+ self.assertEqual(C['Customer']['version'], '1')
+ self.assertEqual(C['Customer']['path'], '/acme')
+
+ self.assertEqual(C.output(['path']),
+ 'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme')
+ self.assertEqual(C.js_output(), """
+ <script type="text/javascript">
+ <!-- begin hiding
+ document.cookie = "Customer="WILE_E_COYOTE"; Path=/acme; Version=1";
+ // end hiding -->
+ </script>
+ """)
+ self.assertEqual(C.js_output(['path']), """
+ <script type="text/javascript">
+ <!-- begin hiding
+ document.cookie = "Customer="WILE_E_COYOTE"; Path=/acme";
+ // end hiding -->
+ </script>
+ """)
+
+ def test_quoted_meta(self):
+ # Try cookie with quoted meta-data
+ C = Cookie.SimpleCookie()
+ C.load('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"')
+ self.assertEqual(C['Customer'].value, 'WILE_E_COYOTE')
+ self.assertEqual(C['Customer']['version'], '1')
+ self.assertEqual(C['Customer']['path'], '/acme')
+
+def test_main():
+ run_unittest(CookieTests)
+ run_doctest(Cookie)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py
index 765bdaf..3329104 100644
--- a/Lib/test/test_datetime.py
+++ b/Lib/test/test_datetime.py
@@ -852,6 +852,7 @@ class TestDate(HarmlessMixedComparison):
t = self.theclass(2005, 3, 2)
self.assertEqual(t.strftime("m:%m d:%d y:%y"), "m:03 d:02 y:05")
self.assertEqual(t.strftime(""), "") # SF bug #761337
+ self.assertEqual(t.strftime('x'*1000), 'x'*1000) # SF bug #1556784
self.assertRaises(TypeError, t.strftime) # needs an arg
self.assertRaises(TypeError, t.strftime, "one", "two") # too many args
diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py
index 55a53d3..50df93d 100644
--- a/Lib/test/test_decimal.py
+++ b/Lib/test/test_decimal.py
@@ -23,6 +23,7 @@ or Behaviour) to test each part, or without parameter to test both parts. If
you're working through IDLE, you can import this test module and call test_main()
with the corresponding argument.
"""
+from __future__ import with_statement
import unittest
import glob
@@ -1057,6 +1058,32 @@ class ContextAPItests(unittest.TestCase):
self.assertNotEqual(id(c.flags), id(d.flags))
self.assertNotEqual(id(c.traps), id(d.traps))
+class WithStatementTest(unittest.TestCase):
+ # Can't do these as docstrings until Python 2.6
+ # as doctest can't handle __future__ statements
+
+ def test_localcontext(self):
+ # Use a copy of the current context in the block
+ orig_ctx = getcontext()
+ with localcontext() as enter_ctx:
+ set_ctx = getcontext()
+ final_ctx = getcontext()
+ self.assert_(orig_ctx is final_ctx, 'did not restore context correctly')
+ self.assert_(orig_ctx is not set_ctx, 'did not copy the context')
+ self.assert_(set_ctx is enter_ctx, '__enter__ returned wrong context')
+
+ def test_localcontextarg(self):
+ # Use a copy of the supplied context in the block
+ orig_ctx = getcontext()
+ new_ctx = Context(prec=42)
+ with localcontext(new_ctx) as enter_ctx:
+ set_ctx = getcontext()
+ final_ctx = getcontext()
+ self.assert_(orig_ctx is final_ctx, 'did not restore context correctly')
+ self.assert_(set_ctx.prec == new_ctx.prec, 'did not set correct context')
+ self.assert_(new_ctx is not set_ctx, 'did not copy the context')
+ self.assert_(set_ctx is enter_ctx, '__enter__ returned wrong context')
+
def test_main(arith=False, verbose=None):
""" Execute the tests.
@@ -1077,6 +1104,7 @@ def test_main(arith=False, verbose=None):
DecimalPythonAPItests,
ContextAPItests,
DecimalTest,
+ WithStatementTest,
]
try:
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index d3ae455..2968e3d 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -2017,6 +2017,13 @@ def supers():
veris(Sub.test(), Base.aProp)
+ # Verify that super() doesn't allow keyword args
+ try:
+ super(Base, kw=1)
+ except TypeError:
+ pass
+ else:
+ raise TestFailed, "super shouldn't accept keyword args"
def inherits():
if verbose: print "Testing inheritance from basic types..."
@@ -3501,6 +3508,13 @@ def test_mutable_bases():
raise TestFailed, "shouldn't be able to assign to list.__bases__"
try:
+ D.__bases__ = (C2, list)
+ except TypeError:
+ pass
+ else:
+ assert 0, "best_base calculation found wanting"
+
+ try:
del D.__bases__
except TypeError:
pass
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py
index 717ed5e..ff6ccde 100644
--- a/Lib/test/test_dict.py
+++ b/Lib/test/test_dict.py
@@ -439,6 +439,16 @@ class DictTest(unittest.TestCase):
else:
self.fail_("g[42] didn't raise KeyError")
+ def test_tuple_keyerror(self):
+ # SF #1576657
+ d = {}
+ try:
+ d[(1,)]
+ except KeyError, e:
+ self.assertEqual(e.args, ((1,),))
+ else:
+ self.fail("missing KeyError")
+
from test import mapping_tests
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index b5c5676..abce41e 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -196,17 +196,21 @@ class ExceptionTests(unittest.TestCase):
test_capi2()
test_capi3()
- def testAttributes(self):
- # test that exception attributes are happy
+ def test_WindowsError(self):
try:
- str(u'Hello \u00E1')
- except Exception, e:
- sampleUnicodeEncodeError = e
+ WindowsError
+ except NameError:
+ pass
+ else:
+ self.failUnlessEqual(str(WindowsError(1001)),
+ "1001")
+ self.failUnlessEqual(str(WindowsError(1001, "message")),
+ "[Error 1001] message")
+ self.failUnlessEqual(WindowsError(1001, "message").errno, 22)
+ self.failUnlessEqual(WindowsError(1001, "message").winerror, 1001)
- try:
- unicode('\xff')
- except Exception, e:
- sampleUnicodeDecodeError = e
+ def testAttributes(self):
+ # test that exception attributes are happy
exceptionList = [
(BaseException, (), {'message' : '', 'args' : ()}),
@@ -218,11 +222,16 @@ class ExceptionTests(unittest.TestCase):
(SystemExit, ('foo',),
{'message' : 'foo', 'args' : ('foo',), 'code' : 'foo'}),
(IOError, ('foo',),
- {'message' : 'foo', 'args' : ('foo',)}),
+ {'message' : 'foo', 'args' : ('foo',), 'filename' : None,
+ 'errno' : None, 'strerror' : None}),
(IOError, ('foo', 'bar'),
- {'message' : '', 'args' : ('foo', 'bar')}),
+ {'message' : '', 'args' : ('foo', 'bar'), 'filename' : None,
+ 'errno' : 'foo', 'strerror' : 'bar'}),
(IOError, ('foo', 'bar', 'baz'),
- {'message' : '', 'args' : ('foo', 'bar')}),
+ {'message' : '', 'args' : ('foo', 'bar'), 'filename' : 'baz',
+ 'errno' : 'foo', 'strerror' : 'bar'}),
+ (IOError, ('foo', 'bar', 'baz', 'quux'),
+ {'message' : '', 'args' : ('foo', 'bar', 'baz', 'quux')}),
(EnvironmentError, ('errnoStr', 'strErrorStr', 'filenameStr'),
{'message' : '', 'args' : ('errnoStr', 'strErrorStr'),
'strerror' : 'strErrorStr', 'errno' : 'errnoStr',
@@ -249,16 +258,16 @@ class ExceptionTests(unittest.TestCase):
'print_file_and_line' : None, 'msg' : 'msgStr',
'filename' : None, 'lineno' : None, 'offset' : None}),
(UnicodeError, (), {'message' : '', 'args' : (),}),
- (sampleUnicodeEncodeError,
- {'message' : '', 'args' : ('ascii', u'Hello \xe1', 6, 7,
- 'ordinal not in range(128)'),
- 'encoding' : 'ascii', 'object' : u'Hello \xe1',
- 'start' : 6, 'reason' : 'ordinal not in range(128)'}),
- (sampleUnicodeDecodeError,
+ (UnicodeEncodeError, ('ascii', u'a', 0, 1, 'ordinal not in range'),
+ {'message' : '', 'args' : ('ascii', u'a', 0, 1,
+ 'ordinal not in range'),
+ 'encoding' : 'ascii', 'object' : u'a',
+ 'start' : 0, 'reason' : 'ordinal not in range'}),
+ (UnicodeDecodeError, ('ascii', '\xff', 0, 1, 'ordinal not in range'),
{'message' : '', 'args' : ('ascii', '\xff', 0, 1,
- 'ordinal not in range(128)'),
+ 'ordinal not in range'),
'encoding' : 'ascii', 'object' : '\xff',
- 'start' : 0, 'reason' : 'ordinal not in range(128)'}),
+ 'start' : 0, 'reason' : 'ordinal not in range'}),
(UnicodeTranslateError, (u"\u3042", 0, 1, "ouch"),
{'message' : '', 'args' : (u'\u3042', 0, 1, 'ouch'),
'object' : u'\u3042', 'reason' : 'ouch',
@@ -274,18 +283,14 @@ class ExceptionTests(unittest.TestCase):
except NameError:
pass
- for args in exceptionList:
- expected = args[-1]
+ for exc, args, expected in exceptionList:
try:
- exc = args[0]
- if len(args) == 2:
- raise exc
- else:
- raise exc(*args[1])
+ raise exc(*args)
except BaseException, e:
- if (e is not exc and # needed for sampleUnicode errors
- type(e) is not exc):
+ if type(e) is not exc:
raise
+ # Verify module name
+ self.assertEquals(type(e).__module__, 'exceptions')
# Verify no ref leaks in Exc_str()
s = str(e)
for checkArgName in expected:
@@ -332,6 +337,15 @@ class ExceptionTests(unittest.TestCase):
return -1
self.assertRaises(RuntimeError, g)
+ def testUnicodeStrUsage(self):
+ # Make sure both instances and classes have a str and unicode
+ # representation.
+ self.failUnless(str(Exception))
+ self.failUnless(unicode(Exception))
+ self.failUnless(str(Exception('a')))
+ self.failUnless(unicode(Exception(u'a')))
+
+
def test_main():
run_unittest(ExceptionTests)
diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py
index 58a57b5..2d800b2 100755
--- a/Lib/test/test_fcntl.py
+++ b/Lib/test/test_fcntl.py
@@ -25,7 +25,7 @@ if sys.platform in ('netbsd1', 'netbsd2', 'netbsd3',
'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
'freebsd6', 'freebsd7',
'bsdos2', 'bsdos3', 'bsdos4',
- 'openbsd', 'openbsd2', 'openbsd3'):
+ 'openbsd', 'openbsd2', 'openbsd3', 'openbsd4'):
if struct.calcsize('l') == 8:
off_t = 'l'
pid_t = 'i'
diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py
index a9b3170..8bf5d6e 100644
--- a/Lib/test/test_format.py
+++ b/Lib/test/test_format.py
@@ -219,8 +219,8 @@ if have_unicode:
test_exc(unicode('abc %\u3000','raw-unicode-escape'), 1, ValueError,
"unsupported format character '?' (0x3000) at index 5")
-test_exc('%d', '1', TypeError, "int argument required")
-test_exc('%g', '1', TypeError, "float argument required")
+test_exc('%d', '1', TypeError, "int argument required, not str")
+test_exc('%g', '1', TypeError, "float argument required, not str")
test_exc('no format', '1', TypeError,
"not all arguments converted during string formatting")
test_exc('no format', u'1', TypeError,
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index 01d6cd2..edc17fc 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -210,6 +210,13 @@ class TestUpdateWrapper(unittest.TestCase):
self.assertEqual(wrapper.attr, 'This is a different test')
self.assertEqual(wrapper.dict_attr, f.dict_attr)
+ def test_builtin_update(self):
+ # Test for bug #1576241
+ def wrapper():
+ pass
+ functools.update_wrapper(wrapper, max)
+ self.assertEqual(wrapper.__name__, 'max')
+ self.assert_(wrapper.__doc__.startswith('max('))
class TestWraps(TestUpdateWrapper):
diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py
index f5462e20..9a5f829 100644
--- a/Lib/test/test_future.py
+++ b/Lib/test/test_future.py
@@ -82,6 +82,27 @@ class FutureTest(unittest.TestCase):
else:
self.fail("expected exception didn't occur")
+ def test_parserhack(self):
+ # test that the parser.c::future_hack function works as expected
+ # Note: although this test must pass, it's not testing the original
+ # bug as of 2.6 since the with statement is not optional and
+ # the parser hack disabled. If a new keyword is introduced in
+ # 2.6, change this to refer to the new future import.
+ try:
+ exec("from __future__ import division, with_statement; with = 0")
+ except SyntaxError:
+ pass
+ else:
+ self.fail("syntax error didn't occur")
+
+ try:
+ exec("from __future__ import (with_statement, division); with = 0")
+ except SyntaxError:
+ pass
+ else:
+ self.fail("syntax error didn't occur")
+
+
def test_main():
test_support.run_unittest(FutureTest)
diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py
new file mode 100644
index 0000000..53c4607
--- /dev/null
+++ b/Lib/test/test_genericpath.py
@@ -0,0 +1,184 @@
+import unittest
+from test import test_support
+import os
+import genericpath
+
+class AllCommonTest(unittest.TestCase):
+
+ def assertIs(self, a, b):
+ self.assert_(a is b)
+
+ def test_commonprefix(self):
+ self.assertEqual(
+ genericpath.commonprefix([]),
+ ""
+ )
+ self.assertEqual(
+ genericpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"]),
+ "/home/swen"
+ )
+ self.assertEqual(
+ genericpath.commonprefix(["/home/swen/spam", "/home/swen/eggs"]),
+ "/home/swen/"
+ )
+ self.assertEqual(
+ genericpath.commonprefix(["/home/swen/spam", "/home/swen/spam"]),
+ "/home/swen/spam"
+ )
+
+ def test_getsize(self):
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertEqual(genericpath.getsize(test_support.TESTFN), 3)
+ finally:
+ if not f.closed:
+ f.close()
+ os.remove(test_support.TESTFN)
+
+ def test_time(self):
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ f = open(test_support.TESTFN, "ab")
+ f.write("bar")
+ f.close()
+ f = open(test_support.TESTFN, "rb")
+ d = f.read()
+ f.close()
+ self.assertEqual(d, "foobar")
+
+ self.assert_(
+ genericpath.getctime(test_support.TESTFN) <=
+ genericpath.getmtime(test_support.TESTFN)
+ )
+ finally:
+ if not f.closed:
+ f.close()
+ os.remove(test_support.TESTFN)
+
+ def test_exists(self):
+ self.assertIs(genericpath.exists(test_support.TESTFN), False)
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertIs(genericpath.exists(test_support.TESTFN), True)
+ finally:
+ if not f.close():
+ f.close()
+ try:
+ os.remove(test_support.TESTFN)
+ except os.error:
+ pass
+
+ self.assertRaises(TypeError, genericpath.exists)
+
+ def test_isdir(self):
+ self.assertIs(genericpath.isdir(test_support.TESTFN), False)
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertIs(genericpath.isdir(test_support.TESTFN), False)
+ os.remove(test_support.TESTFN)
+ os.mkdir(test_support.TESTFN)
+ self.assertIs(genericpath.isdir(test_support.TESTFN), True)
+ os.rmdir(test_support.TESTFN)
+ finally:
+ if not f.close():
+ f.close()
+ try:
+ os.remove(test_support.TESTFN)
+ except os.error:
+ pass
+ try:
+ os.rmdir(test_support.TESTFN)
+ except os.error:
+ pass
+
+ self.assertRaises(TypeError, genericpath.isdir)
+
+ def test_isfile(self):
+ self.assertIs(genericpath.isfile(test_support.TESTFN), False)
+ f = open(test_support.TESTFN, "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertIs(genericpath.isfile(test_support.TESTFN), True)
+ os.remove(test_support.TESTFN)
+ os.mkdir(test_support.TESTFN)
+ self.assertIs(genericpath.isfile(test_support.TESTFN), False)
+ os.rmdir(test_support.TESTFN)
+ finally:
+ if not f.close():
+ f.close()
+ try:
+ os.remove(test_support.TESTFN)
+ except os.error:
+ pass
+ try:
+ os.rmdir(test_support.TESTFN)
+ except os.error:
+ pass
+
+ self.assertRaises(TypeError, genericpath.isdir)
+
+ def test_samefile(self):
+ f = open(test_support.TESTFN + "1", "wb")
+ try:
+ f.write("foo")
+ f.close()
+ self.assertIs(
+ genericpath.samefile(
+ test_support.TESTFN + "1",
+ test_support.TESTFN + "1"
+ ),
+ True
+ )
+ # If we don't have links, assume that os.stat doesn't return resonable
+ # inode information and thus, that samefile() doesn't work
+ if hasattr(os, "symlink"):
+ os.symlink(
+ test_support.TESTFN + "1",
+ test_support.TESTFN + "2"
+ )
+ self.assertIs(
+ genericpath.samefile(
+ test_support.TESTFN + "1",
+ test_support.TESTFN + "2"
+ ),
+ True
+ )
+ os.remove(test_support.TESTFN + "2")
+ f = open(test_support.TESTFN + "2", "wb")
+ f.write("bar")
+ f.close()
+ self.assertIs(
+ genericpath.samefile(
+ test_support.TESTFN + "1",
+ test_support.TESTFN + "2"
+ ),
+ False
+ )
+ finally:
+ if not f.close():
+ f.close()
+ try:
+ os.remove(test_support.TESTFN + "1")
+ except os.error:
+ pass
+ try:
+ os.remove(test_support.TESTFN + "2")
+ except os.error:
+ pass
+
+ self.assertRaises(TypeError, genericpath.samefile)
+
+def test_main():
+ test_support.run_unittest(AllCommonTest)
+
+if __name__=="__main__":
+ test_main()
diff --git a/Lib/test/test_global.py b/Lib/test/test_global.py
index 4cc953c..22e4b25 100644
--- a/Lib/test/test_global.py
+++ b/Lib/test/test_global.py
@@ -1,51 +1,51 @@
"""Verify that warnings are issued for global statements following use."""
-from test.test_support import check_syntax
+from test.test_support import run_unittest, check_syntax_error
+import unittest
import warnings
+warnings.filterwarnings("error", module="<test string>")
-warnings.filterwarnings("error", module="<test code>")
-
-def compile_and_check(text, should_fail=1):
- try:
- compile(text, "<test code>", "exec")
- except SyntaxError, msg:
- if should_fail:
- print "got SyntaxError as expected"
- else:
- print "raised unexpected SyntaxError:", text
- else:
- if should_fail:
- print "should have raised SyntaxError:", text
- else:
- print "as expected, no SyntaxError"
-
-prog_text_1 = """
+class GlobalTests(unittest.TestCase):
+
+ def test1(self):
+ prog_text_1 = """\
def wrong1():
a = 1
b = 2
global a
global b
"""
-compile_and_check(prog_text_1)
+ check_syntax_error(self, prog_text_1)
-prog_text_2 = """
+ def test2(self):
+ prog_text_2 = """\
def wrong2():
print x
global x
"""
-compile_and_check(prog_text_2)
+ check_syntax_error(self, prog_text_2)
-prog_text_3 = """
+ def test3(self):
+ prog_text_3 = """\
def wrong3():
print x
x = 2
global x
"""
-compile_and_check(prog_text_3)
+ check_syntax_error(self, prog_text_3)
-prog_text_4 = """
+ def test4(self):
+ prog_text_4 = """\
global x
x = 2
"""
-compile_and_check(prog_text_4, 0)
+ # this should work
+ compile(prog_text_4, "<test string>", "exec")
+
+
+def test_main():
+ run_unittest(GlobalTests)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py
index ca84c56..f4a0478 100644
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -8,830 +8,897 @@
# regression test, the filterwarnings() call has been added to
# regrtest.py.
-from test.test_support import TestFailed, verify, vereq, check_syntax
+from test.test_support import run_unittest, check_syntax_error
+import unittest
import sys
+# testing import *
+from sys import *
-print '1. Parser'
-
-print '1.1 Tokens'
-
-print '1.1.1 Backslashes'
-
-# Backslash means line continuation:
-x = 1 \
-+ 1
-if x != 2: raise TestFailed, 'backslash for line continuation'
-
-# Backslash does not means continuation in comments :\
-x = 0
-if x != 0: raise TestFailed, 'backslash ending comment'
-
-print '1.1.2 Numeric literals'
-
-print '1.1.2.1 Plain integers'
-if 0xff != 255: raise TestFailed, 'hex int'
-if 0377 != 255: raise TestFailed, 'octal int'
-if 2147483647 != 017777777777: raise TestFailed, 'large positive int'
-try:
- from sys import maxint
-except ImportError:
- maxint = 2147483647
-if maxint == 2147483647:
- # The following test will start to fail in Python 2.4;
- # change the 020000000000 to -020000000000
- if -2147483647-1 != -020000000000: raise TestFailed, 'max negative int'
- # XXX -2147483648
- if 037777777777 < 0: raise TestFailed, 'large oct'
- if 0xffffffff < 0: raise TestFailed, 'large hex'
- for s in '2147483648', '040000000000', '0x100000000':
- try:
- x = eval(s)
- except OverflowError:
- print "OverflowError on huge integer literal " + repr(s)
-elif eval('maxint == 9223372036854775807'):
- if eval('-9223372036854775807-1 != -01000000000000000000000'):
- raise TestFailed, 'max negative int'
- if eval('01777777777777777777777') < 0: raise TestFailed, 'large oct'
- if eval('0xffffffffffffffff') < 0: raise TestFailed, 'large hex'
- for s in '9223372036854775808', '02000000000000000000000', \
- '0x10000000000000000':
- try:
- x = eval(s)
- except OverflowError:
- print "OverflowError on huge integer literal " + repr(s)
-else:
- print 'Weird maxint value', maxint
-
-print '1.1.2.2 Long integers'
-x = 0L
-x = 0l
-x = 0xffffffffffffffffL
-x = 0xffffffffffffffffl
-x = 077777777777777777L
-x = 077777777777777777l
-x = 123456789012345678901234567890L
-x = 123456789012345678901234567890l
-
-print '1.1.2.3 Floating point'
-x = 3.14
-x = 314.
-x = 0.314
-# XXX x = 000.314
-x = .314
-x = 3e14
-x = 3E14
-x = 3e-14
-x = 3e+14
-x = 3.e14
-x = .3e14
-x = 3.1e4
-
-print '1.1.3 String literals'
-
-x = ''; y = ""; verify(len(x) == 0 and x == y)
-x = '\''; y = "'"; verify(len(x) == 1 and x == y and ord(x) == 39)
-x = '"'; y = "\""; verify(len(x) == 1 and x == y and ord(x) == 34)
-x = "doesn't \"shrink\" does it"
-y = 'doesn\'t "shrink" does it'
-verify(len(x) == 24 and x == y)
-x = "does \"shrink\" doesn't it"
-y = 'does "shrink" doesn\'t it'
-verify(len(x) == 24 and x == y)
-x = """
+class TokenTests(unittest.TestCase):
+
+ def testBackslash(self):
+ # Backslash means line continuation:
+ x = 1 \
+ + 1
+ self.assertEquals(x, 2, 'backslash for line continuation')
+
+ # Backslash does not means continuation in comments :\
+ x = 0
+ self.assertEquals(x, 0, 'backslash ending comment')
+
+ def testPlainIntegers(self):
+ self.assertEquals(0xff, 255)
+ self.assertEquals(0377, 255)
+ self.assertEquals(2147483647, 017777777777)
+ from sys import maxint
+ if maxint == 2147483647:
+ self.assertEquals(-2147483647-1, -020000000000)
+ # XXX -2147483648
+ self.assert_(037777777777 > 0)
+ self.assert_(0xffffffff > 0)
+ for s in '2147483648', '040000000000', '0x100000000':
+ try:
+ x = eval(s)
+ except OverflowError:
+ self.fail("OverflowError on huge integer literal %r" % s)
+ elif maxint == 9223372036854775807:
+ self.assertEquals(-9223372036854775807-1, -01000000000000000000000)
+ self.assert_(01777777777777777777777 > 0)
+ self.assert_(0xffffffffffffffff > 0)
+ for s in '9223372036854775808', '02000000000000000000000', \
+ '0x10000000000000000':
+ try:
+ x = eval(s)
+ except OverflowError:
+ self.fail("OverflowError on huge integer literal %r" % s)
+ else:
+ self.fail('Weird maxint value %r' % maxint)
+
+ def testLongIntegers(self):
+ x = 0L
+ x = 0l
+ x = 0xffffffffffffffffL
+ x = 0xffffffffffffffffl
+ x = 077777777777777777L
+ x = 077777777777777777l
+ x = 123456789012345678901234567890L
+ x = 123456789012345678901234567890l
+
+ def testFloats(self):
+ x = 3.14
+ x = 314.
+ x = 0.314
+ # XXX x = 000.314
+ x = .314
+ x = 3e14
+ x = 3E14
+ x = 3e-14
+ x = 3e+14
+ x = 3.e14
+ x = .3e14
+ x = 3.1e4
+
+ def testStringLiterals(self):
+ x = ''; y = ""; self.assert_(len(x) == 0 and x == y)
+ x = '\''; y = "'"; self.assert_(len(x) == 1 and x == y and ord(x) == 39)
+ x = '"'; y = "\""; self.assert_(len(x) == 1 and x == y and ord(x) == 34)
+ x = "doesn't \"shrink\" does it"
+ y = 'doesn\'t "shrink" does it'
+ self.assert_(len(x) == 24 and x == y)
+ x = "does \"shrink\" doesn't it"
+ y = 'does "shrink" doesn\'t it'
+ self.assert_(len(x) == 24 and x == y)
+ x = """
The "quick"
brown fox
jumps over
the 'lazy' dog.
"""
-y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n'
-verify(x == y)
-y = '''
+ y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n'
+ self.assertEquals(x, y)
+ y = '''
The "quick"
brown fox
jumps over
the 'lazy' dog.
-'''; verify(x == y)
-y = "\n\
+'''
+ self.assertEquals(x, y)
+ y = "\n\
The \"quick\"\n\
brown fox\n\
jumps over\n\
the 'lazy' dog.\n\
-"; verify(x == y)
-y = '\n\
+"
+ self.assertEquals(x, y)
+ y = '\n\
The \"quick\"\n\
brown fox\n\
jumps over\n\
the \'lazy\' dog.\n\
-'; verify(x == y)
-
-
-print '1.1.4 Ellipsis literal'
-
-x = ...
-verify(x == Ellipsis)
-
-
-print '1.2 Grammar'
-
-print 'single_input' # NEWLINE | simple_stmt | compound_stmt NEWLINE
-# XXX can't test in a script -- this rule is only used when interactive
-
-print 'file_input' # (NEWLINE | stmt)* ENDMARKER
-# Being tested as this very moment this very module
-
-print 'expr_input' # testlist NEWLINE
-# XXX Hard to test -- used only in calls to input()
-
-print 'eval_input' # testlist ENDMARKER
-x = eval('1, 0 or 1')
-
-print 'funcdef'
-### 'def' NAME parameters ':' suite
-### parameters: '(' [varargslist] ')'
-### varargslist: (fpdef ['=' test] ',')*
-### ('*' (NAME|',' fpdef ['=' test]) [',' ('**'|'*' '*') NAME]
-### | ('**'|'*' '*') NAME)
-### | fpdef ['=' test] (',' fpdef ['=' test])* [',']
-### fpdef: NAME | '(' fplist ')'
-### fplist: fpdef (',' fpdef)* [',']
-### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test)
-### argument: [test '='] test # Really [keyword '='] test
-def f1(): pass
-f1()
-f1(*())
-f1(*(), **{})
-def f2(one_argument): pass
-def f3(two, arguments): pass
-def f4(two, (compound, (argument, list))): pass
-def f5((compound, first), two): pass
-vereq(f2.func_code.co_varnames, ('one_argument',))
-vereq(f3.func_code.co_varnames, ('two', 'arguments'))
-if sys.platform.startswith('java'):
- vereq(f4.func_code.co_varnames,
- ('two', '(compound, (argument, list))', 'compound', 'argument',
- 'list',))
- vereq(f5.func_code.co_varnames,
- ('(compound, first)', 'two', 'compound', 'first'))
-else:
- vereq(f4.func_code.co_varnames,
- ('two', '.1', 'compound', 'argument', 'list'))
- vereq(f5.func_code.co_varnames,
- ('.0', 'two', 'compound', 'first'))
-def a1(one_arg,): pass
-def a2(two, args,): pass
-def v0(*rest): pass
-def v1(a, *rest): pass
-def v2(a, b, *rest): pass
-def v3(a, (b, c), *rest): return a, b, c, rest
-# ceval unpacks the formal arguments into the first argcount names;
-# thus, the names nested inside tuples must appear after these names.
-if sys.platform.startswith('java'):
- verify(v3.func_code.co_varnames == ('a', '(b, c)', 'rest', 'b', 'c'))
-else:
- vereq(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c'))
-verify(v3(1, (2, 3), 4) == (1, 2, 3, (4,)))
-def d01(a=1): pass
-d01()
-d01(1)
-d01(*(1,))
-d01(**{'a':2})
-def d11(a, b=1): pass
-d11(1)
-d11(1, 2)
-d11(1, **{'b':2})
-def d21(a, b, c=1): pass
-d21(1, 2)
-d21(1, 2, 3)
-d21(*(1, 2, 3))
-d21(1, *(2, 3))
-d21(1, 2, *(3,))
-d21(1, 2, **{'c':3})
-def d02(a=1, b=2): pass
-d02()
-d02(1)
-d02(1, 2)
-d02(*(1, 2))
-d02(1, *(2,))
-d02(1, **{'b':2})
-d02(**{'a': 1, 'b': 2})
-def d12(a, b=1, c=2): pass
-d12(1)
-d12(1, 2)
-d12(1, 2, 3)
-def d22(a, b, c=1, d=2): pass
-d22(1, 2)
-d22(1, 2, 3)
-d22(1, 2, 3, 4)
-def d01v(a=1, *rest): pass
-d01v()
-d01v(1)
-d01v(1, 2)
-d01v(*(1, 2, 3, 4))
-d01v(*(1,))
-d01v(**{'a':2})
-def d11v(a, b=1, *rest): pass
-d11v(1)
-d11v(1, 2)
-d11v(1, 2, 3)
-def d21v(a, b, c=1, *rest): pass
-d21v(1, 2)
-d21v(1, 2, 3)
-d21v(1, 2, 3, 4)
-d21v(*(1, 2, 3, 4))
-d21v(1, 2, **{'c': 3})
-def d02v(a=1, b=2, *rest): pass
-d02v()
-d02v(1)
-d02v(1, 2)
-d02v(1, 2, 3)
-d02v(1, *(2, 3, 4))
-d02v(**{'a': 1, 'b': 2})
-def d12v(a, b=1, c=2, *rest): pass
-d12v(1)
-d12v(1, 2)
-d12v(1, 2, 3)
-d12v(1, 2, 3, 4)
-d12v(*(1, 2, 3, 4))
-d12v(1, 2, *(3, 4, 5))
-d12v(1, *(2,), **{'c': 3})
-def d22v(a, b, c=1, d=2, *rest): pass
-d22v(1, 2)
-d22v(1, 2, 3)
-d22v(1, 2, 3, 4)
-d22v(1, 2, 3, 4, 5)
-d22v(*(1, 2, 3, 4))
-d22v(1, 2, *(3, 4, 5))
-d22v(1, *(2, 3), **{'d': 4})
-def d31v((x)): pass
-d31v(1)
-def d32v((x,)): pass
-d32v((1,))
-#keyword only argument tests
-def pos0key1(*, key): return key
-pos0key1(key=100)
-def pos2key2(p1, p2, *, k1, k2=100): return p1,p2,k1,k2
-pos2key2(1, 2, k1=100)
-pos2key2(1, 2, k1=100, k2=200)
-pos2key2(1, 2, k2=100, k1=200)
-def pos2key2dict(p1, p2, *, k1=100, k2, **kwarg): return p1,p2,k1,k2,kwarg
-pos2key2dict(1,2,k2=100,tokwarg1=100,tokwarg2=200)
-pos2key2dict(1,2,tokwarg1=100,tokwarg2=200, k2=100)
-
-### lambdef: 'lambda' [varargslist] ':' test
-print 'lambdef'
-l1 = lambda : 0
-verify(l1() == 0)
-l2 = lambda : a[d] # XXX just testing the expression
-l3 = lambda : [2 < x for x in [-1, 3, 0L]]
-verify(l3() == [0, 1, 0])
-l4 = lambda x = lambda y = lambda z=1 : z : y() : x()
-verify(l4() == 1)
-l5 = lambda x, y, z=2: x + y + z
-verify(l5(1, 2) == 5)
-verify(l5(1, 2, 3) == 6)
-check_syntax("lambda x: x = 2")
-l6 = lambda x, y, *, k=20: x+y+k
-verify(l6(1,2) == 1+2+20)
-verify(l6(1,2,k=10) == 1+2+10)
-
-### stmt: simple_stmt | compound_stmt
-# Tested below
-
-### simple_stmt: small_stmt (';' small_stmt)* [';']
-print 'simple_stmt'
-x = 1; pass; del x
-def foo():
- # verify statments that end with semi-colons
- x = 1; pass; del x;
-foo()
-
-### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt
-# Tested below
-
-print 'expr_stmt' # (exprlist '=')* exprlist
-1
-1, 2, 3
-x = 1
-x = 1, 2, 3
-x = y = z = 1, 2, 3
-x, y, z = 1, 2, 3
-abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4)
-# NB these variables are deleted below
-
-check_syntax("x + 1 = 1")
-check_syntax("a + 1 = b + 2")
-
-print 'print_stmt' # 'print' (test ',')* [test]
-print 1, 2, 3
-print 1, 2, 3,
-print
-print 0 or 1, 0 or 1,
-print 0 or 1
-
-print 'extended print_stmt' # 'print' '>>' test ','
-import sys
-print >> sys.stdout, 1, 2, 3
-print >> sys.stdout, 1, 2, 3,
-print >> sys.stdout
-print >> sys.stdout, 0 or 1, 0 or 1,
-print >> sys.stdout, 0 or 1
-
-# test printing to an instance
-class Gulp:
- def write(self, msg): pass
-
-gulp = Gulp()
-print >> gulp, 1, 2, 3
-print >> gulp, 1, 2, 3,
-print >> gulp
-print >> gulp, 0 or 1, 0 or 1,
-print >> gulp, 0 or 1
-
-# test print >> None
-def driver():
- oldstdout = sys.stdout
- sys.stdout = Gulp()
- try:
- tellme(Gulp())
- tellme()
- finally:
- sys.stdout = oldstdout
-
-# we should see this once
-def tellme(file=sys.stdout):
- print >> file, 'hello world'
-
-driver()
-
-# we should not see this at all
-def tellme(file=None):
- print >> file, 'goodbye universe'
-
-driver()
-
-# syntax errors
-check_syntax('print ,')
-check_syntax('print >> x,')
-
-print 'del_stmt' # 'del' exprlist
-del abc
-del x, y, (z, xyz)
-
-print 'pass_stmt' # 'pass'
-pass
-
-print 'flow_stmt' # break_stmt | continue_stmt | return_stmt | raise_stmt
-# Tested below
-
-print 'break_stmt' # 'break'
-while 1: break
-
-print 'continue_stmt' # 'continue'
-i = 1
-while i: i = 0; continue
-
-msg = ""
-while not msg:
- msg = "continue + try/except ok"
- try:
- continue
- msg = "continue failed to continue inside try"
- except:
- msg = "continue inside try called except block"
-print msg
-
-msg = ""
-while not msg:
- msg = "finally block not called"
- try:
- continue
- finally:
- msg = "continue + try/finally ok"
-print msg
-
-
-# This test warrants an explanation. It is a test specifically for SF bugs
-# #463359 and #462937. The bug is that a 'break' statement executed or
-# exception raised inside a try/except inside a loop, *after* a continue
-# statement has been executed in that loop, will cause the wrong number of
-# arguments to be popped off the stack and the instruction pointer reset to
-# a very small number (usually 0.) Because of this, the following test
-# *must* written as a function, and the tracking vars *must* be function
-# arguments with default values. Otherwise, the test will loop and loop.
-
-print "testing continue and break in try/except in loop"
-def test_break_continue_loop(extra_burning_oil = 1, count=0):
- big_hippo = 2
- while big_hippo:
- count += 1
+'
+ self.assertEquals(x, y)
+
+ def testEllipsis(self):
+ x = ...
+ self.assert_(x is Ellipsis)
+
+class GrammarTests(unittest.TestCase):
+
+ # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
+ # XXX can't test in a script -- this rule is only used when interactive
+
+ # file_input: (NEWLINE | stmt)* ENDMARKER
+ # Being tested as this very moment this very module
+
+ # expr_input: testlist NEWLINE
+ # XXX Hard to test -- used only in calls to input()
+
+ def testEvalInput(self):
+ # testlist ENDMARKER
+ x = eval('1, 0 or 1')
+
+ def testFuncdef(self):
+ ### 'def' NAME parameters ':' suite
+ ### parameters: '(' [varargslist] ')'
+ ### varargslist: (fpdef ['=' test] ',')*
+ ### ('*' (NAME|',' fpdef ['=' test]) [',' ('**'|'*' '*') NAME]
+ ### | ('**'|'*' '*') NAME)
+ ### | fpdef ['=' test] (',' fpdef ['=' test])* [',']
+ ### fpdef: NAME | '(' fplist ')'
+ ### fplist: fpdef (',' fpdef)* [',']
+ ### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test)
+ ### argument: [test '='] test # Really [keyword '='] test
+ def f1(): pass
+ f1()
+ f1(*())
+ f1(*(), **{})
+ def f2(one_argument): pass
+ def f3(two, arguments): pass
+ def f4(two, (compound, (argument, list))): pass
+ def f5((compound, first), two): pass
+ self.assertEquals(f2.func_code.co_varnames, ('one_argument',))
+ self.assertEquals(f3.func_code.co_varnames, ('two', 'arguments'))
+ if sys.platform.startswith('java'):
+ self.assertEquals(f4.func_code.co_varnames,
+ ('two', '(compound, (argument, list))', 'compound', 'argument',
+ 'list',))
+ self.assertEquals(f5.func_code.co_varnames,
+ ('(compound, first)', 'two', 'compound', 'first'))
+ else:
+ self.assertEquals(f4.func_code.co_varnames,
+ ('two', '.1', 'compound', 'argument', 'list'))
+ self.assertEquals(f5.func_code.co_varnames,
+ ('.0', 'two', 'compound', 'first'))
+ def a1(one_arg,): pass
+ def a2(two, args,): pass
+ def v0(*rest): pass
+ def v1(a, *rest): pass
+ def v2(a, b, *rest): pass
+ def v3(a, (b, c), *rest): return a, b, c, rest
+
+ f1()
+ f2(1)
+ f2(1,)
+ f3(1, 2)
+ f3(1, 2,)
+ f4(1, (2, (3, 4)))
+ v0()
+ v0(1)
+ v0(1,)
+ v0(1,2)
+ v0(1,2,3,4,5,6,7,8,9,0)
+ v1(1)
+ v1(1,)
+ v1(1,2)
+ v1(1,2,3)
+ v1(1,2,3,4,5,6,7,8,9,0)
+ v2(1,2)
+ v2(1,2,3)
+ v2(1,2,3,4)
+ v2(1,2,3,4,5,6,7,8,9,0)
+ v3(1,(2,3))
+ v3(1,(2,3),4)
+ v3(1,(2,3),4,5,6,7,8,9,0)
+
+ # ceval unpacks the formal arguments into the first argcount names;
+ # thus, the names nested inside tuples must appear after these names.
+ if sys.platform.startswith('java'):
+ self.assertEquals(v3.func_code.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c'))
+ else:
+ self.assertEquals(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c'))
+ self.assertEquals(v3(1, (2, 3), 4), (1, 2, 3, (4,)))
+ def d01(a=1): pass
+ d01()
+ d01(1)
+ d01(*(1,))
+ d01(**{'a':2})
+ def d11(a, b=1): pass
+ d11(1)
+ d11(1, 2)
+ d11(1, **{'b':2})
+ def d21(a, b, c=1): pass
+ d21(1, 2)
+ d21(1, 2, 3)
+ d21(*(1, 2, 3))
+ d21(1, *(2, 3))
+ d21(1, 2, *(3,))
+ d21(1, 2, **{'c':3})
+ def d02(a=1, b=2): pass
+ d02()
+ d02(1)
+ d02(1, 2)
+ d02(*(1, 2))
+ d02(1, *(2,))
+ d02(1, **{'b':2})
+ d02(**{'a': 1, 'b': 2})
+ def d12(a, b=1, c=2): pass
+ d12(1)
+ d12(1, 2)
+ d12(1, 2, 3)
+ def d22(a, b, c=1, d=2): pass
+ d22(1, 2)
+ d22(1, 2, 3)
+ d22(1, 2, 3, 4)
+ def d01v(a=1, *rest): pass
+ d01v()
+ d01v(1)
+ d01v(1, 2)
+ d01v(*(1, 2, 3, 4))
+ d01v(*(1,))
+ d01v(**{'a':2})
+ def d11v(a, b=1, *rest): pass
+ d11v(1)
+ d11v(1, 2)
+ d11v(1, 2, 3)
+ def d21v(a, b, c=1, *rest): pass
+ d21v(1, 2)
+ d21v(1, 2, 3)
+ d21v(1, 2, 3, 4)
+ d21v(*(1, 2, 3, 4))
+ d21v(1, 2, **{'c': 3})
+ def d02v(a=1, b=2, *rest): pass
+ d02v()
+ d02v(1)
+ d02v(1, 2)
+ d02v(1, 2, 3)
+ d02v(1, *(2, 3, 4))
+ d02v(**{'a': 1, 'b': 2})
+ def d12v(a, b=1, c=2, *rest): pass
+ d12v(1)
+ d12v(1, 2)
+ d12v(1, 2, 3)
+ d12v(1, 2, 3, 4)
+ d12v(*(1, 2, 3, 4))
+ d12v(1, 2, *(3, 4, 5))
+ d12v(1, *(2,), **{'c': 3})
+ def d22v(a, b, c=1, d=2, *rest): pass
+ d22v(1, 2)
+ d22v(1, 2, 3)
+ d22v(1, 2, 3, 4)
+ d22v(1, 2, 3, 4, 5)
+ d22v(*(1, 2, 3, 4))
+ d22v(1, 2, *(3, 4, 5))
+ d22v(1, *(2, 3), **{'d': 4})
+ def d31v((x)): pass
+ d31v(1)
+ def d32v((x,)): pass
+ d32v((1,))
+ # keyword only argument tests
+ def pos0key1(*, key): return key
+ pos0key1(key=100)
+ def pos2key2(p1, p2, *, k1, k2=100): return p1,p2,k1,k2
+ pos2key2(1, 2, k1=100)
+ pos2key2(1, 2, k1=100, k2=200)
+ pos2key2(1, 2, k2=100, k1=200)
+ def pos2key2dict(p1, p2, *, k1=100, k2, **kwarg): return p1,p2,k1,k2,kwarg
+ pos2key2dict(1,2,k2=100,tokwarg1=100,tokwarg2=200)
+ pos2key2dict(1,2,tokwarg1=100,tokwarg2=200, k2=100)
+
+ def testLambdef(self):
+ ### lambdef: 'lambda' [varargslist] ':' test
+ l1 = lambda : 0
+ self.assertEquals(l1(), 0)
+ l2 = lambda : a[d] # XXX just testing the expression
+ l3 = lambda : [2 < x for x in [-1, 3, 0L]]
+ self.assertEquals(l3(), [0, 1, 0])
+ l4 = lambda x = lambda y = lambda z=1 : z : y() : x()
+ self.assertEquals(l4(), 1)
+ l5 = lambda x, y, z=2: x + y + z
+ self.assertEquals(l5(1, 2), 5)
+ self.assertEquals(l5(1, 2, 3), 6)
+ check_syntax_error(self, "lambda x: x = 2")
+ l6 = lambda x, y, *, k=20: x+y+k
+ self.assertEquals(l6(1,2), 1+2+20)
+ self.assertEquals(l6(1,2,k=10), 1+2+10)
+
+
+ ### stmt: simple_stmt | compound_stmt
+ # Tested below
+
+ def testSimpleStmt(self):
+ ### simple_stmt: small_stmt (';' small_stmt)* [';']
+ x = 1; pass; del x
+ def foo():
+ # verify statments that end with semi-colons
+ x = 1; pass; del x;
+ foo()
+
+ ### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt
+ # Tested below
+
+ def testExprStmt(self):
+ # (exprlist '=')* exprlist
+ 1
+ 1, 2, 3
+ x = 1
+ x = 1, 2, 3
+ x = y = z = 1, 2, 3
+ x, y, z = 1, 2, 3
+ abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4)
+
+ check_syntax_error(self, "x + 1 = 1")
+ check_syntax_error(self, "a + 1 = b + 2")
+
+ def testPrintStmt(self):
+ # 'print' (test ',')* [test]
+ import StringIO
+
+ # Can't test printing to real stdout without comparing output
+ # which is not available in unittest.
+ save_stdout = sys.stdout
+ sys.stdout = StringIO.StringIO()
+
+ print 1, 2, 3
+ print 1, 2, 3,
+ print
+ print 0 or 1, 0 or 1,
+ print 0 or 1
+
+ # 'print' '>>' test ','
+ print >> sys.stdout, 1, 2, 3
+ print >> sys.stdout, 1, 2, 3,
+ print >> sys.stdout
+ print >> sys.stdout, 0 or 1, 0 or 1,
+ print >> sys.stdout, 0 or 1
+
+ # test printing to an instance
+ class Gulp:
+ def write(self, msg): pass
+
+ gulp = Gulp()
+ print >> gulp, 1, 2, 3
+ print >> gulp, 1, 2, 3,
+ print >> gulp
+ print >> gulp, 0 or 1, 0 or 1,
+ print >> gulp, 0 or 1
+
+ # test print >> None
+ def driver():
+ oldstdout = sys.stdout
+ sys.stdout = Gulp()
+ try:
+ tellme(Gulp())
+ tellme()
+ finally:
+ sys.stdout = oldstdout
+
+ # we should see this once
+ def tellme(file=sys.stdout):
+ print >> file, 'hello world'
+
+ driver()
+
+ # we should not see this at all
+ def tellme(file=None):
+ print >> file, 'goodbye universe'
+
+ driver()
+
+ self.assertEqual(sys.stdout.getvalue(), '''\
+1 2 3
+1 2 3
+1 1 1
+1 2 3
+1 2 3
+1 1 1
+hello world
+''')
+ sys.stdout = save_stdout
+
+ # syntax errors
+ check_syntax_error(self, 'print ,')
+ check_syntax_error(self, 'print >> x,')
+
+ def testDelStmt(self):
+ # 'del' exprlist
+ abc = [1,2,3]
+ x, y, z = abc
+ xyz = x, y, z
+
+ del abc
+ del x, y, (z, xyz)
+
+ def testPassStmt(self):
+ # 'pass'
+ pass
+
+ # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt
+ # Tested below
+
+ def testBreakStmt(self):
+ # 'break'
+ while 1: break
+
+ def testContinueStmt(self):
+ # 'continue'
+ i = 1
+ while i: i = 0; continue
+
+ msg = ""
+ while not msg:
+ msg = "ok"
+ try:
+ continue
+ msg = "continue failed to continue inside try"
+ except:
+ msg = "continue inside try called except block"
+ if msg != "ok":
+ self.fail(msg)
+
+ msg = ""
+ while not msg:
+ msg = "finally block not called"
+ try:
+ continue
+ finally:
+ msg = "ok"
+ if msg != "ok":
+ self.fail(msg)
+
+ def test_break_continue_loop(self):
+ # This test warrants an explanation. It is a test specifically for SF bugs
+ # #463359 and #462937. The bug is that a 'break' statement executed or
+ # exception raised inside a try/except inside a loop, *after* a continue
+ # statement has been executed in that loop, will cause the wrong number of
+ # arguments to be popped off the stack and the instruction pointer reset to
+ # a very small number (usually 0.) Because of this, the following test
+ # *must* written as a function, and the tracking vars *must* be function
+ # arguments with default values. Otherwise, the test will loop and loop.
+
+ def test_inner(extra_burning_oil = 1, count=0):
+ big_hippo = 2
+ while big_hippo:
+ count += 1
+ try:
+ if extra_burning_oil and big_hippo == 1:
+ extra_burning_oil -= 1
+ break
+ big_hippo -= 1
+ continue
+ except:
+ raise
+ if count > 2 or big_hippo != 1:
+ self.fail("continue then break in try/except in loop broken!")
+ test_inner()
+
+ def testReturn(self):
+ # 'return' [testlist]
+ def g1(): return
+ def g2(): return 1
+ g1()
+ x = g2()
+ check_syntax_error(self, "class foo:return 1")
+
+ def testYield(self):
+ check_syntax_error(self, "class foo:yield 1")
+
+ def testRaise(self):
+ # 'raise' test [',' test]
+ try: raise RuntimeError, 'just testing'
+ except RuntimeError: pass
+ try: raise KeyboardInterrupt
+ except KeyboardInterrupt: pass
+
+ def testImport(self):
+ # 'import' dotted_as_names
+ import sys
+ import time, sys
+ # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names)
+ from time import time
+ from time import (time)
+ # not testable inside a function, but already done at top of the module
+ # from sys import *
+ from sys import path, argv
+ from sys import (path, argv)
+ from sys import (path, argv,)
+
+ def testGlobal(self):
+ # 'global' NAME (',' NAME)*
+ global a
+ global a, b
+ global one, two, three, four, five, six, seven, eight, nine, ten
+
+ def testAssert(self):
+ # assert_stmt: 'assert' test [',' test]
+ assert 1
+ assert 1, 1
+ assert lambda x:x
+ assert 1, lambda x:x+1
try:
- if extra_burning_oil and big_hippo == 1:
- extra_burning_oil -= 1
- break
- big_hippo -= 1
- continue
- except:
- raise
- if count > 2 or big_hippo != 1:
- print "continue then break in try/except in loop broken!"
-test_break_continue_loop()
-
-print 'return_stmt' # 'return' [testlist]
-def g1(): return
-def g2(): return 1
-g1()
-x = g2()
-check_syntax("class foo:return 1")
-
-print 'yield_stmt'
-check_syntax("class foo:yield 1")
-
-print 'raise_stmt' # 'raise' test [',' test]
-try: raise RuntimeError, 'just testing'
-except RuntimeError: pass
-try: raise KeyboardInterrupt
-except KeyboardInterrupt: pass
-
-print 'import_name' # 'import' dotted_as_names
-import sys
-import time, sys
-print 'import_from' # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names)
-from time import time
-from time import (time)
-from sys import *
-from sys import path, argv
-from sys import (path, argv)
-from sys import (path, argv,)
-
-print 'global_stmt' # 'global' NAME (',' NAME)*
-def f():
- global a
- global a, b
- global one, two, three, four, five, six, seven, eight, nine, ten
-
-print "assert_stmt" # assert_stmt: 'assert' test [',' test]
-assert 1
-assert 1, 1
-assert lambda x:x
-assert 1, lambda x:x+1
-
-### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
-# Tested below
-
-print 'if_stmt' # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
-if 1: pass
-if 1: pass
-else: pass
-if 0: pass
-elif 0: pass
-if 0: pass
-elif 0: pass
-elif 0: pass
-elif 0: pass
-else: pass
-
-print 'while_stmt' # 'while' test ':' suite ['else' ':' suite]
-while 0: pass
-while 0: pass
-else: pass
-
-print 'for_stmt' # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
-for i in 1, 2, 3: pass
-for i, j, k in (): pass
-else: pass
-class Squares:
- def __init__(self, max):
- self.max = max
- self.sofar = []
- def __len__(self): return len(self.sofar)
- def __getitem__(self, i):
- if not 0 <= i < self.max: raise IndexError
- n = len(self.sofar)
- while n <= i:
- self.sofar.append(n*n)
- n = n+1
- return self.sofar[i]
-n = 0
-for x in Squares(10): n = n+x
-if n != 285: raise TestFailed, 'for over growing sequence'
-
-result = []
-for x, in [(1,), (2,), (3,)]:
- result.append(x)
-vereq(result, [1, 2, 3])
-
-print 'try_stmt'
-### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
-### | 'try' ':' suite 'finally' ':' suite
-### except_clause: 'except' [expr [',' expr]]
-try:
- 1/0
-except ZeroDivisionError:
- pass
-else:
- pass
-try: 1/0
-except EOFError: pass
-except TypeError, msg: pass
-except RuntimeError, msg: pass
-except: pass
-else: pass
-try: 1/0
-except (EOFError, TypeError, ZeroDivisionError): pass
-try: 1/0
-except (EOFError, TypeError, ZeroDivisionError), msg: pass
-try: pass
-finally: pass
-
-print 'suite' # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
-if 1: pass
-if 1:
- pass
-if 1:
- #
- #
- #
- pass
- pass
- #
- pass
- #
-
-print 'test'
-### and_test ('or' and_test)*
-### and_test: not_test ('and' not_test)*
-### not_test: 'not' not_test | comparison
-if not 1: pass
-if 1 and 1: pass
-if 1 or 1: pass
-if not not not 1: pass
-if not 1 and 1 and 1: pass
-if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass
-
-print 'comparison'
-### comparison: expr (comp_op expr)*
-### comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not'
-if 1: pass
-x = (1 == 1)
-if 1 == 1: pass
-if 1 != 1: pass
-if 1 < 1: pass
-if 1 > 1: pass
-if 1 <= 1: pass
-if 1 >= 1: pass
-if 1 is 1: pass
-if 1 is not 1: pass
-if 1 in (): pass
-if 1 not in (): pass
-if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: pass
-
-print 'binary mask ops'
-x = 1 & 1
-x = 1 ^ 1
-x = 1 | 1
-
-print 'shift ops'
-x = 1 << 1
-x = 1 >> 1
-x = 1 << 1 >> 1
-
-print 'additive ops'
-x = 1
-x = 1 + 1
-x = 1 - 1 - 1
-x = 1 - 1 + 1 - 1 + 1
-
-print 'multiplicative ops'
-x = 1 * 1
-x = 1 / 1
-x = 1 % 1
-x = 1 / 1 * 1 % 1
-
-print 'unary ops'
-x = +1
-x = -1
-x = ~1
-x = ~1 ^ 1 & 1 | 1 & 1 ^ -1
-x = -1*1/1 + 1*1 - ---1*1
-
-print 'selectors'
-### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME
-### subscript: expr | [expr] ':' [expr]
-f1()
-f2(1)
-f2(1,)
-f3(1, 2)
-f3(1, 2,)
-f4(1, (2, (3, 4)))
-v0()
-v0(1)
-v0(1,)
-v0(1,2)
-v0(1,2,3,4,5,6,7,8,9,0)
-v1(1)
-v1(1,)
-v1(1,2)
-v1(1,2,3)
-v1(1,2,3,4,5,6,7,8,9,0)
-v2(1,2)
-v2(1,2,3)
-v2(1,2,3,4)
-v2(1,2,3,4,5,6,7,8,9,0)
-v3(1,(2,3))
-v3(1,(2,3),4)
-v3(1,(2,3),4,5,6,7,8,9,0)
-print
-import sys, time
-c = sys.path[0]
-x = time.time()
-x = sys.modules['time'].time()
-a = '01234'
-c = a[0]
-c = a[-1]
-s = a[0:5]
-s = a[:5]
-s = a[0:]
-s = a[:]
-s = a[-5:]
-s = a[:-1]
-s = a[-4:-3]
-# A rough test of SF bug 1333982. http://python.org/sf/1333982
-# The testing here is fairly incomplete.
-# Test cases should include: commas with 1 and 2 colons
-d = {}
-d[1] = 1
-d[1,] = 2
-d[1,2] = 3
-d[1,2,3] = 4
-L = list(d)
-L.sort(key=lambda x: x if isinstance(x, tuple) else ())
-print L
-
-
-print 'atoms'
-### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictsetmaker] '}' | NAME | NUMBER | STRING
-### dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [','])
-
-x = (1)
-x = (1 or 2 or 3)
-x = (1 or 2 or 3, 2, 3)
-
-x = []
-x = [1]
-x = [1 or 2 or 3]
-x = [1 or 2 or 3, 2, 3]
-x = []
-
-x = {}
-x = {'one': 1}
-x = {'one': 1,}
-x = {'one' or 'two': 1 or 2}
-x = {'one': 1, 'two': 2}
-x = {'one': 1, 'two': 2,}
-x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6}
-
-x = {'one'}
-x = {'one', 1,}
-x = {'one', 'two', 'three'}
-x = {2, 3, 4,}
-
-x = x
-x = 'x'
-x = 123
-
-### exprlist: expr (',' expr)* [',']
-### testlist: test (',' test)* [',']
-# These have been exercised enough above
-
-print 'classdef' # 'class' NAME ['(' [testlist] ')'] ':' suite
-class B: pass
-class B2(): pass
-class C1(B): pass
-class C2(B): pass
-class D(C1, C2, B): pass
-class C:
- def meth1(self): pass
- def meth2(self, arg): pass
- def meth3(self, a1, a2): pass
-
-# list comprehension tests
-nums = [1, 2, 3, 4, 5]
-strs = ["Apple", "Banana", "Coconut"]
-spcs = [" Apple", " Banana ", "Coco nut "]
-
-print [s.strip() for s in spcs]
-print [3 * x for x in nums]
-print [x for x in nums if x > 2]
-print [(i, s) for i in nums for s in strs]
-print [(i, s) for i in nums for s in [f for f in strs if "n" in f]]
-print [(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)]
-
-def test_in_func(l):
- return [0 < x < 3 for x in l if x > 2]
-
-print test_in_func(nums)
-
-def test_nested_front():
- print [[y for y in [x, x + 1]] for x in [1,3,5]]
-
-test_nested_front()
-
-check_syntax("[i, s for i in nums for s in strs]")
-check_syntax("[x if y]")
-
-suppliers = [
- (1, "Boeing"),
- (2, "Ford"),
- (3, "Macdonalds")
-]
-
-parts = [
- (10, "Airliner"),
- (20, "Engine"),
- (30, "Cheeseburger")
-]
-
-suppart = [
- (1, 10), (1, 20), (2, 20), (3, 30)
-]
-
-print [
- (sname, pname)
- for (sno, sname) in suppliers
- for (pno, pname) in parts
- for (sp_sno, sp_pno) in suppart
- if sno == sp_sno and pno == sp_pno
-]
-
-# generator expression tests
-g = ([x for x in range(10)] for x in range(1))
-verify(g.next() == [x for x in range(10)])
-try:
- g.next()
- raise TestFailed, 'should produce StopIteration exception'
-except StopIteration:
- pass
-
-a = 1
-try:
- g = (a for d in a)
- g.next()
- raise TestFailed, 'should produce TypeError'
-except TypeError:
- pass
-
-verify(list((x, y) for x in 'abcd' for y in 'abcd') == [(x, y) for x in 'abcd' for y in 'abcd'])
-verify(list((x, y) for x in 'ab' for y in 'xy') == [(x, y) for x in 'ab' for y in 'xy'])
-
-a = [x for x in range(10)]
-b = (x for x in (y for y in a))
-verify(sum(b) == sum([x for x in range(10)]))
-
-verify(sum(x**2 for x in range(10)) == sum([x**2 for x in range(10)]))
-verify(sum(x*x for x in range(10) if x%2) == sum([x*x for x in range(10) if x%2]))
-verify(sum(x for x in (y for y in range(10))) == sum([x for x in range(10)]))
-verify(sum(x for x in (y for y in (z for z in range(10)))) == sum([x for x in range(10)]))
-verify(sum(x for x in [y for y in (z for z in range(10))]) == sum([x for x in range(10)]))
-verify(sum(x for x in (y for y in (z for z in range(10) if True)) if True) == sum([x for x in range(10)]))
-verify(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True) == 0)
-check_syntax("foo(x for x in range(10), 100)")
-check_syntax("foo(100, x for x in range(10))")
-
-# test for outmost iterable precomputation
-x = 10; g = (i for i in range(x)); x = 5
-verify(len(list(g)) == 10)
-
-# This should hold, since we're only precomputing outmost iterable.
-x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x))
-x = 5; t = True;
-verify([(i,j) for i in range(10) for j in range(5)] == list(g))
-
-# Grammar allows multiple adjacent 'if's in listcomps and genexps,
-# even though it's silly. Make sure it works (ifelse broke this.)
-verify([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7])
-verify((x for x in range(10) if x % 2 if x % 3), [1, 5, 7])
-
-# Test ifelse expressions in various cases
-def _checkeval(msg, ret):
- "helper to check that evaluation of expressions is done correctly"
- print x
- return ret
-
-verify([ x() for x in lambda: True, lambda: False if x() ] == [True])
-verify([ x() for x in (lambda: True, lambda: False) if x() ] == [True])
-verify([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ] == [True])
-verify((5 if 1 else _checkeval("check 1", 0)) == 5)
-verify((_checkeval("check 2", 0) if 0 else 5) == 5)
-verify((5 and 6 if 0 else 1) == 1)
-verify(((5 and 6) if 0 else 1) == 1)
-verify((5 and (6 if 1 else 1)) == 6)
-verify((0 or _checkeval("check 3", 2) if 0 else 3) == 3)
-verify((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)) == 1)
-verify((0 or 5 if 1 else _checkeval("check 6", 3)) == 5)
-verify((not 5 if 1 else 1) == False)
-verify((not 5 if 0 else 1) == 1)
-verify((6 + 1 if 1 else 2) == 7)
-verify((6 - 1 if 1 else 2) == 5)
-verify((6 * 2 if 1 else 4) == 12)
-verify((6 / 2 if 1 else 3) == 3)
-verify((6 < 4 if 0 else 2) == 2)
+ assert 0, "msg"
+ except AssertionError, e:
+ self.assertEquals(e.args[0], "msg")
+ else:
+ if __debug__:
+ self.fail("AssertionError not raised by assert 0")
+
+ ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
+ # Tested below
+
+ def testIf(self):
+ # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+ if 1: pass
+ if 1: pass
+ else: pass
+ if 0: pass
+ elif 0: pass
+ if 0: pass
+ elif 0: pass
+ elif 0: pass
+ elif 0: pass
+ else: pass
+
+ def testWhile(self):
+ # 'while' test ':' suite ['else' ':' suite]
+ while 0: pass
+ while 0: pass
+ else: pass
+
+ def testFor(self):
+ # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
+ for i in 1, 2, 3: pass
+ for i, j, k in (): pass
+ else: pass
+ class Squares:
+ def __init__(self, max):
+ self.max = max
+ self.sofar = []
+ def __len__(self): return len(self.sofar)
+ def __getitem__(self, i):
+ if not 0 <= i < self.max: raise IndexError
+ n = len(self.sofar)
+ while n <= i:
+ self.sofar.append(n*n)
+ n = n+1
+ return self.sofar[i]
+ n = 0
+ for x in Squares(10): n = n+x
+ if n != 285:
+ self.fail('for over growing sequence')
+
+ result = []
+ for x, in [(1,), (2,), (3,)]:
+ result.append(x)
+ self.assertEqual(result, [1, 2, 3])
+
+ def testTry(self):
+ ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
+ ### | 'try' ':' suite 'finally' ':' suite
+ ### except_clause: 'except' [expr [',' expr]]
+ try:
+ 1/0
+ except ZeroDivisionError:
+ pass
+ else:
+ pass
+ try: 1/0
+ except EOFError: pass
+ except TypeError, msg: pass
+ except RuntimeError, msg: pass
+ except: pass
+ else: pass
+ try: 1/0
+ except (EOFError, TypeError, ZeroDivisionError): pass
+ try: 1/0
+ except (EOFError, TypeError, ZeroDivisionError), msg: pass
+ try: pass
+ finally: pass
+
+ def testSuite(self):
+ # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
+ if 1: pass
+ if 1:
+ pass
+ if 1:
+ #
+ #
+ #
+ pass
+ pass
+ #
+ pass
+ #
+
+ def testTest(self):
+ ### and_test ('or' and_test)*
+ ### and_test: not_test ('and' not_test)*
+ ### not_test: 'not' not_test | comparison
+ if not 1: pass
+ if 1 and 1: pass
+ if 1 or 1: pass
+ if not not not 1: pass
+ if not 1 and 1 and 1: pass
+ if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass
+
+ def testComparison(self):
+ ### comparison: expr (comp_op expr)*
+ ### comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not'
+ if 1: pass
+ x = (1 == 1)
+ if 1 == 1: pass
+ if 1 != 1: pass
+ if 1 < 1: pass
+ if 1 > 1: pass
+ if 1 <= 1: pass
+ if 1 >= 1: pass
+ if 1 is 1: pass
+ if 1 is not 1: pass
+ if 1 in (): pass
+ if 1 not in (): pass
+ if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: pass
+
+ def testBinaryMaskOps(self):
+ x = 1 & 1
+ x = 1 ^ 1
+ x = 1 | 1
+
+ def testShiftOps(self):
+ x = 1 << 1
+ x = 1 >> 1
+ x = 1 << 1 >> 1
+
+ def testAdditiveOps(self):
+ x = 1
+ x = 1 + 1
+ x = 1 - 1 - 1
+ x = 1 - 1 + 1 - 1 + 1
+
+ def testMultiplicativeOps(self):
+ x = 1 * 1
+ x = 1 / 1
+ x = 1 % 1
+ x = 1 / 1 * 1 % 1
+
+ def testUnaryOps(self):
+ x = +1
+ x = -1
+ x = ~1
+ x = ~1 ^ 1 & 1 | 1 & 1 ^ -1
+ x = -1*1/1 + 1*1 - ---1*1
+
+ def testSelectors(self):
+ ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME
+ ### subscript: expr | [expr] ':' [expr]
+
+ import sys, time
+ c = sys.path[0]
+ x = time.time()
+ x = sys.modules['time'].time()
+ a = '01234'
+ c = a[0]
+ c = a[-1]
+ s = a[0:5]
+ s = a[:5]
+ s = a[0:]
+ s = a[:]
+ s = a[-5:]
+ s = a[:-1]
+ s = a[-4:-3]
+ # A rough test of SF bug 1333982. http://python.org/sf/1333982
+ # The testing here is fairly incomplete.
+ # Test cases should include: commas with 1 and 2 colons
+ d = {}
+ d[1] = 1
+ d[1,] = 2
+ d[1,2] = 3
+ d[1,2,3] = 4
+ L = list(d)
+ L.sort(key=lambda x: x if isinstance(x, tuple) else ())
+ self.assertEquals(str(L), '[1, (1,), (1, 2), (1, 2, 3)]')
+
+ def testAtoms(self):
+ ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictsetmaker] '}' | NAME | NUMBER | STRING
+ ### dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [','])
+
+ x = (1)
+ x = (1 or 2 or 3)
+ x = (1 or 2 or 3, 2, 3)
+
+ x = []
+ x = [1]
+ x = [1 or 2 or 3]
+ x = [1 or 2 or 3, 2, 3]
+ x = []
+
+ x = {}
+ x = {'one': 1}
+ x = {'one': 1,}
+ x = {'one' or 'two': 1 or 2}
+ x = {'one': 1, 'two': 2}
+ x = {'one': 1, 'two': 2,}
+ x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6}
+
+ x = {'one'}
+ x = {'one', 1,}
+ x = {'one', 'two', 'three'}
+ x = {2, 3, 4,}
+
+ x = x
+ x = 'x'
+ x = 123
+
+ ### exprlist: expr (',' expr)* [',']
+ ### testlist: test (',' test)* [',']
+ # These have been exercised enough above
+
+ def testClassdef(self):
+ # 'class' NAME ['(' [testlist] ')'] ':' suite
+ class B: pass
+ class B2(): pass
+ class C1(B): pass
+ class C2(B): pass
+ class D(C1, C2, B): pass
+ class C:
+ def meth1(self): pass
+ def meth2(self, arg): pass
+ def meth3(self, a1, a2): pass
+
+ def testListcomps(self):
+ # list comprehension tests
+ nums = [1, 2, 3, 4, 5]
+ strs = ["Apple", "Banana", "Coconut"]
+ spcs = [" Apple", " Banana ", "Coco nut "]
+
+ self.assertEqual([s.strip() for s in spcs], ['Apple', 'Banana', 'Coco nut'])
+ self.assertEqual([3 * x for x in nums], [3, 6, 9, 12, 15])
+ self.assertEqual([x for x in nums if x > 2], [3, 4, 5])
+ self.assertEqual([(i, s) for i in nums for s in strs],
+ [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'),
+ (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'),
+ (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'),
+ (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'),
+ (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')])
+ self.assertEqual([(i, s) for i in nums for s in [f for f in strs if "n" in f]],
+ [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'),
+ (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'),
+ (5, 'Banana'), (5, 'Coconut')])
+ self.assertEqual([(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)],
+ [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]])
+
+ def test_in_func(l):
+ return [0 < x < 3 for x in l if x > 2]
+
+ self.assertEqual(test_in_func(nums), [False, False, False])
+
+ def test_nested_front():
+ self.assertEqual([[y for y in [x, x + 1]] for x in [1,3,5]],
+ [[1, 2], [3, 4], [5, 6]])
+
+ test_nested_front()
+
+ check_syntax_error(self, "[i, s for i in nums for s in strs]")
+ check_syntax_error(self, "[x if y]")
+
+ suppliers = [
+ (1, "Boeing"),
+ (2, "Ford"),
+ (3, "Macdonalds")
+ ]
+
+ parts = [
+ (10, "Airliner"),
+ (20, "Engine"),
+ (30, "Cheeseburger")
+ ]
+
+ suppart = [
+ (1, 10), (1, 20), (2, 20), (3, 30)
+ ]
+
+ x = [
+ (sname, pname)
+ for (sno, sname) in suppliers
+ for (pno, pname) in parts
+ for (sp_sno, sp_pno) in suppart
+ if sno == sp_sno and pno == sp_pno
+ ]
+
+ self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'),
+ ('Macdonalds', 'Cheeseburger')])
+
+ def testGenexps(self):
+ # generator expression tests
+ g = ([x for x in range(10)] for x in range(1))
+ self.assertEqual(g.next(), [x for x in range(10)])
+ try:
+ g.next()
+ self.fail('should produce StopIteration exception')
+ except StopIteration:
+ pass
+
+ a = 1
+ try:
+ g = (a for d in a)
+ g.next()
+ self.fail('should produce TypeError')
+ except TypeError:
+ pass
+
+ self.assertEqual(list((x, y) for x in 'abcd' for y in 'abcd'), [(x, y) for x in 'abcd' for y in 'abcd'])
+ self.assertEqual(list((x, y) for x in 'ab' for y in 'xy'), [(x, y) for x in 'ab' for y in 'xy'])
+
+ a = [x for x in range(10)]
+ b = (x for x in (y for y in a))
+ self.assertEqual(sum(b), sum([x for x in range(10)]))
+
+ self.assertEqual(sum(x**2 for x in range(10)), sum([x**2 for x in range(10)]))
+ self.assertEqual(sum(x*x for x in range(10) if x%2), sum([x*x for x in range(10) if x%2]))
+ self.assertEqual(sum(x for x in (y for y in range(10))), sum([x for x in range(10)]))
+ self.assertEqual(sum(x for x in (y for y in (z for z in range(10)))), sum([x for x in range(10)]))
+ self.assertEqual(sum(x for x in [y for y in (z for z in range(10))]), sum([x for x in range(10)]))
+ self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True)) if True), sum([x for x in range(10)]))
+ self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True), 0)
+ check_syntax_error(self, "foo(x for x in range(10), 100)")
+ check_syntax_error(self, "foo(100, x for x in range(10))")
+
+ def testComprehensionSpecials(self):
+ # test for outmost iterable precomputation
+ x = 10; g = (i for i in range(x)); x = 5
+ self.assertEqual(len(list(g)), 10)
+
+ # This should hold, since we're only precomputing outmost iterable.
+ x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x))
+ x = 5; t = True;
+ self.assertEqual([(i,j) for i in range(10) for j in range(5)], list(g))
+
+ # Grammar allows multiple adjacent 'if's in listcomps and genexps,
+ # even though it's silly. Make sure it works (ifelse broke this.)
+ self.assertEqual([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7])
+ self.assertEqual(list(x for x in range(10) if x % 2 if x % 3), [1, 5, 7])
+
+ # verify unpacking single element tuples in listcomp/genexp.
+ self.assertEqual([x for x, in [(4,), (5,), (6,)]], [4, 5, 6])
+ self.assertEqual(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9])
+
+ def testIfElseExpr(self):
+ # Test ifelse expressions in various cases
+ def _checkeval(msg, ret):
+ "helper to check that evaluation of expressions is done correctly"
+ print x
+ return ret
+
+ self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True])
+ self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True])
+ self.assertEqual([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ], [True])
+ self.assertEqual((5 if 1 else _checkeval("check 1", 0)), 5)
+ self.assertEqual((_checkeval("check 2", 0) if 0 else 5), 5)
+ self.assertEqual((5 and 6 if 0 else 1), 1)
+ self.assertEqual(((5 and 6) if 0 else 1), 1)
+ self.assertEqual((5 and (6 if 1 else 1)), 6)
+ self.assertEqual((0 or _checkeval("check 3", 2) if 0 else 3), 3)
+ self.assertEqual((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)), 1)
+ self.assertEqual((0 or 5 if 1 else _checkeval("check 6", 3)), 5)
+ self.assertEqual((not 5 if 1 else 1), False)
+ self.assertEqual((not 5 if 0 else 1), 1)
+ self.assertEqual((6 + 1 if 1 else 2), 7)
+ self.assertEqual((6 - 1 if 1 else 2), 5)
+ self.assertEqual((6 * 2 if 1 else 4), 12)
+ self.assertEqual((6 / 2 if 1 else 3), 3)
+ self.assertEqual((6 < 4 if 0 else 2), 2)
+
+
+def test_main():
+ run_unittest(TokenTests, GrammarTests)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py
index 0f8e03e..9989a92 100644
--- a/Lib/test/test_gzip.py
+++ b/Lib/test/test_gzip.py
@@ -128,6 +128,17 @@ class TestGzip(unittest.TestCase):
f.seek(newpos) # positive seek
f.close()
+ def test_seek_whence(self):
+ self.test_write()
+ # Try seek(whence=1), read test
+
+ f = gzip.GzipFile(self.filename)
+ f.read(10)
+ f.seek(10, whence=1)
+ y = f.read(10)
+ f.close()
+ self.assertEquals(y, data1[20:30])
+
def test_seek_write(self):
# Try seek, write test
f = gzip.GzipFile(self.filename, 'w')
diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
index 90bae88..90a4e55 100644
--- a/Lib/test/test_httplib.py
+++ b/Lib/test/test_httplib.py
@@ -10,9 +10,10 @@ class FakeSocket:
def __init__(self, text, fileclass=StringIO.StringIO):
self.text = text
self.fileclass = fileclass
+ self.data = ''
def sendall(self, data):
- self.data = data
+ self.data += data
def makefile(self, mode, bufsize=None):
if mode != 'r' and mode != 'rb':
@@ -70,103 +71,86 @@ class HeaderTests(TestCase):
conn.request('POST', '/', body, headers)
self.assertEqual(conn._buffer.count[header.lower()], 1)
-# Collect output to a buffer so that we don't have to cope with line-ending
-# issues across platforms. Specifically, the headers will have \r\n pairs
-# and some platforms will strip them from the output file.
-
-def test():
- buf = StringIO.StringIO()
- _stdout = sys.stdout
- try:
- sys.stdout = buf
- _test()
- finally:
- sys.stdout = _stdout
-
- # print individual lines with endings stripped
- s = buf.getvalue()
- for line in s.split("\n"):
- print line.strip()
-
-def _test():
- # Test HTTP status lines
-
- body = "HTTP/1.1 200 Ok\r\n\r\nText"
- sock = FakeSocket(body)
- resp = httplib.HTTPResponse(sock, 1)
- resp.begin()
- print resp.read()
- resp.close()
-
- body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText"
- sock = FakeSocket(body)
- resp = httplib.HTTPResponse(sock, 1)
- try:
+class BasicTest(TestCase):
+ def test_status_lines(self):
+ # Test HTTP status lines
+
+ body = "HTTP/1.1 200 Ok\r\n\r\nText"
+ sock = FakeSocket(body)
+ resp = httplib.HTTPResponse(sock)
resp.begin()
- except httplib.BadStatusLine:
- print "BadStatusLine raised as expected"
- else:
- print "Expect BadStatusLine"
-
- # Check invalid host_port
-
- for hp in ("www.python.org:abc", "www.python.org:"):
- try:
- h = httplib.HTTP(hp)
- except httplib.InvalidURL:
- print "InvalidURL raised as expected"
- else:
- print "Expect InvalidURL"
-
- for hp,h,p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b", 8000),
- ("www.python.org:80", "www.python.org", 80),
- ("www.python.org", "www.python.org", 80),
- ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
- try:
+ self.assertEqual(resp.read(), 'Text')
+ resp.close()
+
+ body = "HTTP/1.1 400.100 Not Ok\r\n\r\nText"
+ sock = FakeSocket(body)
+ resp = httplib.HTTPResponse(sock)
+ self.assertRaises(httplib.BadStatusLine, resp.begin)
+
+ def test_host_port(self):
+ # Check invalid host_port
+
+ for hp in ("www.python.org:abc", "www.python.org:"):
+ self.assertRaises(httplib.InvalidURL, httplib.HTTP, hp)
+
+ for hp, h, p in (("[fe80::207:e9ff:fe9b]:8000", "fe80::207:e9ff:fe9b", 8000),
+ ("www.python.org:80", "www.python.org", 80),
+ ("www.python.org", "www.python.org", 80),
+ ("[fe80::207:e9ff:fe9b]", "fe80::207:e9ff:fe9b", 80)):
http = httplib.HTTP(hp)
- except httplib.InvalidURL:
- print "InvalidURL raised erroneously"
- c = http._conn
- if h != c.host: raise AssertionError, ("Host incorrectly parsed", h, c.host)
- if p != c.port: raise AssertionError, ("Port incorrectly parsed", p, c.host)
-
- # test response with multiple message headers with the same field name.
- text = ('HTTP/1.1 200 OK\r\n'
- 'Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"\r\n'
- 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
- ' Path="/acme"\r\n'
- '\r\n'
- 'No body\r\n')
- hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
- ', '
- 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
- s = FakeSocket(text)
- r = httplib.HTTPResponse(s, 1)
- r.begin()
- cookies = r.getheader("Set-Cookie")
- if cookies != hdr:
- raise AssertionError, "multiple headers not combined properly"
-
- # Test that the library doesn't attempt to read any data
- # from a HEAD request. (Tickles SF bug #622042.)
- sock = FakeSocket(
- 'HTTP/1.1 200 OK\r\n'
- 'Content-Length: 14432\r\n'
- '\r\n',
- NoEOFStringIO)
- resp = httplib.HTTPResponse(sock, 1, method="HEAD")
- resp.begin()
- if resp.read() != "":
- raise AssertionError, "Did not expect response from HEAD request"
- resp.close()
+ c = http._conn
+ if h != c.host: self.fail("Host incorrectly parsed: %s != %s" % (h, c.host))
+ if p != c.port: self.fail("Port incorrectly parsed: %s != %s" % (p, c.host))
+
+ def test_response_headers(self):
+ # test response with multiple message headers with the same field name.
+ text = ('HTTP/1.1 200 OK\r\n'
+ 'Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"\r\n'
+ 'Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";'
+ ' Path="/acme"\r\n'
+ '\r\n'
+ 'No body\r\n')
+ hdr = ('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"'
+ ', '
+ 'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"')
+ s = FakeSocket(text)
+ r = httplib.HTTPResponse(s)
+ r.begin()
+ cookies = r.getheader("Set-Cookie")
+ if cookies != hdr:
+ self.fail("multiple headers not combined properly")
+
+ def test_read_head(self):
+ # Test that the library doesn't attempt to read any data
+ # from a HEAD request. (Tickles SF bug #622042.)
+ sock = FakeSocket(
+ 'HTTP/1.1 200 OK\r\n'
+ 'Content-Length: 14432\r\n'
+ '\r\n',
+ NoEOFStringIO)
+ resp = httplib.HTTPResponse(sock, method="HEAD")
+ resp.begin()
+ if resp.read() != "":
+ self.fail("Did not expect response from HEAD request")
+ resp.close()
+
+ def test_send_file(self):
+ expected = 'GET /foo HTTP/1.1\r\nHost: example.com\r\n' \
+ 'Accept-Encoding: identity\r\nContent-Length:'
+ body = open(__file__, 'rb')
+ conn = httplib.HTTPConnection('example.com')
+ sock = FakeSocket(body)
+ conn.sock = sock
+ conn.request('GET', '/foo', body)
+ self.assertTrue(sock.data.startswith(expected))
class OfflineTest(TestCase):
def test_responses(self):
self.assertEquals(httplib.responses[httplib.NOT_FOUND], "Not Found")
def test_main(verbose=None):
- tests = [HeaderTests,OfflineTest]
- test_support.run_unittest(*tests)
+ test_support.run_unittest(HeaderTests, OfflineTest, BasicTest)
-test()
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py
index 893ba24..62b14e0 100644
--- a/Lib/test/test_imp.py
+++ b/Lib/test/test_imp.py
@@ -1,43 +1,47 @@
import imp
-from test.test_support import TestFailed, TestSkipped
-try:
- import thread
-except ImportError:
- raise TestSkipped("test only valid when thread support is available")
+import thread
+import unittest
+from test import test_support
-def verify_lock_state(expected):
- if imp.lock_held() != expected:
- raise TestFailed("expected imp.lock_held() to be %r" % expected)
-def testLock():
- LOOPS = 50
+class LockTests(unittest.TestCase):
- # The import lock may already be held, e.g. if the test suite is run
- # via "import test.autotest".
- lock_held_at_start = imp.lock_held()
- verify_lock_state(lock_held_at_start)
+ """Very basic test of import lock functions."""
- for i in range(LOOPS):
- imp.acquire_lock()
- verify_lock_state(True)
+ def verify_lock_state(self, expected):
+ self.failUnlessEqual(imp.lock_held(), expected,
+ "expected imp.lock_held() to be %r" % expected)
+ def testLock(self):
+ LOOPS = 50
- for i in range(LOOPS):
- imp.release_lock()
+ # The import lock may already be held, e.g. if the test suite is run
+ # via "import test.autotest".
+ lock_held_at_start = imp.lock_held()
+ self.verify_lock_state(lock_held_at_start)
- # The original state should be restored now.
- verify_lock_state(lock_held_at_start)
+ for i in range(LOOPS):
+ imp.acquire_lock()
+ self.verify_lock_state(True)
- if not lock_held_at_start:
- try:
+ for i in range(LOOPS):
imp.release_lock()
- except RuntimeError:
- pass
- else:
- raise TestFailed("release_lock() without lock should raise "
- "RuntimeError")
+
+ # The original state should be restored now.
+ self.verify_lock_state(lock_held_at_start)
+
+ if not lock_held_at_start:
+ try:
+ imp.release_lock()
+ except RuntimeError:
+ pass
+ else:
+ self.fail("release_lock() without lock should raise "
+ "RuntimeError")
def test_main():
- testLock()
+ test_support.run_unittest(
+ LockTests,
+ )
if __name__ == "__main__":
test_main()
diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py
index b64c23b..e37378f 100644
--- a/Lib/test/test_import.py
+++ b/Lib/test/test_import.py
@@ -1,21 +1,11 @@
-from test.test_support import TESTFN, TestFailed
+from test.test_support import TESTFN, run_unittest
+import unittest
import os
import random
import sys
import py_compile
-# Brief digression to test that import is case-sensitive: if we got this
-# far, we know for sure that "random" exists.
-try:
- import RAnDoM
-except ImportError:
- pass
-else:
- raise TestFailed("import of RAnDoM should have failed (case mismatch)")
-
-# Another brief digression to test the accuracy of manifest float constants.
-from test import double_const # don't blink -- that *was* the test
def remove_files(name):
for f in (name + os.extsep + "py",
@@ -26,199 +16,206 @@ def remove_files(name):
if os.path.exists(f):
os.remove(f)
-def test_with_extension(ext): # ext normally ".py"; perhaps ".pyw"
- source = TESTFN + ext
- pyo = TESTFN + os.extsep + "pyo"
- if sys.platform.startswith('java'):
- pyc = TESTFN + "$py.class"
- else:
- pyc = TESTFN + os.extsep + "pyc"
-
- f = open(source, "w")
- print >> f, "# This tests Python's ability to import a", ext, "file."
- a = random.randrange(1000)
- b = random.randrange(1000)
- print >> f, "a =", a
- print >> f, "b =", b
- f.close()
-
- try:
- try:
- mod = __import__(TESTFN)
- except ImportError, err:
- raise ValueError("import from %s failed: %s" % (ext, err))
- if mod.a != a or mod.b != b:
- print a, "!=", mod.a
- print b, "!=", mod.b
- raise ValueError("module loaded (%s) but contents invalid" % mod)
- finally:
- os.unlink(source)
+class ImportTest(unittest.TestCase):
- try:
- try:
- reload(mod)
- except ImportError, err:
- raise ValueError("import from .pyc/.pyo failed: %s" % err)
- finally:
+ def testCaseSensitivity(self):
+ # Brief digression to test that import is case-sensitive: if we got this
+ # far, we know for sure that "random" exists.
try:
- os.unlink(pyc)
- except os.error:
+ import RAnDoM
+ except ImportError:
pass
- try:
- os.unlink(pyo)
- except os.error:
- pass
- del sys.modules[TESTFN]
-
-sys.path.insert(0, os.curdir)
-try:
- test_with_extension(os.extsep + "py")
- if sys.platform.startswith("win"):
- for ext in ".PY", ".Py", ".pY", ".pyw", ".PYW", ".pYw":
- test_with_extension(ext)
-finally:
- del sys.path[0]
-
-# Verify that the imp module can correctly load and find .py files
-import imp
-x = imp.find_module("os")
-os = imp.load_module("os", *x)
-
-def test_module_with_large_stack(module):
- # create module w/list of 65000 elements to test bug #561858
- filename = module + os.extsep + 'py'
-
- # create a file with a list of 65000 elements
- f = open(filename, 'w+')
- f.write('d = [\n')
- for i in range(65000):
- f.write('"",\n')
- f.write(']')
- f.close()
-
- # compile & remove .py file, we only need .pyc (or .pyo)
- f = open(filename, 'r')
- py_compile.compile(filename)
- f.close()
- os.unlink(filename)
-
- # need to be able to load from current dir
- sys.path.append('')
-
- # this used to crash
- exec('import ' + module)
-
- # cleanup
- del sys.path[-1]
- for ext in 'pyc', 'pyo':
- fname = module + os.extsep + ext
- if os.path.exists(fname):
- os.unlink(fname)
-
-test_module_with_large_stack('longlist')
-
-def test_failing_import_sticks():
- source = TESTFN + os.extsep + "py"
- f = open(source, "w")
- print >> f, "a = 1/0"
- f.close()
-
- # New in 2.4, we shouldn't be able to import that no matter how often
- # we try.
- sys.path.insert(0, os.curdir)
- try:
- for i in 1, 2, 3:
- try:
- mod = __import__(TESTFN)
- except ZeroDivisionError:
- if TESTFN in sys.modules:
- raise TestFailed("damaged module in sys.modules", i)
+ else:
+ self.fail("import of RAnDoM should have failed (case mismatch)")
+
+ def testDoubleConst(self):
+ # Another brief digression to test the accuracy of manifest float constants.
+ from test import double_const # don't blink -- that *was* the test
+
+ def testImport(self):
+ def test_with_extension(ext):
+ # ext normally ".py"; perhaps ".pyw"
+ source = TESTFN + ext
+ pyo = TESTFN + os.extsep + "pyo"
+ if sys.platform.startswith('java'):
+ pyc = TESTFN + "$py.class"
else:
- raise TestFailed("was able to import a damaged module", i)
- finally:
- sys.path.pop(0)
- remove_files(TESTFN)
-
-test_failing_import_sticks()
-
-def test_failing_reload():
- # A failing reload should leave the module object in sys.modules.
- source = TESTFN + os.extsep + "py"
- f = open(source, "w")
- print >> f, "a = 1"
- print >> f, "b = 2"
- f.close()
-
- sys.path.insert(0, os.curdir)
- try:
- mod = __import__(TESTFN)
- if TESTFN not in sys.modules:
- raise TestFailed("expected module in sys.modules")
- if mod.a != 1 or mod.b != 2:
- raise TestFailed("module has wrong attribute values")
-
- # On WinXP, just replacing the .py file wasn't enough to
- # convince reload() to reparse it. Maybe the timestamp didn't
- # move enough. We force it to get reparsed by removing the
- # compiled file too.
- remove_files(TESTFN)
-
- # Now damage the module.
+ pyc = TESTFN + os.extsep + "pyc"
+
+ f = open(source, "w")
+ print >> f, "# This tests Python's ability to import a", ext, "file."
+ a = random.randrange(1000)
+ b = random.randrange(1000)
+ print >> f, "a =", a
+ print >> f, "b =", b
+ f.close()
+
+ try:
+ try:
+ mod = __import__(TESTFN)
+ except ImportError, err:
+ self.fail("import from %s failed: %s" % (ext, err))
+
+ self.assertEquals(mod.a, a,
+ "module loaded (%s) but contents invalid" % mod)
+ self.assertEquals(mod.b, b,
+ "module loaded (%s) but contents invalid" % mod)
+ finally:
+ os.unlink(source)
+
+ try:
+ try:
+ reload(mod)
+ except ImportError, err:
+ self.fail("import from .pyc/.pyo failed: %s" % err)
+ finally:
+ try:
+ os.unlink(pyc)
+ except OSError:
+ pass
+ try:
+ os.unlink(pyo)
+ except OSError:
+ pass
+ del sys.modules[TESTFN]
+
+ sys.path.insert(0, os.curdir)
+ try:
+ test_with_extension(os.extsep + "py")
+ if sys.platform.startswith("win"):
+ for ext in ".PY", ".Py", ".pY", ".pyw", ".PYW", ".pYw":
+ test_with_extension(ext)
+ finally:
+ del sys.path[0]
+
+ def testImpModule(self):
+ # Verify that the imp module can correctly load and find .py files
+ import imp
+ x = imp.find_module("os")
+ os = imp.load_module("os", *x)
+
+ def test_module_with_large_stack(self, module='longlist'):
+ # create module w/list of 65000 elements to test bug #561858
+ filename = module + os.extsep + 'py'
+
+ # create a file with a list of 65000 elements
+ f = open(filename, 'w+')
+ f.write('d = [\n')
+ for i in range(65000):
+ f.write('"",\n')
+ f.write(']')
+ f.close()
+
+ # compile & remove .py file, we only need .pyc (or .pyo)
+ f = open(filename, 'r')
+ py_compile.compile(filename)
+ f.close()
+ os.unlink(filename)
+
+ # need to be able to load from current dir
+ sys.path.append('')
+
+ # this used to crash
+ exec('import ' + module)
+
+ # cleanup
+ del sys.path[-1]
+ for ext in 'pyc', 'pyo':
+ fname = module + os.extsep + ext
+ if os.path.exists(fname):
+ os.unlink(fname)
+
+ def test_failing_import_sticks(self):
+ source = TESTFN + os.extsep + "py"
f = open(source, "w")
- print >> f, "a = 10"
- print >> f, "b = 20//0"
+ print >> f, "a = 1/0"
f.close()
+
+ # New in 2.4, we shouldn't be able to import that no matter how often
+ # we try.
+ sys.path.insert(0, os.curdir)
try:
- reload(mod)
- except ZeroDivisionError:
- pass
- else:
- raise TestFailed("was able to reload a damaged module")
-
- # But we still expect the module to be in sys.modules.
- mod = sys.modules.get(TESTFN)
- if mod is None:
- raise TestFailed("expected module to still be in sys.modules")
- # We should have replaced a w/ 10, but the old b value should
- # stick.
- if mod.a != 10 or mod.b != 2:
- raise TestFailed("module has wrong attribute values")
-
- finally:
- sys.path.pop(0)
- remove_files(TESTFN)
- if TESTFN in sys.modules:
- del sys.modules[TESTFN]
-
-test_failing_reload()
-
-def test_import_name_binding():
- # import x.y.z binds x in the current namespace
- import test as x
- import test.test_support
- assert x is test, x.__name__
- assert hasattr(test.test_support, "__file__")
-
- # import x.y.z as w binds z as w
- import test.test_support as y
- assert y is test.test_support, y.__name__
-
-test_import_name_binding()
-
-def test_import_initless_directory_warning():
- import warnings
- oldfilters = warnings.filters[:]
- warnings.simplefilter('error', ImportWarning);
- try:
- # Just a random non-package directory we always expect to be
- # somewhere in sys.path...
- __import__("site-packages")
- except ImportWarning:
- pass
- else:
- raise AssertionError
- finally:
- warnings.filters = oldfilters
-
-test_import_initless_directory_warning()
+ for i in 1, 2, 3:
+ try:
+ mod = __import__(TESTFN)
+ except ZeroDivisionError:
+ if TESTFN in sys.modules:
+ self.fail("damaged module in sys.modules on %i. try" % i)
+ else:
+ self.fail("was able to import a damaged module on %i. try" % i)
+ finally:
+ sys.path.pop(0)
+ remove_files(TESTFN)
+
+ def test_failing_reload(self):
+ # A failing reload should leave the module object in sys.modules.
+ source = TESTFN + os.extsep + "py"
+ f = open(source, "w")
+ print >> f, "a = 1"
+ print >> f, "b = 2"
+ f.close()
+
+ sys.path.insert(0, os.curdir)
+ try:
+ mod = __import__(TESTFN)
+ self.assert_(TESTFN in sys.modules, "expected module in sys.modules")
+ self.assertEquals(mod.a, 1, "module has wrong attribute values")
+ self.assertEquals(mod.b, 2, "module has wrong attribute values")
+
+ # On WinXP, just replacing the .py file wasn't enough to
+ # convince reload() to reparse it. Maybe the timestamp didn't
+ # move enough. We force it to get reparsed by removing the
+ # compiled file too.
+ remove_files(TESTFN)
+
+ # Now damage the module.
+ f = open(source, "w")
+ print >> f, "a = 10"
+ print >> f, "b = 20//0"
+ f.close()
+
+ self.assertRaises(ZeroDivisionError, reload, mod)
+
+ # But we still expect the module to be in sys.modules.
+ mod = sys.modules.get(TESTFN)
+ self.failIf(mod is None, "expected module to still be in sys.modules")
+
+ # We should have replaced a w/ 10, but the old b value should
+ # stick.
+ self.assertEquals(mod.a, 10, "module has wrong attribute values")
+ self.assertEquals(mod.b, 2, "module has wrong attribute values")
+
+ finally:
+ sys.path.pop(0)
+ remove_files(TESTFN)
+ if TESTFN in sys.modules:
+ del sys.modules[TESTFN]
+
+ def test_import_name_binding(self):
+ # import x.y.z binds x in the current namespace
+ import test as x
+ import test.test_support
+ self.assert_(x is test, x.__name__)
+ self.assert_(hasattr(test.test_support, "__file__"))
+
+ # import x.y.z as w binds z as w
+ import test.test_support as y
+ self.assert_(y is test.test_support, y.__name__)
+
+ def test_import_initless_directory_warning(self):
+ import warnings
+ oldfilters = warnings.filters[:]
+ warnings.simplefilter('error', ImportWarning);
+ try:
+ # Just a random non-package directory we always expect to be
+ # somewhere in sys.path...
+ self.assertRaises(ImportWarning, __import__, "site-packages")
+ finally:
+ warnings.filters = oldfilters
+
+def test_main(verbose=None):
+ run_unittest(ImportTest)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
index e5946e9..071e521 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -180,7 +180,18 @@ class TestRetrievingSourceCode(GetSourceBase):
self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
def test_getmodule(self):
+ # Check actual module
+ self.assertEqual(inspect.getmodule(mod), mod)
+ # Check class (uses __module__ attribute)
self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
+ # Check a method (no __module__ attribute, falls back to filename)
+ self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
+ # Do it again (check the caching isn't broken)
+ self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
+ # Check a builtin
+ self.assertEqual(inspect.getmodule(str), sys.modules["__builtin__"])
+ # Check filename override
+ self.assertEqual(inspect.getmodule(None, modfile), mod)
def test_getsource(self):
self.assertSourceEqual(git.abuse, 29, 39)
diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py
index 8f8fc73..8e1118a 100644
--- a/Lib/test/test_itertools.py
+++ b/Lib/test/test_itertools.py
@@ -61,6 +61,10 @@ class TestBasicOps(unittest.TestCase):
self.assertEqual(repr(c), 'count(3)')
c.next()
self.assertEqual(repr(c), 'count(4)')
+ c = count(-9)
+ self.assertEqual(repr(c), 'count(-9)')
+ c.next()
+ self.assertEqual(c.next(), -8)
def test_cycle(self):
self.assertEqual(take(10, cycle('abc')), list('abcabcabca'))
@@ -375,6 +379,7 @@ class TestBasicOps(unittest.TestCase):
# test values of n
self.assertRaises(TypeError, tee, 'abc', 'invalid')
+ self.assertRaises(ValueError, tee, [], -1)
for n in xrange(5):
result = tee('abc', n)
self.assertEqual(type(result), tuple)
diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py
index 92fe7a1..e0c781f 100644
--- a/Lib/test/test_long.py
+++ b/Lib/test/test_long.py
@@ -247,17 +247,23 @@ class LongTest(unittest.TestCase):
"long(-sys.maxint-1) != -sys.maxint-1")
# long -> int should not fail for hugepos_aslong or hugeneg_aslong
+ x = int(hugepos_aslong)
try:
- self.assertEqual(int(hugepos_aslong), hugepos,
+ self.assertEqual(x, hugepos,
"converting sys.maxint to long and back to int fails")
except OverflowError:
self.fail("int(long(sys.maxint)) overflowed!")
+ if not isinstance(x, int):
+ raise TestFailed("int(long(sys.maxint)) should have returned int")
+ x = int(hugeneg_aslong)
try:
- self.assertEqual(int(hugeneg_aslong), hugeneg,
+ self.assertEqual(x, hugeneg,
"converting -sys.maxint-1 to long and back to int fails")
except OverflowError:
self.fail("int(long(-sys.maxint-1)) overflowed!")
-
+ if not isinstance(x, int):
+ raise TestFailed("int(long(-sys.maxint-1)) should have "
+ "returned int")
# but long -> int should overflow for hugepos+1 and hugeneg-1
x = hugepos_aslong + 1
try:
@@ -282,6 +288,17 @@ class LongTest(unittest.TestCase):
self.assert_(type(y) is long,
"overflowing int conversion must return long not long subtype")
+ # long -> Py_ssize_t conversion
+ class X(object):
+ def __getslice__(self, i, j):
+ return i, j
+
+ self.assertEqual(X()[-5L:7L], (-5, 7))
+ # use the clamping effect to test the smallest and largest longs
+ # that fit a Py_ssize_t
+ slicemin, slicemax = X()[-2L**100:2L**100]
+ self.assertEqual(X()[slicemin:slicemax], (slicemin, slicemax))
+
# ----------------------------------- tests of auto int->long conversion
def test_auto_overflow(self):
diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py
index 1837306..def58cc 100644
--- a/Lib/test/test_mailbox.py
+++ b/Lib/test/test_mailbox.py
@@ -666,6 +666,19 @@ class TestMaildir(TestMailbox):
self._box.lock()
self._box.unlock()
+ def test_folder (self):
+ # Test for bug #1569790: verify that folders returned by .get_folder()
+ # use the same factory function.
+ def dummy_factory (s):
+ return None
+ box = self._factory(self._path, factory=dummy_factory)
+ folder = box.add_folder('folder1')
+ self.assert_(folder._factory is dummy_factory)
+
+ folder1_alias = box.get_folder('folder1')
+ self.assert_(folder1_alias._factory is dummy_factory)
+
+
class _TestMboxMMDF(TestMailbox):
@@ -740,6 +753,22 @@ class _TestMboxMMDF(TestMailbox):
self._box.lock()
self._box.unlock()
+ def test_relock(self):
+ # Test case for bug #1575506: the mailbox class was locking the
+ # wrong file object in its flush() method.
+ msg = "Subject: sub\n\nbody\n"
+ key1 = self._box.add(msg)
+ self._box.flush()
+ self._box.close()
+
+ self._box = self._factory(self._path)
+ self._box.lock()
+ key2 = self._box.add(msg)
+ self._box.flush()
+ self.assert_(self._box._locked)
+ self._box.close()
+
+
class TestMbox(_TestMboxMMDF):
@@ -766,7 +795,11 @@ class TestMH(TestMailbox):
def test_get_folder(self):
# Open folders
- self._box.add_folder('foo.bar')
+ def dummy_factory (s):
+ return None
+ self._box = self._factory(self._path, dummy_factory)
+
+ new_folder = self._box.add_folder('foo.bar')
folder0 = self._box.get_folder('foo.bar')
folder0.add(self._template % 'bar')
self.assert_(os.path.isdir(os.path.join(self._path, 'foo.bar')))
@@ -774,6 +807,11 @@ class TestMH(TestMailbox):
self.assert_(folder1.get_string(folder1.keys()[0]) == \
self._template % 'bar')
+ # Test for bug #1569790: verify that folders returned by .get_folder()
+ # use the same factory function.
+ self.assert_(new_folder._factory is self._box._factory)
+ self.assert_(folder0._factory is self._box._factory)
+
def test_add_and_remove_folders(self):
# Delete folders
self._box.add_folder('one')
@@ -842,6 +880,21 @@ class TestMH(TestMailbox):
self.assert_(self._box.get_sequences() ==
{'foo':[1, 2, 3], 'unseen':[1], 'bar':[3], 'replied':[3]})
+ # Test case for packing while holding the mailbox locked.
+ key0 = self._box.add(msg1)
+ key1 = self._box.add(msg1)
+ key2 = self._box.add(msg1)
+ key3 = self._box.add(msg1)
+
+ self._box.remove(key0)
+ self._box.remove(key2)
+ self._box.lock()
+ self._box.pack()
+ self._box.unlock()
+ self.assert_(self._box.get_sequences() ==
+ {'foo':[1, 2, 3, 4, 5],
+ 'unseen':[1], 'bar':[3], 'replied':[3]})
+
def _get_lock_path(self):
return os.path.join(self._path, '.mh_sequences.lock')
diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py
index a092265..a45fc34 100644
--- a/Lib/test/test_math.py
+++ b/Lib/test/test_math.py
@@ -1,208 +1,241 @@
# Python test set -- math module
# XXXX Should not do tests around zero only
-from test.test_support import TestFailed, verbose
+from test.test_support import run_unittest, verbose
+import unittest
+import math
seps='1e-05'
eps = eval(seps)
-print 'math module, testing with eps', seps
-import math
-def testit(name, value, expected):
- if abs(value-expected) > eps:
- raise TestFailed, '%s returned %f, expected %f'%\
- (name, value, expected)
-
-print 'constants'
-testit('pi', math.pi, 3.1415926)
-testit('e', math.e, 2.7182818)
-
-print 'acos'
-testit('acos(-1)', math.acos(-1), math.pi)
-testit('acos(0)', math.acos(0), math.pi/2)
-testit('acos(1)', math.acos(1), 0)
-
-print 'asin'
-testit('asin(-1)', math.asin(-1), -math.pi/2)
-testit('asin(0)', math.asin(0), 0)
-testit('asin(1)', math.asin(1), math.pi/2)
-
-print 'atan'
-testit('atan(-1)', math.atan(-1), -math.pi/4)
-testit('atan(0)', math.atan(0), 0)
-testit('atan(1)', math.atan(1), math.pi/4)
-
-print 'atan2'
-testit('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
-testit('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
-testit('atan2(0, 1)', math.atan2(0, 1), 0)
-testit('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
-testit('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
-
-print 'ceil'
-testit('ceil(0.5)', math.ceil(0.5), 1)
-testit('ceil(1.0)', math.ceil(1.0), 1)
-testit('ceil(1.5)', math.ceil(1.5), 2)
-testit('ceil(-0.5)', math.ceil(-0.5), 0)
-testit('ceil(-1.0)', math.ceil(-1.0), -1)
-testit('ceil(-1.5)', math.ceil(-1.5), -1)
-
-print 'cos'
-testit('cos(-pi/2)', math.cos(-math.pi/2), 0)
-testit('cos(0)', math.cos(0), 1)
-testit('cos(pi/2)', math.cos(math.pi/2), 0)
-testit('cos(pi)', math.cos(math.pi), -1)
-
-print 'cosh'
-testit('cosh(0)', math.cosh(0), 1)
-testit('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
-
-print 'degrees'
-testit('degrees(pi)', math.degrees(math.pi), 180.0)
-testit('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
-testit('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
-
-print 'exp'
-testit('exp(-1)', math.exp(-1), 1/math.e)
-testit('exp(0)', math.exp(0), 1)
-testit('exp(1)', math.exp(1), math.e)
-
-print 'fabs'
-testit('fabs(-1)', math.fabs(-1), 1)
-testit('fabs(0)', math.fabs(0), 0)
-testit('fabs(1)', math.fabs(1), 1)
-
-print 'floor'
-testit('floor(0.5)', math.floor(0.5), 0)
-testit('floor(1.0)', math.floor(1.0), 1)
-testit('floor(1.5)', math.floor(1.5), 1)
-testit('floor(-0.5)', math.floor(-0.5), -1)
-testit('floor(-1.0)', math.floor(-1.0), -1)
-testit('floor(-1.5)', math.floor(-1.5), -2)
-
-print 'fmod'
-testit('fmod(10,1)', math.fmod(10,1), 0)
-testit('fmod(10,0.5)', math.fmod(10,0.5), 0)
-testit('fmod(10,1.5)', math.fmod(10,1.5), 1)
-testit('fmod(-10,1)', math.fmod(-10,1), 0)
-testit('fmod(-10,0.5)', math.fmod(-10,0.5), 0)
-testit('fmod(-10,1.5)', math.fmod(-10,1.5), -1)
-
-print 'frexp'
-def testfrexp(name, (mant, exp), (emant, eexp)):
- if abs(mant-emant) > eps or exp != eexp:
- raise TestFailed, '%s returned %r, expected %r'%\
- (name, (mant, exp), (emant,eexp))
-
-testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
-testfrexp('frexp(0)', math.frexp(0), (0, 0))
-testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
-testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
-
-print 'hypot'
-testit('hypot(0,0)', math.hypot(0,0), 0)
-testit('hypot(3,4)', math.hypot(3,4), 5)
-
-print 'ldexp'
-testit('ldexp(0,1)', math.ldexp(0,1), 0)
-testit('ldexp(1,1)', math.ldexp(1,1), 2)
-testit('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
-testit('ldexp(-1,1)', math.ldexp(-1,1), -2)
-
-print 'log'
-testit('log(1/e)', math.log(1/math.e), -1)
-testit('log(1)', math.log(1), 0)
-testit('log(e)', math.log(math.e), 1)
-testit('log(32,2)', math.log(32,2), 5)
-testit('log(10**40, 10)', math.log(10**40, 10), 40)
-testit('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
-
-print 'log10'
-testit('log10(0.1)', math.log10(0.1), -1)
-testit('log10(1)', math.log10(1), 0)
-testit('log10(10)', math.log10(10), 1)
-
-print 'modf'
-def testmodf(name, (v1, v2), (e1, e2)):
- if abs(v1-e1) > eps or abs(v2-e2):
- raise TestFailed, '%s returned %r, expected %r'%\
- (name, (v1,v2), (e1,e2))
-
-testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
-testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
-
-print 'pow'
-testit('pow(0,1)', math.pow(0,1), 0)
-testit('pow(1,0)', math.pow(1,0), 1)
-testit('pow(2,1)', math.pow(2,1), 2)
-testit('pow(2,-1)', math.pow(2,-1), 0.5)
-
-print 'radians'
-testit('radians(180)', math.radians(180), math.pi)
-testit('radians(90)', math.radians(90), math.pi/2)
-testit('radians(-45)', math.radians(-45), -math.pi/4)
-
-print 'sin'
-testit('sin(0)', math.sin(0), 0)
-testit('sin(pi/2)', math.sin(math.pi/2), 1)
-testit('sin(-pi/2)', math.sin(-math.pi/2), -1)
-
-print 'sinh'
-testit('sinh(0)', math.sinh(0), 0)
-testit('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
-testit('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
-
-print 'sqrt'
-testit('sqrt(0)', math.sqrt(0), 0)
-testit('sqrt(1)', math.sqrt(1), 1)
-testit('sqrt(4)', math.sqrt(4), 2)
-
-print 'tan'
-testit('tan(0)', math.tan(0), 0)
-testit('tan(pi/4)', math.tan(math.pi/4), 1)
-testit('tan(-pi/4)', math.tan(-math.pi/4), -1)
-
-print 'tanh'
-testit('tanh(0)', math.tanh(0), 0)
-testit('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
-
-# RED_FLAG 16-Oct-2000 Tim
-# While 2.0 is more consistent about exceptions than previous releases, it
-# still fails this part of the test on some platforms. For now, we only
-# *run* test_exceptions() in verbose mode, so that this isn't normally
-# tested.
-
-def test_exceptions():
- print 'exceptions'
- try:
- x = math.exp(-1000000000)
- except:
- # mathmodule.c is failing to weed out underflows from libm, or
- # we've got an fp format with huge dynamic range
- raise TestFailed("underflowing exp() should not have raised "
- "an exception")
- if x != 0:
- raise TestFailed("underflowing exp() should have returned 0")
-
- # If this fails, probably using a strict IEEE-754 conforming libm, and x
- # is +Inf afterwards. But Python wants overflows detected by default.
- try:
- x = math.exp(1000000000)
- except OverflowError:
- pass
- else:
- raise TestFailed("overflowing exp() didn't trigger OverflowError")
-
- # If this fails, it could be a puzzle. One odd possibility is that
- # mathmodule.c's macros are getting confused while comparing
- # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
- # as a result (and so raising OverflowError instead).
- try:
- x = math.sqrt(-1.0)
- except ValueError:
- pass
- else:
- raise TestFailed("sqrt(-1) didn't raise ValueError")
-
-if verbose:
- test_exceptions()
+class MathTests(unittest.TestCase):
+
+ def ftest(self, name, value, expected):
+ if abs(value-expected) > eps:
+ self.fail('%s returned %f, expected %f'%\
+ (name, value, expected))
+
+ def testConstants(self):
+ self.ftest('pi', math.pi, 3.1415926)
+ self.ftest('e', math.e, 2.7182818)
+
+ def testAcos(self):
+ self.assertRaises(TypeError, math.acos)
+ self.ftest('acos(-1)', math.acos(-1), math.pi)
+ self.ftest('acos(0)', math.acos(0), math.pi/2)
+ self.ftest('acos(1)', math.acos(1), 0)
+
+ def testAsin(self):
+ self.assertRaises(TypeError, math.asin)
+ self.ftest('asin(-1)', math.asin(-1), -math.pi/2)
+ self.ftest('asin(0)', math.asin(0), 0)
+ self.ftest('asin(1)', math.asin(1), math.pi/2)
+
+ def testAtan(self):
+ self.assertRaises(TypeError, math.atan)
+ self.ftest('atan(-1)', math.atan(-1), -math.pi/4)
+ self.ftest('atan(0)', math.atan(0), 0)
+ self.ftest('atan(1)', math.atan(1), math.pi/4)
+
+ def testAtan2(self):
+ self.assertRaises(TypeError, math.atan2)
+ self.ftest('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
+ self.ftest('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
+ self.ftest('atan2(0, 1)', math.atan2(0, 1), 0)
+ self.ftest('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
+ self.ftest('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
+
+ def testCeil(self):
+ self.assertRaises(TypeError, math.ceil)
+ self.ftest('ceil(0.5)', math.ceil(0.5), 1)
+ self.ftest('ceil(1.0)', math.ceil(1.0), 1)
+ self.ftest('ceil(1.5)', math.ceil(1.5), 2)
+ self.ftest('ceil(-0.5)', math.ceil(-0.5), 0)
+ self.ftest('ceil(-1.0)', math.ceil(-1.0), -1)
+ self.ftest('ceil(-1.5)', math.ceil(-1.5), -1)
+
+ def testCos(self):
+ self.assertRaises(TypeError, math.cos)
+ self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0)
+ self.ftest('cos(0)', math.cos(0), 1)
+ self.ftest('cos(pi/2)', math.cos(math.pi/2), 0)
+ self.ftest('cos(pi)', math.cos(math.pi), -1)
+
+ def testCosh(self):
+ self.assertRaises(TypeError, math.cosh)
+ self.ftest('cosh(0)', math.cosh(0), 1)
+ self.ftest('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
+
+ def testDegrees(self):
+ self.assertRaises(TypeError, math.degrees)
+ self.ftest('degrees(pi)', math.degrees(math.pi), 180.0)
+ self.ftest('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
+ self.ftest('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
+
+ def testExp(self):
+ self.assertRaises(TypeError, math.exp)
+ self.ftest('exp(-1)', math.exp(-1), 1/math.e)
+ self.ftest('exp(0)', math.exp(0), 1)
+ self.ftest('exp(1)', math.exp(1), math.e)
+
+ def testFabs(self):
+ self.assertRaises(TypeError, math.fabs)
+ self.ftest('fabs(-1)', math.fabs(-1), 1)
+ self.ftest('fabs(0)', math.fabs(0), 0)
+ self.ftest('fabs(1)', math.fabs(1), 1)
+
+ def testFloor(self):
+ self.assertRaises(TypeError, math.floor)
+ self.ftest('floor(0.5)', math.floor(0.5), 0)
+ self.ftest('floor(1.0)', math.floor(1.0), 1)
+ self.ftest('floor(1.5)', math.floor(1.5), 1)
+ self.ftest('floor(-0.5)', math.floor(-0.5), -1)
+ self.ftest('floor(-1.0)', math.floor(-1.0), -1)
+ self.ftest('floor(-1.5)', math.floor(-1.5), -2)
+
+ def testFmod(self):
+ self.assertRaises(TypeError, math.fmod)
+ self.ftest('fmod(10,1)', math.fmod(10,1), 0)
+ self.ftest('fmod(10,0.5)', math.fmod(10,0.5), 0)
+ self.ftest('fmod(10,1.5)', math.fmod(10,1.5), 1)
+ self.ftest('fmod(-10,1)', math.fmod(-10,1), 0)
+ self.ftest('fmod(-10,0.5)', math.fmod(-10,0.5), 0)
+ self.ftest('fmod(-10,1.5)', math.fmod(-10,1.5), -1)
+
+ def testFrexp(self):
+ self.assertRaises(TypeError, math.frexp)
+
+ def testfrexp(name, (mant, exp), (emant, eexp)):
+ if abs(mant-emant) > eps or exp != eexp:
+ self.fail('%s returned %r, expected %r'%\
+ (name, (mant, exp), (emant,eexp)))
+
+ testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
+ testfrexp('frexp(0)', math.frexp(0), (0, 0))
+ testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
+ testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
+
+ def testHypot(self):
+ self.assertRaises(TypeError, math.hypot)
+ self.ftest('hypot(0,0)', math.hypot(0,0), 0)
+ self.ftest('hypot(3,4)', math.hypot(3,4), 5)
+
+ def testLdexp(self):
+ self.assertRaises(TypeError, math.ldexp)
+ self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
+ self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
+ self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
+ self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
+
+ def testLog(self):
+ self.assertRaises(TypeError, math.log)
+ self.ftest('log(1/e)', math.log(1/math.e), -1)
+ self.ftest('log(1)', math.log(1), 0)
+ self.ftest('log(e)', math.log(math.e), 1)
+ self.ftest('log(32,2)', math.log(32,2), 5)
+ self.ftest('log(10**40, 10)', math.log(10**40, 10), 40)
+ self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
+
+ def testLog10(self):
+ self.assertRaises(TypeError, math.log10)
+ self.ftest('log10(0.1)', math.log10(0.1), -1)
+ self.ftest('log10(1)', math.log10(1), 0)
+ self.ftest('log10(10)', math.log10(10), 1)
+
+ def testModf(self):
+ self.assertRaises(TypeError, math.modf)
+
+ def testmodf(name, (v1, v2), (e1, e2)):
+ if abs(v1-e1) > eps or abs(v2-e2):
+ self.fail('%s returned %r, expected %r'%\
+ (name, (v1,v2), (e1,e2)))
+
+ testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
+ testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
+
+ def testPow(self):
+ self.assertRaises(TypeError, math.pow)
+ self.ftest('pow(0,1)', math.pow(0,1), 0)
+ self.ftest('pow(1,0)', math.pow(1,0), 1)
+ self.ftest('pow(2,1)', math.pow(2,1), 2)
+ self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
+
+ def testRadians(self):
+ self.assertRaises(TypeError, math.radians)
+ self.ftest('radians(180)', math.radians(180), math.pi)
+ self.ftest('radians(90)', math.radians(90), math.pi/2)
+ self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
+
+ def testSin(self):
+ self.assertRaises(TypeError, math.sin)
+ self.ftest('sin(0)', math.sin(0), 0)
+ self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
+ self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
+
+ def testSinh(self):
+ self.assertRaises(TypeError, math.sinh)
+ self.ftest('sinh(0)', math.sinh(0), 0)
+ self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
+ self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
+
+ def testSqrt(self):
+ self.assertRaises(TypeError, math.sqrt)
+ self.ftest('sqrt(0)', math.sqrt(0), 0)
+ self.ftest('sqrt(1)', math.sqrt(1), 1)
+ self.ftest('sqrt(4)', math.sqrt(4), 2)
+
+ def testTan(self):
+ self.assertRaises(TypeError, math.tan)
+ self.ftest('tan(0)', math.tan(0), 0)
+ self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
+ self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
+
+ def testTanh(self):
+ self.assertRaises(TypeError, math.tanh)
+ self.ftest('tanh(0)', math.tanh(0), 0)
+ self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
+
+ # RED_FLAG 16-Oct-2000 Tim
+ # While 2.0 is more consistent about exceptions than previous releases, it
+ # still fails this part of the test on some platforms. For now, we only
+ # *run* test_exceptions() in verbose mode, so that this isn't normally
+ # tested.
+
+ if verbose:
+ def test_exceptions(self):
+ try:
+ x = math.exp(-1000000000)
+ except:
+ # mathmodule.c is failing to weed out underflows from libm, or
+ # we've got an fp format with huge dynamic range
+ self.fail("underflowing exp() should not have raised "
+ "an exception")
+ if x != 0:
+ self.fail("underflowing exp() should have returned 0")
+
+ # If this fails, probably using a strict IEEE-754 conforming libm, and x
+ # is +Inf afterwards. But Python wants overflows detected by default.
+ try:
+ x = math.exp(1000000000)
+ except OverflowError:
+ pass
+ else:
+ self.fail("overflowing exp() didn't trigger OverflowError")
+
+ # If this fails, it could be a puzzle. One odd possibility is that
+ # mathmodule.c's macros are getting confused while comparing
+ # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
+ # as a result (and so raising OverflowError instead).
+ try:
+ x = math.sqrt(-1.0)
+ except ValueError:
+ pass
+ else:
+ self.fail("sqrt(-1) didn't raise ValueError")
+
+
+def test_main():
+ run_unittest(MathTests)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py
index d2a2477..0b53823 100644
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -1,190 +1,158 @@
-from test.test_support import verify, vereq, TESTFN
+from test.test_support import TESTFN, run_unittest
import mmap
+import unittest
import os, re
PAGESIZE = mmap.PAGESIZE
-def test_both():
- "Test mmap module on Unix systems and Windows"
+class MmapTests(unittest.TestCase):
- # Create a file to be mmap'ed.
- if os.path.exists(TESTFN):
- os.unlink(TESTFN)
- f = open(TESTFN, 'w+')
+ def setUp(self):
+ if os.path.exists(TESTFN):
+ os.unlink(TESTFN)
- try: # unlink TESTFN no matter what
- # Write 2 pages worth of data to the file
- f.write('\0'* PAGESIZE)
- f.write('foo')
- f.write('\0'* (PAGESIZE-3) )
- f.flush()
- m = mmap.mmap(f.fileno(), 2 * PAGESIZE)
- f.close()
+ def tearDown(self):
+ try:
+ os.unlink(TESTFN)
+ except OSError:
+ pass
- # Simple sanity checks
+ def test_basic(self):
+ # Test mmap module on Unix systems and Windows
- print type(m) # SF bug 128713: segfaulted on Linux
- print ' Position of foo:', m.find('foo') / float(PAGESIZE), 'pages'
- vereq(m.find('foo'), PAGESIZE)
+ # Create a file to be mmap'ed.
+ f = open(TESTFN, 'w+')
+ try:
+ # Write 2 pages worth of data to the file
+ f.write('\0'* PAGESIZE)
+ f.write('foo')
+ f.write('\0'* (PAGESIZE-3) )
+ f.flush()
+ m = mmap.mmap(f.fileno(), 2 * PAGESIZE)
+ f.close()
- print ' Length of file:', len(m) / float(PAGESIZE), 'pages'
- vereq(len(m), 2*PAGESIZE)
+ # Simple sanity checks
- print ' Contents of byte 0:', repr(m[0])
- vereq(m[0], '\0')
- print ' Contents of first 3 bytes:', repr(m[0:3])
- vereq(m[0:3], '\0\0\0')
+ tp = str(type(m)) # SF bug 128713: segfaulted on Linux
+ self.assertEqual(m.find('foo'), PAGESIZE)
- # Modify the file's content
- print "\n Modifying file's content..."
- m[0] = '3'
- m[PAGESIZE +3: PAGESIZE +3+3] = 'bar'
+ self.assertEqual(len(m), 2*PAGESIZE)
- # Check that the modification worked
- print ' Contents of byte 0:', repr(m[0])
- vereq(m[0], '3')
- print ' Contents of first 3 bytes:', repr(m[0:3])
- vereq(m[0:3], '3\0\0')
- print ' Contents of second page:', repr(m[PAGESIZE-1 : PAGESIZE + 7])
- vereq(m[PAGESIZE-1 : PAGESIZE + 7], '\0foobar\0')
+ self.assertEqual(m[0], '\0')
+ self.assertEqual(m[0:3], '\0\0\0')
- m.flush()
+ # Modify the file's content
+ m[0] = '3'
+ m[PAGESIZE +3: PAGESIZE +3+3] = 'bar'
- # Test doing a regular expression match in an mmap'ed file
- match = re.search('[A-Za-z]+', m)
- if match is None:
- print ' ERROR: regex match on mmap failed!'
- else:
- start, end = match.span(0)
- length = end - start
-
- print ' Regex match on mmap (page start, length of match):',
- print start / float(PAGESIZE), length
-
- vereq(start, PAGESIZE)
- vereq(end, PAGESIZE + 6)
-
- # test seeking around (try to overflow the seek implementation)
- m.seek(0,0)
- print ' Seek to zeroth byte'
- vereq(m.tell(), 0)
- m.seek(42,1)
- print ' Seek to 42nd byte'
- vereq(m.tell(), 42)
- m.seek(0,2)
- print ' Seek to last byte'
- vereq(m.tell(), len(m))
-
- print ' Try to seek to negative position...'
- try:
- m.seek(-1)
- except ValueError:
- pass
- else:
- verify(0, 'expected a ValueError but did not get it')
+ # Check that the modification worked
+ self.assertEqual(m[0], '3')
+ self.assertEqual(m[0:3], '3\0\0')
+ self.assertEqual(m[PAGESIZE-1 : PAGESIZE + 7], '\0foobar\0')
- print ' Try to seek beyond end of mmap...'
- try:
- m.seek(1,2)
- except ValueError:
- pass
- else:
- verify(0, 'expected a ValueError but did not get it')
+ m.flush()
- print ' Try to seek to negative position...'
- try:
- m.seek(-len(m)-1,2)
- except ValueError:
- pass
- else:
- verify(0, 'expected a ValueError but did not get it')
+ # Test doing a regular expression match in an mmap'ed file
+ match = re.search('[A-Za-z]+', m)
+ if match is None:
+ self.fail('regex match on mmap failed!')
+ else:
+ start, end = match.span(0)
+ length = end - start
- # Try resizing map
- print ' Attempting resize()'
- try:
- m.resize(512)
- except SystemError:
- # resize() not supported
- # No messages are printed, since the output of this test suite
- # would then be different across platforms.
- pass
- else:
- # resize() is supported
- verify(len(m) == 512,
- "len(m) is %d, but expecting 512" % (len(m),) )
- # Check that we can no longer seek beyond the new size.
+ self.assertEqual(start, PAGESIZE)
+ self.assertEqual(end, PAGESIZE + 6)
+
+ # test seeking around (try to overflow the seek implementation)
+ m.seek(0,0)
+ self.assertEqual(m.tell(), 0)
+ m.seek(42,1)
+ self.assertEqual(m.tell(), 42)
+ m.seek(0,2)
+ self.assertEqual(m.tell(), len(m))
+
+ # Try to seek to negative position...
+ self.assertRaises(ValueError, m.seek, -1)
+
+ # Try to seek beyond end of mmap...
+ self.assertRaises(ValueError, m.seek, 1, 2)
+
+ # Try to seek to negative position...
+ self.assertRaises(ValueError, m.seek, -len(m)-1, 2)
+
+ # Try resizing map
try:
- m.seek(513,0)
- except ValueError:
+ m.resize(512)
+ except SystemError:
+ # resize() not supported
+ # No messages are printed, since the output of this test suite
+ # would then be different across platforms.
pass
else:
- verify(0, 'Could seek beyond the new size')
+ # resize() is supported
+ self.assertEqual(len(m), 512)
+ # Check that we can no longer seek beyond the new size.
+ self.assertRaises(ValueError, m.seek, 513, 0)
+
+ # Check that the underlying file is truncated too
+ # (bug #728515)
+ f = open(TESTFN)
+ f.seek(0, 2)
+ self.assertEqual(f.tell(), 512)
+ f.close()
+ self.assertEqual(m.size(), 512)
- # Check that the underlying file is truncated too
- # (bug #728515)
- f = open(TESTFN)
- f.seek(0, 2)
- verify(f.tell() == 512, 'Underlying file not truncated')
- f.close()
- verify(m.size() == 512, 'New size not reflected in file')
-
- m.close()
+ m.close()
- finally:
- try:
- f.close()
- except OSError:
- pass
- try:
- os.unlink(TESTFN)
- except OSError:
- pass
+ finally:
+ try:
+ f.close()
+ except OSError:
+ pass
- # Test for "access" keyword parameter
- try:
+ def test_access_parameter(self):
+ # Test for "access" keyword parameter
mapsize = 10
- print " Creating", mapsize, "byte test data file."
open(TESTFN, "wb").write("a"*mapsize)
- print " Opening mmap with access=ACCESS_READ"
f = open(TESTFN, "rb")
m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_READ)
- verify(m[:] == 'a'*mapsize, "Readonly memory map data incorrect.")
+ self.assertEqual(m[:], 'a'*mapsize, "Readonly memory map data incorrect.")
- print " Ensuring that readonly mmap can't be slice assigned."
+ # Ensuring that readonly mmap can't be slice assigned
try:
m[:] = 'b'*mapsize
except TypeError:
pass
else:
- verify(0, "Able to write to readonly memory map")
+ self.fail("Able to write to readonly memory map")
- print " Ensuring that readonly mmap can't be item assigned."
+ # Ensuring that readonly mmap can't be item assigned
try:
m[0] = 'b'
except TypeError:
pass
else:
- verify(0, "Able to write to readonly memory map")
+ self.fail("Able to write to readonly memory map")
- print " Ensuring that readonly mmap can't be write() to."
+ # Ensuring that readonly mmap can't be write() to
try:
m.seek(0,0)
m.write('abc')
except TypeError:
pass
else:
- verify(0, "Able to write to readonly memory map")
+ self.fail("Able to write to readonly memory map")
- print " Ensuring that readonly mmap can't be write_byte() to."
+ # Ensuring that readonly mmap can't be write_byte() to
try:
m.seek(0,0)
m.write_byte('d')
except TypeError:
pass
else:
- verify(0, "Able to write to readonly memory map")
+ self.fail("Able to write to readonly memory map")
- print " Ensuring that readonly mmap can't be resized."
+ # Ensuring that readonly mmap can't be resized
try:
m.resize(2*mapsize)
except SystemError: # resize is not universally supported
@@ -192,12 +160,12 @@ def test_both():
except TypeError:
pass
else:
- verify(0, "Able to resize readonly memory map")
+ self.fail("Able to resize readonly memory map")
del m, f
- verify(open(TESTFN, "rb").read() == 'a'*mapsize,
+ self.assertEqual(open(TESTFN, "rb").read(), 'a'*mapsize,
"Readonly memory map data file was modified")
- print " Opening mmap with size too big"
+ # Opening mmap with size too big
import sys
f = open(TESTFN, "r+b")
try:
@@ -208,11 +176,11 @@ def test_both():
# later tests assume that the length hasn't changed. We need to
# repair that.
if sys.platform.startswith('win'):
- verify(0, "Opening mmap with size+1 should work on Windows.")
+ self.fail("Opening mmap with size+1 should work on Windows.")
else:
# we expect a ValueError on Unix, but not on Windows
if not sys.platform.startswith('win'):
- verify(0, "Opening mmap with size+1 should raise ValueError.")
+ self.fail("Opening mmap with size+1 should raise ValueError.")
m.close()
f.close()
if sys.platform.startswith('win'):
@@ -221,12 +189,12 @@ def test_both():
f.truncate(mapsize)
f.close()
- print " Opening mmap with access=ACCESS_WRITE"
+ # Opening mmap with access=ACCESS_WRITE
f = open(TESTFN, "r+b")
m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_WRITE)
- print " Modifying write-through memory map."
+ # Modifying write-through memory map
m[:] = 'c'*mapsize
- verify(m[:] == 'c'*mapsize,
+ self.assertEqual(m[:], 'c'*mapsize,
"Write-through memory map memory not updated properly.")
m.flush()
m.close()
@@ -234,66 +202,45 @@ def test_both():
f = open(TESTFN, 'rb')
stuff = f.read()
f.close()
- verify(stuff == 'c'*mapsize,
+ self.assertEqual(stuff, 'c'*mapsize,
"Write-through memory map data file not updated properly.")
- print " Opening mmap with access=ACCESS_COPY"
+ # Opening mmap with access=ACCESS_COPY
f = open(TESTFN, "r+b")
m = mmap.mmap(f.fileno(), mapsize, access=mmap.ACCESS_COPY)
- print " Modifying copy-on-write memory map."
+ # Modifying copy-on-write memory map
m[:] = 'd'*mapsize
- verify(m[:] == 'd' * mapsize,
+ self.assertEqual(m[:], 'd' * mapsize,
"Copy-on-write memory map data not written correctly.")
m.flush()
- verify(open(TESTFN, "rb").read() == 'c'*mapsize,
+ self.assertEqual(open(TESTFN, "rb").read(), 'c'*mapsize,
"Copy-on-write test data file should not be modified.")
- try:
- print " Ensuring copy-on-write maps cannot be resized."
- m.resize(2*mapsize)
- except TypeError:
- pass
- else:
- verify(0, "Copy-on-write mmap resize did not raise exception.")
+ # Ensuring copy-on-write maps cannot be resized
+ self.assertRaises(TypeError, m.resize, 2*mapsize)
del m, f
- try:
- print " Ensuring invalid access parameter raises exception."
- f = open(TESTFN, "r+b")
- m = mmap.mmap(f.fileno(), mapsize, access=4)
- except ValueError:
- pass
- else:
- verify(0, "Invalid access code should have raised exception.")
+
+ # Ensuring invalid access parameter raises exception
+ f = open(TESTFN, "r+b")
+ self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize, access=4)
+ f.close()
if os.name == "posix":
# Try incompatible flags, prot and access parameters.
f = open(TESTFN, "r+b")
- try:
- m = mmap.mmap(f.fileno(), mapsize, flags=mmap.MAP_PRIVATE,
+ self.assertRaises(ValueError, mmap.mmap, f.fileno(), mapsize,
+ flags=mmap.MAP_PRIVATE,
prot=mmap.PROT_READ, access=mmap.ACCESS_WRITE)
- except ValueError:
- pass
- else:
- verify(0, "Incompatible parameters should raise ValueError.")
f.close()
- finally:
- try:
- os.unlink(TESTFN)
- except OSError:
- pass
- print ' Try opening a bad file descriptor...'
- try:
- mmap.mmap(-2, 4096)
- except mmap.error:
- pass
- else:
- verify(0, 'expected a mmap.error but did not get it')
+ def test_bad_file_desc(self):
+ # Try opening a bad file descriptor...
+ self.assertRaises(mmap.error, mmap.mmap, -2, 4096)
- # Do a tougher .find() test. SF bug 515943 pointed out that, in 2.2,
- # searching for data with embedded \0 bytes didn't work.
- f = open(TESTFN, 'w+')
+ def test_tougher_find(self):
+ # Do a tougher .find() test. SF bug 515943 pointed out that, in 2.2,
+ # searching for data with embedded \0 bytes didn't work.
+ f = open(TESTFN, 'w+')
- try: # unlink TESTFN no matter what
data = 'aabaac\x00deef\x00\x00aa\x00'
n = len(data)
f.write(data)
@@ -304,17 +251,14 @@ def test_both():
for start in range(n+1):
for finish in range(start, n+1):
slice = data[start : finish]
- vereq(m.find(slice), data.find(slice))
- vereq(m.find(slice + 'x'), -1)
+ self.assertEqual(m.find(slice), data.find(slice))
+ self.assertEqual(m.find(slice + 'x'), -1)
m.close()
- finally:
- os.unlink(TESTFN)
+ def test_double_close(self):
+ # make sure a double close doesn't crash on Solaris (Bug# 665913)
+ f = open(TESTFN, 'w+')
- # make sure a double close doesn't crash on Solaris (Bug# 665913)
- f = open(TESTFN, 'w+')
-
- try: # unlink TESTFN no matter what
f.write(2**16 * 'a') # Arbitrary character
f.close()
@@ -324,72 +268,46 @@ def test_both():
mf.close()
f.close()
- finally:
- os.unlink(TESTFN)
-
- # test mapping of entire file by passing 0 for map length
- if hasattr(os, "stat"):
- print " Ensuring that passing 0 as map length sets map size to current file size."
- f = open(TESTFN, "w+")
+ def test_entire_file(self):
+ # test mapping of entire file by passing 0 for map length
+ if hasattr(os, "stat"):
+ f = open(TESTFN, "w+")
- try:
f.write(2**16 * 'm') # Arbitrary character
f.close()
f = open(TESTFN, "rb+")
mf = mmap.mmap(f.fileno(), 0)
- verify(len(mf) == 2**16, "Map size should equal file size.")
- vereq(mf.read(2**16), 2**16 * "m")
+ self.assertEqual(len(mf), 2**16, "Map size should equal file size.")
+ self.assertEqual(mf.read(2**16), 2**16 * "m")
mf.close()
f.close()
- finally:
- os.unlink(TESTFN)
-
- # test mapping of entire file by passing 0 for map length
- if hasattr(os, "stat"):
- print " Ensuring that passing 0 as map length sets map size to current file size."
- f = open(TESTFN, "w+")
- try:
- f.write(2**16 * 'm') # Arbitrary character
- f.close()
-
- f = open(TESTFN, "rb+")
- mf = mmap.mmap(f.fileno(), 0)
- verify(len(mf) == 2**16, "Map size should equal file size.")
- vereq(mf.read(2**16), 2**16 * "m")
- mf.close()
- f.close()
-
- finally:
- os.unlink(TESTFN)
-
- # make move works everywhere (64-bit format problem earlier)
- f = open(TESTFN, 'w+')
+ def test_move(self):
+ # make move works everywhere (64-bit format problem earlier)
+ f = open(TESTFN, 'w+')
- try: # unlink TESTFN no matter what
f.write("ABCDEabcde") # Arbitrary character
f.flush()
mf = mmap.mmap(f.fileno(), 10)
mf.move(5, 0, 5)
- verify(mf[:] == "ABCDEABCDE", "Map move should have duplicated front 5")
+ self.assertEqual(mf[:], "ABCDEABCDE", "Map move should have duplicated front 5")
mf.close()
f.close()
- finally:
- os.unlink(TESTFN)
+ def test_anonymous(self):
+ # anonymous mmap.mmap(-1, PAGE)
+ m = mmap.mmap(-1, PAGESIZE)
+ for x in xrange(PAGESIZE):
+ self.assertEqual(m[x], '\0', "anonymously mmap'ed contents should be zero")
-def test_anon():
- print " anonymous mmap.mmap(-1, PAGESIZE)..."
- m = mmap.mmap(-1, PAGESIZE)
- for x in xrange(PAGESIZE):
- verify(m[x] == '\0', "anonymously mmap'ed contents should be zero")
+ for x in xrange(PAGESIZE):
+ m[x] = ch = chr(x & 255)
+ self.assertEqual(m[x], ch)
- for x in xrange(PAGESIZE):
- m[x] = ch = chr(x & 255)
- vereq(m[x], ch)
+def test_main():
+ run_unittest(MmapTests)
-test_both()
-test_anon()
-print ' Test passed'
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_modulefinder.py b/Lib/test/test_modulefinder.py
index 0b8e451..7da241b 100644
--- a/Lib/test/test_modulefinder.py
+++ b/Lib/test/test_modulefinder.py
@@ -50,7 +50,7 @@ b/__init__.py
maybe_test_new = [
"a.module",
["a", "a.module", "sys",
- "b"],
+ "b", "__future__"],
["c"], ["b.something"],
"""\
a/__init__.py
@@ -58,6 +58,7 @@ a/module.py
from b import something
from c import something
b/__init__.py
+ from __future__ import absolute_import
from sys import *
"""]
@@ -86,12 +87,13 @@ absolute_import_test = [
"a.module",
["a", "a.module",
"b", "b.x", "b.y", "b.z",
- "sys", "exceptions"],
+ "__future__", "sys", "exceptions"],
["blahblah", "z"], [],
"""\
mymodule.py
a/__init__.py
a/module.py
+ from __future__ import absolute_import
import sys # sys
import blahblah # fails
import exceptions # exceptions
@@ -115,7 +117,8 @@ b/z.py
relative_import_test = [
"a.module",
- ["a", "a.module",
+ ["__future__",
+ "a", "a.module",
"a.b", "a.b.y", "a.b.z",
"a.b.c", "a.b.c.moduleC",
"a.b.c.d", "a.b.c.e",
@@ -127,6 +130,7 @@ mymodule.py
a/__init__.py
from .b import y, z # a.b.y, a.b.z
a/module.py
+ from __future__ import absolute_import # __future__
import exceptions # exceptions
a/exceptions.py
a/sys.py
@@ -253,6 +257,7 @@ class ModuleFinderTest(unittest.TestCase):
self._do_test(relative_import_test_2)
def test_main():
+ distutils.log.set_threshold(distutils.log.WARN)
test_support.run_unittest(ModuleFinderTest)
if __name__ == "__main__":
diff --git a/Lib/test/test_multibytecodec.py b/Lib/test/test_multibytecodec.py
index 95f4b38..fb7f82d 100644
--- a/Lib/test/test_multibytecodec.py
+++ b/Lib/test/test_multibytecodec.py
@@ -202,6 +202,22 @@ class Test_ISO2022(unittest.TestCase):
uni = u':hu4:unit\xe9 de famille'
self.assertEqual(iso2022jp2.decode('iso2022-jp-2'), uni)
+ def test_iso2022_jp_g0(self):
+ self.failIf('\x0e' in u'\N{SOFT HYPHEN}'.encode('iso-2022-jp-2'))
+ for encoding in ('iso-2022-jp-2004', 'iso-2022-jp-3'):
+ e = u'\u3406'.encode(encoding)
+ self.failIf(filter(lambda x: x >= '\x80', e))
+
+ def test_bug1572832(self):
+ if sys.maxunicode >= 0x10000:
+ myunichr = unichr
+ else:
+ myunichr = lambda x: unichr(0xD7C0+(x>>10)) + unichr(0xDC00+(x&0x3FF))
+
+ for x in xrange(0x10000, 0x110000):
+ # Any ISO 2022 codec will cause the segfault
+ myunichr(x).encode('iso_2022_jp', 'ignore')
+
def test_main():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(Test_MultibyteCodec))
diff --git a/Lib/test/test_mutants.py b/Lib/test/test_mutants.py
index 8afda75..6215226 100644
--- a/Lib/test/test_mutants.py
+++ b/Lib/test/test_mutants.py
@@ -92,8 +92,8 @@ class Horrid:
##self.hashcode = random.randrange(1000000000)
def __hash__(self):
- ##return self.hashcode
return 42
+ return self.hashcode
def __eq__(self, other):
maybe_mutate() # The point of the test.
diff --git a/Lib/test/test_new.py b/Lib/test/test_new.py
index 3c16bf5..e90fd66 100644
--- a/Lib/test/test_new.py
+++ b/Lib/test/test_new.py
@@ -47,6 +47,14 @@ except TypeError:
else:
raise TestFailed, "dangerous instance method creation allowed"
+# Verify that instancemethod() doesn't allow keyword args
+try:
+ new.instancemethod(break_yolks, c, kw=1)
+except TypeError:
+ pass
+else:
+ raise TestFailed, "instancemethod shouldn't accept keyword args"
+
# It's unclear what the semantics should be for a code object compiled at
# module scope, but bound and run in a function. In CPython, `c' is global
# (by accident?) while in Jython, `c' is local. The intent of the test
diff --git a/Lib/test/test_nis.py b/Lib/test/test_nis.py
index f5224fe..590868f 100644
--- a/Lib/test/test_nis.py
+++ b/Lib/test/test_nis.py
@@ -1,32 +1,41 @@
-from test.test_support import verbose, TestFailed, TestSkipped
+from test.test_support import verbose, run_unittest
+import unittest
import nis
-print 'nis.maps()'
-try:
- maps = nis.maps()
-except nis.error, msg:
- # NIS is probably not active, so this test isn't useful
- if verbose:
- raise TestFailed, msg
- # only do this if running under the regression suite
- raise TestSkipped, msg
+class NisTests(unittest.TestCase):
+ def test_maps(self):
+ try:
+ maps = nis.maps()
+ except nis.error, msg:
+ # NIS is probably not active, so this test isn't useful
+ if verbose:
+ self.fail("(failing because of verbose mode) %s" % msg)
+ return
+ try:
+ # On some systems, this map is only accessible to the
+ # super user
+ maps.remove("passwd.adjunct.byname")
+ except ValueError:
+ pass
-done = 0
-for nismap in maps:
- if verbose:
- print nismap
- mapping = nis.cat(nismap)
- for k, v in mapping.items():
- if verbose:
- print ' ', k, v
- if not k:
- continue
- if nis.match(k, nismap) != v:
- print "NIS match failed for key `%s' in map `%s'" % (k, nismap)
- else:
- # just test the one key, otherwise this test could take a
- # very long time
- done = 1
- break
- if done:
- break
+ done = 0
+ for nismap in maps:
+ mapping = nis.cat(nismap)
+ for k, v in mapping.items():
+ if not k:
+ continue
+ if nis.match(k, nismap) != v:
+ self.fail("NIS match failed for key `%s' in map `%s'" % (k, nismap))
+ else:
+ # just test the one key, otherwise this test could take a
+ # very long time
+ done = 1
+ break
+ if done:
+ break
+
+def test_main():
+ run_unittest(NisTests)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_opcodes.py b/Lib/test/test_opcodes.py
index 742267f..1a2f5d6 100644
--- a/Lib/test/test_opcodes.py
+++ b/Lib/test/test_opcodes.py
@@ -1,101 +1,110 @@
# Python test set -- part 2, opcodes
-from test.test_support import TestFailed
-
-
-print '2. Opcodes'
-print 'XXX Not yet fully implemented'
-
-print '2.1 try inside for loop'
-n = 0
-for i in range(10):
- n = n+i
- try: 1/0
- except NameError: pass
- except ZeroDivisionError: pass
- except TypeError: pass
- try: pass
- except: pass
- try: pass
- finally: pass
- n = n+i
-if n != 90:
- raise TestFailed, 'try inside for'
-
-
-print '2.2 raise class exceptions'
-
-class AClass(Exception): pass
-class BClass(AClass): pass
-class CClass(Exception): pass
-class DClass(AClass):
- def __init__(self, ignore):
- pass
-
-try: raise AClass()
-except: pass
-
-try: raise AClass()
-except AClass: pass
-
-try: raise BClass()
-except AClass: pass
-
-try: raise BClass()
-except CClass: raise TestFailed
-except: pass
-
-a = AClass()
-b = BClass()
-
-try: raise AClass, b
-except BClass, v:
- if v != b: raise TestFailed, "v!=b"
-else: raise TestFailed, "no exception"
-
-try: raise b
-except AClass, v:
- if v != b: raise TestFailed, "v!=b AClass"
-
-# not enough arguments
-##try: raise BClass, a
-##except TypeError: pass
-
-try: raise DClass, a
-except DClass, v:
- if not isinstance(v, DClass):
- raise TestFailed, "v not DClass"
-
-print '2.3 comparing function objects'
-
-f = eval('lambda: None')
-g = eval('lambda: None')
-if f == g: raise TestFailed, "functions should not be same"
-
-f = eval('lambda a: a')
-g = eval('lambda a: a')
-if f == g: raise TestFailed, "functions should not be same"
-
-f = eval('lambda a=1: a')
-g = eval('lambda a=1: a')
-if f == g: raise TestFailed, "functions should not be same"
-
-f = eval('lambda: 0')
-g = eval('lambda: 1')
-if f == g: raise TestFailed
-
-f = eval('lambda: None')
-g = eval('lambda a: None')
-if f == g: raise TestFailed
-
-f = eval('lambda a: None')
-g = eval('lambda b: None')
-if f == g: raise TestFailed
-
-f = eval('lambda a: None')
-g = eval('lambda a=None: None')
-if f == g: raise TestFailed
-
-f = eval('lambda a=0: None')
-g = eval('lambda a=1: None')
-if f == g: raise TestFailed
+from test.test_support import run_unittest
+import unittest
+
+class OpcodeTest(unittest.TestCase):
+
+ def test_try_inside_for_loop(self):
+ n = 0
+ for i in range(10):
+ n = n+i
+ try: 1/0
+ except NameError: pass
+ except ZeroDivisionError: pass
+ except TypeError: pass
+ try: pass
+ except: pass
+ try: pass
+ finally: pass
+ n = n+i
+ if n != 90:
+ self.fail('try inside for')
+
+ def test_raise_class_exceptions(self):
+
+ class AClass(Exception): pass
+ class BClass(AClass): pass
+ class CClass(Exception): pass
+ class DClass(AClass):
+ def __init__(self, ignore):
+ pass
+
+ try: raise AClass()
+ except: pass
+
+ try: raise AClass()
+ except AClass: pass
+
+ try: raise BClass()
+ except AClass: pass
+
+ try: raise BClass()
+ except CClass: self.fail()
+ except: pass
+
+ a = AClass()
+ b = BClass()
+
+ try: raise AClass, b
+ except BClass, v:
+ if v != b: self.fail("v!=b")
+ else: self.fail("no exception")
+
+ try: raise b
+ except AClass, v:
+ if v != b: self.fail("v!=b AClass")
+ else:
+ self.fail("no exception")
+
+ # not enough arguments
+ ##try: raise BClass, a
+ ##except TypeError: pass
+ ##else: self.fail("no exception")
+
+ try: raise DClass, a
+ except DClass, v:
+ self.assert_(isinstance(v, DClass))
+ else:
+ self.fail("no exception")
+
+ def test_compare_function_objects(self):
+
+ f = eval('lambda: None')
+ g = eval('lambda: None')
+ self.failIf(f == g)
+
+ f = eval('lambda a: a')
+ g = eval('lambda a: a')
+ self.failIf(f == g)
+
+ f = eval('lambda a=1: a')
+ g = eval('lambda a=1: a')
+ self.failIf(f == g)
+
+ f = eval('lambda: 0')
+ g = eval('lambda: 1')
+ self.failIf(f == g)
+
+ f = eval('lambda: None')
+ g = eval('lambda a: None')
+ self.failIf(f == g)
+
+ f = eval('lambda a: None')
+ g = eval('lambda b: None')
+ self.failIf(f == g)
+
+ f = eval('lambda a: None')
+ g = eval('lambda a=None: None')
+ self.failIf(f == g)
+
+ f = eval('lambda a=0: None')
+ g = eval('lambda a=1: None')
+ self.failIf(f == g)
+
+
+def test_main():
+ run_unittest(OpcodeTest)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_openpty.py b/Lib/test/test_openpty.py
index a8b8550..6471f58 100644
--- a/Lib/test/test_openpty.py
+++ b/Lib/test/test_openpty.py
@@ -1,19 +1,23 @@
# Test to see if openpty works. (But don't worry if it isn't available.)
-import os
-from test.test_support import verbose, TestFailed, TestSkipped
+import os, unittest
+from test.test_support import run_unittest, TestSkipped
-try:
- if verbose:
- print "Calling os.openpty()"
- master, slave = os.openpty()
- if verbose:
- print "(master, slave) = (%d, %d)"%(master, slave)
-except AttributeError:
+if not hasattr(os, "openpty"):
raise TestSkipped, "No openpty() available."
-if not os.isatty(slave):
- raise TestFailed, "Slave-end of pty is not a terminal."
-os.write(slave, 'Ping!')
-print os.read(master, 1024)
+class OpenptyTest(unittest.TestCase):
+ def test(self):
+ master, slave = os.openpty()
+ if not os.isatty(slave):
+ self.fail("Slave-end of pty is not a terminal.")
+
+ os.write(slave, 'Ping!')
+ self.assertEqual(os.read(master, 1024), 'Ping!')
+
+def test_main():
+ run_unittest(OpenptyTest)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index bf0e196..1c87d06 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -223,6 +223,23 @@ class StatAttributeTests(unittest.TestCase):
except TypeError:
pass
+ def test_utime_dir(self):
+ delta = 1000000
+ st = os.stat(test_support.TESTFN)
+ # round to int, because some systems may support sub-second
+ # time stamps in stat, but not in utime.
+ os.utime(test_support.TESTFN, (st.st_atime, int(st.st_mtime-delta)))
+ st2 = os.stat(test_support.TESTFN)
+ self.assertEquals(st2.st_mtime, int(st.st_mtime-delta))
+
+ # Restrict test to Win32, since there is no guarantee other
+ # systems support centiseconds
+ if sys.platform == 'win32':
+ def test_1565150(self):
+ t1 = 1159195039.25
+ os.utime(self.fname, (t1, t1))
+ self.assertEquals(os.stat(self.fname).st_mtime, t1)
+
from test import mapping_tests
class EnvironTests(mapping_tests.BasicTestMappingProtocol):
diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py
index 96384cd..0bf1218 100644
--- a/Lib/test/test_parser.py
+++ b/Lib/test/test_parser.py
@@ -183,6 +183,44 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase):
def test_assert(self):
self.check_suite("assert alo < ahi and blo < bhi\n")
+ def test_position(self):
+ # An absolutely minimal test of position information. Better
+ # tests would be a big project.
+ code = "def f(x):\n return x + 1\n"
+ st1 = parser.suite(code)
+ st2 = st1.totuple(line_info=1, col_info=1)
+
+ def walk(tree):
+ node_type = tree[0]
+ next = tree[1]
+ if isinstance(next, tuple):
+ for elt in tree[1:]:
+ for x in walk(elt):
+ yield x
+ else:
+ yield tree
+
+ terminals = list(walk(st2))
+ self.assertEqual([
+ (1, 'def', 1, 0),
+ (1, 'f', 1, 4),
+ (7, '(', 1, 5),
+ (1, 'x', 1, 6),
+ (8, ')', 1, 7),
+ (11, ':', 1, 8),
+ (4, '', 1, 9),
+ (5, '', 2, -1),
+ (1, 'return', 2, 4),
+ (1, 'x', 2, 11),
+ (14, '+', 2, 13),
+ (2, '1', 2, 15),
+ (4, '', 2, 16),
+ (6, '', 2, -1),
+ (4, '', 2, -1),
+ (0, '', 2, -1)],
+ terminals)
+
+
#
# Second, we take *invalid* trees and make sure we get ParserError
# rejections for them.
diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py
index be7d4e8..779a20a 100644
--- a/Lib/test/test_peepholer.py
+++ b/Lib/test/test_peepholer.py
@@ -160,6 +160,41 @@ class TestTranforms(unittest.TestCase):
self.assert_('(None)' not in asm)
self.assertEqual(asm.split().count('RETURN_VALUE'), 1)
+ def test_elim_jump_to_return(self):
+ # JUMP_FORWARD to RETURN --> RETURN
+ def f(cond, true_value, false_value):
+ return true_value if cond else false_value
+ asm = disassemble(f)
+ self.assert_('JUMP_FORWARD' not in asm)
+ self.assert_('JUMP_ABSOLUTE' not in asm)
+ self.assertEqual(asm.split().count('RETURN_VALUE'), 2)
+
+ def test_elim_jump_after_return1(self):
+ # Eliminate dead code: jumps immediately after returns can't be reached
+ def f(cond1, cond2):
+ if cond1: return 1
+ if cond2: return 2
+ while 1:
+ return 3
+ while 1:
+ if cond1: return 4
+ return 5
+ return 6
+ asm = disassemble(f)
+ self.assert_('JUMP_FORWARD' not in asm)
+ self.assert_('JUMP_ABSOLUTE' not in asm)
+ self.assertEqual(asm.split().count('RETURN_VALUE'), 6)
+
+ def test_elim_jump_after_return2(self):
+ # Eliminate dead code: jumps immediately after returns can't be reached
+ def f(cond1, cond2):
+ while 1:
+ if cond1: return 4
+ asm = disassemble(f)
+ self.assert_('JUMP_FORWARD' not in asm)
+ # There should be one jump for the while loop.
+ self.assertEqual(asm.split().count('JUMP_ABSOLUTE'), 1)
+ self.assertEqual(asm.split().count('RETURN_VALUE'), 2)
def test_main(verbose=None):
diff --git a/Lib/test/test_pep352.py b/Lib/test/test_pep352.py
index 73cffd2..75610b6 100644
--- a/Lib/test/test_pep352.py
+++ b/Lib/test/test_pep352.py
@@ -15,8 +15,7 @@ class ExceptionClassTests(unittest.TestCase):
self.failUnless(issubclass(Exception, object))
def verify_instance_interface(self, ins):
- for attr in ("args", "message", "__str__", "__unicode__", "__repr__",
- "__getitem__"):
+ for attr in ("args", "message", "__str__", "__repr__", "__getitem__"):
self.failUnless(hasattr(ins, attr), "%s missing %s attribute" %
(ins.__class__.__name__, attr))
diff --git a/Lib/test/test_poll.py b/Lib/test/test_poll.py
index 3a48bce..60cd3f4 100644
--- a/Lib/test/test_poll.py
+++ b/Lib/test/test_poll.py
@@ -1,7 +1,7 @@
# Test case for the os.poll() function
-import sys, os, select, random
-from test.test_support import verify, verbose, TestSkipped, TESTFN
+import sys, os, select, random, unittest
+from test.test_support import TestSkipped, TESTFN, run_unittest
try:
select.poll
@@ -16,177 +16,141 @@ def find_ready_matching(ready, flag):
match.append(fd)
return match
-def test_poll1():
- """Basic functional test of poll object
-
- Create a bunch of pipe and test that poll works with them.
- """
- print 'Running poll test 1'
- p = select.poll()
-
- NUM_PIPES = 12
- MSG = " This is a test."
- MSG_LEN = len(MSG)
- readers = []
- writers = []
- r2w = {}
- w2r = {}
-
- for i in range(NUM_PIPES):
- rd, wr = os.pipe()
- p.register(rd, select.POLLIN)
- p.register(wr, select.POLLOUT)
- readers.append(rd)
- writers.append(wr)
- r2w[rd] = wr
- w2r[wr] = rd
-
- while writers:
- ready = p.poll()
- ready_writers = find_ready_matching(ready, select.POLLOUT)
- if not ready_writers:
- raise RuntimeError, "no pipes ready for writing"
- wr = random.choice(ready_writers)
- os.write(wr, MSG)
-
- ready = p.poll()
- ready_readers = find_ready_matching(ready, select.POLLIN)
- if not ready_readers:
- raise RuntimeError, "no pipes ready for reading"
- rd = random.choice(ready_readers)
- buf = os.read(rd, MSG_LEN)
- verify(len(buf) == MSG_LEN)
- print buf
- os.close(r2w[rd]) ; os.close( rd )
- p.unregister( r2w[rd] )
- p.unregister( rd )
- writers.remove(r2w[rd])
-
- poll_unit_tests()
- print 'Poll test 1 complete'
-
-def poll_unit_tests():
- # returns NVAL for invalid file descriptor
- FD = 42
- try:
- os.close(FD)
- except OSError:
- pass
- p = select.poll()
- p.register(FD)
- r = p.poll()
- verify(r[0] == (FD, select.POLLNVAL))
-
- f = open(TESTFN, 'w')
- fd = f.fileno()
- p = select.poll()
- p.register(f)
- r = p.poll()
- verify(r[0][0] == fd)
- f.close()
- r = p.poll()
- verify(r[0] == (fd, select.POLLNVAL))
- os.unlink(TESTFN)
-
- # type error for invalid arguments
- p = select.poll()
- try:
- p.register(p)
- except TypeError:
- pass
- else:
- print "Bogus register call did not raise TypeError"
- try:
- p.unregister(p)
- except TypeError:
- pass
- else:
- print "Bogus unregister call did not raise TypeError"
-
- # can't unregister non-existent object
- p = select.poll()
- try:
- p.unregister(3)
- except KeyError:
- pass
- else:
- print "Bogus unregister call did not raise KeyError"
-
- # Test error cases
- pollster = select.poll()
- class Nope:
- pass
-
- class Almost:
- def fileno(self):
- return 'fileno'
-
- try:
- pollster.register( Nope(), 0 )
- except TypeError: pass
- else: print 'expected TypeError exception, not raised'
-
- try:
- pollster.register( Almost(), 0 )
- except TypeError: pass
- else: print 'expected TypeError exception, not raised'
-
-
-# Another test case for poll(). This is copied from the test case for
-# select(), modified to use poll() instead.
-
-def test_poll2():
- print 'Running poll test 2'
- cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done'
- p = os.popen(cmd, 'r')
- pollster = select.poll()
- pollster.register( p, select.POLLIN )
- for tout in (0, 1000, 2000, 4000, 8000, 16000) + (-1,)*10:
- if verbose:
- print 'timeout =', tout
- fdlist = pollster.poll(tout)
- if (fdlist == []):
- continue
- fd, flags = fdlist[0]
- if flags & select.POLLHUP:
- line = p.readline()
- if line != "":
- print 'error: pipe seems to be closed, but still returns data'
- continue
-
- elif flags & select.POLLIN:
- line = p.readline()
- if verbose:
- print repr(line)
- if not line:
- if verbose:
- print 'EOF'
- break
- continue
- else:
- print 'Unexpected return value from select.poll:', fdlist
- p.close()
- print 'Poll test 2 complete'
-
-def test_poll3():
- # test int overflow
- print 'Running poll test 3'
- pollster = select.poll()
- pollster.register(1)
-
- try:
- pollster.poll(1L << 64)
- except OverflowError:
- pass
- else:
- print 'Expected OverflowError with excessive timeout'
-
- x = 2 + 3
- if x != 5:
- print 'Overflow must have occurred'
- print 'Poll test 3 complete'
-
-
-test_poll1()
-test_poll2()
-test_poll3()
+class PollTests(unittest.TestCase):
+
+ def test_poll1(self):
+ # Basic functional test of poll object
+ # Create a bunch of pipe and test that poll works with them.
+
+ p = select.poll()
+
+ NUM_PIPES = 12
+ MSG = " This is a test."
+ MSG_LEN = len(MSG)
+ readers = []
+ writers = []
+ r2w = {}
+ w2r = {}
+
+ for i in range(NUM_PIPES):
+ rd, wr = os.pipe()
+ p.register(rd, select.POLLIN)
+ p.register(wr, select.POLLOUT)
+ readers.append(rd)
+ writers.append(wr)
+ r2w[rd] = wr
+ w2r[wr] = rd
+
+ bufs = []
+
+ while writers:
+ ready = p.poll()
+ ready_writers = find_ready_matching(ready, select.POLLOUT)
+ if not ready_writers:
+ raise RuntimeError, "no pipes ready for writing"
+ wr = random.choice(ready_writers)
+ os.write(wr, MSG)
+
+ ready = p.poll()
+ ready_readers = find_ready_matching(ready, select.POLLIN)
+ if not ready_readers:
+ raise RuntimeError, "no pipes ready for reading"
+ rd = random.choice(ready_readers)
+ buf = os.read(rd, MSG_LEN)
+ self.assertEqual(len(buf), MSG_LEN)
+ bufs.append(buf)
+ os.close(r2w[rd]) ; os.close( rd )
+ p.unregister( r2w[rd] )
+ p.unregister( rd )
+ writers.remove(r2w[rd])
+
+ self.assertEqual(bufs, [MSG] * NUM_PIPES)
+
+ def poll_unit_tests(self):
+ # returns NVAL for invalid file descriptor
+ FD = 42
+ try:
+ os.close(FD)
+ except OSError:
+ pass
+ p = select.poll()
+ p.register(FD)
+ r = p.poll()
+ self.assertEqual(r[0], (FD, select.POLLNVAL))
+
+ f = open(TESTFN, 'w')
+ fd = f.fileno()
+ p = select.poll()
+ p.register(f)
+ r = p.poll()
+ self.assertEqual(r[0][0], fd)
+ f.close()
+ r = p.poll()
+ self.assertEqual(r[0], (fd, select.POLLNVAL))
+ os.unlink(TESTFN)
+
+ # type error for invalid arguments
+ p = select.poll()
+ self.assertRaises(TypeError, p.register, p)
+ self.assertRaises(TypeError, p.unregister, p)
+
+ # can't unregister non-existent object
+ p = select.poll()
+ self.assertRaises(KeyError, p.unregister, 3)
+
+ # Test error cases
+ pollster = select.poll()
+ class Nope:
+ pass
+
+ class Almost:
+ def fileno(self):
+ return 'fileno'
+
+ self.assertRaises(TypeError, pollster.register, Nope(), 0)
+ self.assertRaises(TypeError, pollster.register, Almost(), 0)
+
+ # Another test case for poll(). This is copied from the test case for
+ # select(), modified to use poll() instead.
+
+ def test_poll2(self):
+ cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done'
+ p = os.popen(cmd, 'r')
+ pollster = select.poll()
+ pollster.register( p, select.POLLIN )
+ for tout in (0, 1000, 2000, 4000, 8000, 16000) + (-1,)*10:
+ fdlist = pollster.poll(tout)
+ if (fdlist == []):
+ continue
+ fd, flags = fdlist[0]
+ if flags & select.POLLHUP:
+ line = p.readline()
+ if line != "":
+ self.fail('error: pipe seems to be closed, but still returns data')
+ continue
+
+ elif flags & select.POLLIN:
+ line = p.readline()
+ if not line:
+ break
+ continue
+ else:
+ self.fail('Unexpected return value from select.poll: %s' % fdlist)
+ p.close()
+
+ def test_poll3(self):
+ # test int overflow
+ pollster = select.poll()
+ pollster.register(1)
+
+ self.assertRaises(OverflowError, pollster.poll, 1L << 64)
+
+ x = 2 + 3
+ if x != 5:
+ self.fail('Overflow must have occurred')
+
+def test_main():
+ run_unittest(PollTests)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py
index 01703b5..7c9d4aa 100644
--- a/Lib/test/test_pyclbr.py
+++ b/Lib/test/test_pyclbr.py
@@ -95,6 +95,9 @@ class PyclbrTest(TestCase):
py_item = getattr(module, name)
if isinstance(value, pyclbr.Function):
self.assert_(isinstance(py_item, (FunctionType, BuiltinFunctionType)))
+ if py_item.__module__ != moduleName:
+ continue # skip functions that came from somewhere else
+ self.assertEquals(py_item.__module__, value.module)
else:
self.failUnless(isinstance(py_item, (ClassType, type)))
if py_item.__module__ != moduleName:
diff --git a/Lib/test/test_scope.py b/Lib/test/test_scope.py
index e4e592a..777e85a 100644
--- a/Lib/test/test_scope.py
+++ b/Lib/test/test_scope.py
@@ -1,186 +1,190 @@
-from test.test_support import verify, TestFailed, check_syntax, vereq
+import unittest
+from test.test_support import check_syntax_error, run_unittest
import warnings
+warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<test string>")
warnings.filterwarnings("ignore", r"import \*", SyntaxWarning, "<string>")
-print "1. simple nesting"
+class ScopeTests(unittest.TestCase):
-def make_adder(x):
- def adder(y):
- return x + y
- return adder
+ def testSimpleNesting(self):
-inc = make_adder(1)
-plus10 = make_adder(10)
+ def make_adder(x):
+ def adder(y):
+ return x + y
+ return adder
-vereq(inc(1), 2)
-vereq(plus10(-2), 8)
+ inc = make_adder(1)
+ plus10 = make_adder(10)
-print "2. extra nesting"
+ self.assertEqual(inc(1), 2)
+ self.assertEqual(plus10(-2), 8)
-def make_adder2(x):
- def extra(): # check freevars passing through non-use scopes
- def adder(y):
- return x + y
- return adder
- return extra()
+ def testExtraNesting(self):
-inc = make_adder2(1)
-plus10 = make_adder2(10)
+ def make_adder2(x):
+ def extra(): # check freevars passing through non-use scopes
+ def adder(y):
+ return x + y
+ return adder
+ return extra()
-vereq(inc(1), 2)
-vereq(plus10(-2), 8)
+ inc = make_adder2(1)
+ plus10 = make_adder2(10)
-print "3. simple nesting + rebinding"
+ self.assertEqual(inc(1), 2)
+ self.assertEqual(plus10(-2), 8)
-def make_adder3(x):
- def adder(y):
- return x + y
- x = x + 1 # check tracking of assignment to x in defining scope
- return adder
+ def testSimpleAndRebinding(self):
-inc = make_adder3(0)
-plus10 = make_adder3(9)
+ def make_adder3(x):
+ def adder(y):
+ return x + y
+ x = x + 1 # check tracking of assignment to x in defining scope
+ return adder
-vereq(inc(1), 2)
-vereq(plus10(-2), 8)
+ inc = make_adder3(0)
+ plus10 = make_adder3(9)
-print "4. nesting with global but no free"
+ self.assertEqual(inc(1), 2)
+ self.assertEqual(plus10(-2), 8)
-def make_adder4(): # XXX add exta level of indirection
- def nest():
- def nest():
- def adder(y):
- return global_x + y # check that plain old globals work
- return adder
- return nest()
- return nest()
+ def testNestingGlobalNoFree(self):
-global_x = 1
-adder = make_adder4()
-vereq(adder(1), 2)
+ def make_adder4(): # XXX add exta level of indirection
+ def nest():
+ def nest():
+ def adder(y):
+ return global_x + y # check that plain old globals work
+ return adder
+ return nest()
+ return nest()
-global_x = 10
-vereq(adder(-2), 8)
+ global_x = 1
+ adder = make_adder4()
+ self.assertEqual(adder(1), 2)
-print "5. nesting through class"
+ global_x = 10
+ self.assertEqual(adder(-2), 8)
-def make_adder5(x):
- class Adder:
- def __call__(self, y):
- return x + y
- return Adder()
+ def testNestingThroughClass(self):
-inc = make_adder5(1)
-plus10 = make_adder5(10)
+ def make_adder5(x):
+ class Adder:
+ def __call__(self, y):
+ return x + y
+ return Adder()
-vereq(inc(1), 2)
-vereq(plus10(-2), 8)
+ inc = make_adder5(1)
+ plus10 = make_adder5(10)
-print "6. nesting plus free ref to global"
+ self.assertEqual(inc(1), 2)
+ self.assertEqual(plus10(-2), 8)
-def make_adder6(x):
- global global_nest_x
- def adder(y):
- return global_nest_x + y
- global_nest_x = x
- return adder
+ def testNestingPlusFreeRefToGlobal(self):
-inc = make_adder6(1)
-plus10 = make_adder6(10)
+ def make_adder6(x):
+ global global_nest_x
+ def adder(y):
+ return global_nest_x + y
+ global_nest_x = x
+ return adder
-vereq(inc(1), 11) # there's only one global
-vereq(plus10(-2), 8)
+ inc = make_adder6(1)
+ plus10 = make_adder6(10)
-print "7. nearest enclosing scope"
+ self.assertEqual(inc(1), 11) # there's only one global
+ self.assertEqual(plus10(-2), 8)
-def f(x):
- def g(y):
- x = 42 # check that this masks binding in f()
- def h(z):
- return x + z
- return h
- return g(2)
-
-test_func = f(10)
-vereq(test_func(5), 47)
-
-print "8. mixed freevars and cellvars"
-
-def identity(x):
- return x
-
-def f(x, y, z):
- def g(a, b, c):
- a = a + x # 3
- def h():
- # z * (4 + 9)
- # 3 * 13
- return identity(z * (b + y))
- y = c + z # 9
- return h
- return g
-
-g = f(1, 2, 3)
-h = g(2, 4, 6)
-vereq(h(), 39)
-
-print "9. free variable in method"
-
-def test():
- method_and_var = "var"
- class Test:
- def method_and_var(self):
- return "method"
- def test(self):
- return method_and_var
- def actual_global(self):
- return str("global")
- def str(self):
- return str(self)
- return Test()
-
-t = test()
-vereq(t.test(), "var")
-vereq(t.method_and_var(), "method")
-vereq(t.actual_global(), "global")
-
-method_and_var = "var"
-class Test:
- # this class is not nested, so the rules are different
- def method_and_var(self):
- return "method"
- def test(self):
- return method_and_var
- def actual_global(self):
- return str("global")
- def str(self):
- return str(self)
-
-t = Test()
-vereq(t.test(), "var")
-vereq(t.method_and_var(), "method")
-vereq(t.actual_global(), "global")
-
-print "10. recursion"
+ def testNearestEnclosingScope(self):
-def f(x):
- def fact(n):
- if n == 0:
- return 1
- else:
- return n * fact(n - 1)
- if x >= 0:
- return fact(x)
- else:
- raise ValueError, "x must be >= 0"
+ def f(x):
+ def g(y):
+ x = 42 # check that this masks binding in f()
+ def h(z):
+ return x + z
+ return h
+ return g(2)
-vereq(f(6), 720)
+ test_func = f(10)
+ self.assertEqual(test_func(5), 47)
+ def testMixedFreevarsAndCellvars(self):
-print "11. unoptimized namespaces"
+ def identity(x):
+ return x
-check_syntax("""\
+ def f(x, y, z):
+ def g(a, b, c):
+ a = a + x # 3
+ def h():
+ # z * (4 + 9)
+ # 3 * 13
+ return identity(z * (b + y))
+ y = c + z # 9
+ return h
+ return g
+
+ g = f(1, 2, 3)
+ h = g(2, 4, 6)
+ self.assertEqual(h(), 39)
+
+ def testFreeVarInMethod(self):
+
+ def test():
+ method_and_var = "var"
+ class Test:
+ def method_and_var(self):
+ return "method"
+ def test(self):
+ return method_and_var
+ def actual_global(self):
+ return str("global")
+ def str(self):
+ return str(self)
+ return Test()
+
+ t = test()
+ self.assertEqual(t.test(), "var")
+ self.assertEqual(t.method_and_var(), "method")
+ self.assertEqual(t.actual_global(), "global")
+
+ method_and_var = "var"
+ class Test:
+ # this class is not nested, so the rules are different
+ def method_and_var(self):
+ return "method"
+ def test(self):
+ return method_and_var
+ def actual_global(self):
+ return str("global")
+ def str(self):
+ return str(self)
+
+ t = Test()
+ self.assertEqual(t.test(), "var")
+ self.assertEqual(t.method_and_var(), "method")
+ self.assertEqual(t.actual_global(), "global")
+
+ def testRecursion(self):
+
+ def f(x):
+ def fact(n):
+ if n == 0:
+ return 1
+ else:
+ return n * fact(n - 1)
+ if x >= 0:
+ return fact(x)
+ else:
+ raise ValueError, "x must be >= 0"
+
+ self.assertEqual(f(6), 720)
+
+
+ def testUnoptimizedNamespaces(self):
+
+ check_syntax_error(self, """\
def unoptimized_clash1(strip):
def f(s):
from string import *
@@ -188,7 +192,7 @@ def unoptimized_clash1(strip):
return f
""")
-check_syntax("""\
+ check_syntax_error(self, """\
def unoptimized_clash2():
from string import *
def f(s):
@@ -196,7 +200,7 @@ def unoptimized_clash2():
return f
""")
-check_syntax("""\
+ check_syntax_error(self, """\
def unoptimized_clash2():
from string import *
def g():
@@ -205,23 +209,23 @@ def unoptimized_clash2():
return f
""")
-check_syntax("""\
+ check_syntax_error(self, """\
def f(x):
def g():
return x
del x # can't del name
""")
-check_syntax("""\
+ check_syntax_error(self, """\
def f():
def g():
- from string import *
- return strip # global or local?
+ from string import *
+ return strip # global or local?
""")
-# and verify a few cases that should work
+ # and verify a few cases that should work
-exec("""
+ exec("""
def noproblem1():
from string import *
f = lambda x:x
@@ -238,59 +242,60 @@ def noproblem3():
y = x
""")
-print "12. lambdas"
-
-f1 = lambda x: lambda y: x + y
-inc = f1(1)
-plus10 = f1(10)
-vereq(inc(1), 2)
-vereq(plus10(5), 15)
-
-f2 = lambda x: (lambda : lambda y: x + y)()
-inc = f2(1)
-plus10 = f2(10)
-vereq(inc(1), 2)
-vereq(plus10(5), 15)
-
-f3 = lambda x: lambda y: global_x + y
-global_x = 1
-inc = f3(None)
-vereq(inc(2), 3)
-
-f8 = lambda x, y, z: lambda a, b, c: lambda : z * (b + y)
-g = f8(1, 2, 3)
-h = g(2, 4, 6)
-vereq(h(), 18)
-
-print "13. UnboundLocal"
-
-def errorInOuter():
- print y
- def inner():
- return y
- y = 1
-
-def errorInInner():
- def inner():
- return y
- inner()
- y = 1
-
-try:
- errorInOuter()
-except UnboundLocalError:
- pass
-else:
- raise TestFailed
+ def testLambdas(self):
+
+ f1 = lambda x: lambda y: x + y
+ inc = f1(1)
+ plus10 = f1(10)
+ self.assertEqual(inc(1), 2)
+ self.assertEqual(plus10(5), 15)
+
+ f2 = lambda x: (lambda : lambda y: x + y)()
+ inc = f2(1)
+ plus10 = f2(10)
+ self.assertEqual(inc(1), 2)
+ self.assertEqual(plus10(5), 15)
+
+ f3 = lambda x: lambda y: global_x + y
+ global_x = 1
+ inc = f3(None)
+ self.assertEqual(inc(2), 3)
+
+ f8 = lambda x, y, z: lambda a, b, c: lambda : z * (b + y)
+ g = f8(1, 2, 3)
+ h = g(2, 4, 6)
+ self.assertEqual(h(), 18)
+
+ def testUnboundLocal(self):
+
+ def errorInOuter():
+ print y
+ def inner():
+ return y
+ y = 1
+
+ def errorInInner():
+ def inner():
+ return y
+ inner()
+ y = 1
+
+ try:
+ errorInOuter()
+ except UnboundLocalError:
+ pass
+ else:
+ self.fail()
-try:
- errorInInner()
-except NameError:
- pass
-else:
- raise TestFailed
+ try:
+ errorInInner()
+ except NameError:
+ pass
+ else:
+ self.fail()
-# test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation
+ # test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation
+ exec("""
global_x = 1
def f():
global_x += 1
@@ -299,34 +304,36 @@ try:
except UnboundLocalError:
pass
else:
- raise TestFailed, 'scope of global_x not correctly determined'
+ fail('scope of global_x not correctly determined')
+""", {'fail': self.fail})
-print "14. complex definitions"
+ def testComplexDefinitions(self):
-def makeReturner(*lst):
- def returner():
- return lst
- return returner
+ def makeReturner(*lst):
+ def returner():
+ return lst
+ return returner
-vereq(makeReturner(1,2,3)(), (1,2,3))
+ self.assertEqual(makeReturner(1,2,3)(), (1,2,3))
-def makeReturner2(**kwargs):
- def returner():
- return kwargs
- return returner
+ def makeReturner2(**kwargs):
+ def returner():
+ return kwargs
+ return returner
-vereq(makeReturner2(a=11)()['a'], 11)
+ self.assertEqual(makeReturner2(a=11)()['a'], 11)
-def makeAddPair((a, b)):
- def addPair((c, d)):
- return (a + c, b + d)
- return addPair
+ def makeAddPair((a, b)):
+ def addPair((c, d)):
+ return (a + c, b + d)
+ return addPair
-vereq(makeAddPair((1, 2))((100, 200)), (101,202))
+ self.assertEqual(makeAddPair((1, 2))((100, 200)), (101,202))
-print "15. scope of global statements"
+ def testScopeOfGlobalStmt(self):
# Examples posted by Samuele Pedroni to python-dev on 3/1/2001
+ exec("""\
# I
x = 7
def f():
@@ -339,8 +346,8 @@ def f():
return h()
return i()
return g()
-vereq(f(), 7)
-vereq(x, 7)
+self.assertEqual(f(), 7)
+self.assertEqual(x, 7)
# II
x = 7
@@ -354,8 +361,8 @@ def f():
return h()
return i()
return g()
-vereq(f(), 2)
-vereq(x, 7)
+self.assertEqual(f(), 2)
+self.assertEqual(x, 7)
# III
x = 7
@@ -370,8 +377,8 @@ def f():
return h()
return i()
return g()
-vereq(f(), 2)
-vereq(x, 2)
+self.assertEqual(f(), 2)
+self.assertEqual(x, 2)
# IV
x = 7
@@ -386,8 +393,8 @@ def f():
return h()
return i()
return g()
-vereq(f(), 2)
-vereq(x, 2)
+self.assertEqual(f(), 2)
+self.assertEqual(x, 2)
# XXX what about global statements in class blocks?
# do they affect methods?
@@ -402,34 +409,36 @@ class Global:
return x
g = Global()
-vereq(g.get(), 13)
+self.assertEqual(g.get(), 13)
g.set(15)
-vereq(g.get(), 13)
+self.assertEqual(g.get(), 13)
+""")
-print "16. check leaks"
+ def testLeaks(self):
-class Foo:
- count = 0
+ class Foo:
+ count = 0
- def __init__(self):
- Foo.count += 1
+ def __init__(self):
+ Foo.count += 1
- def __del__(self):
- Foo.count -= 1
+ def __del__(self):
+ Foo.count -= 1
-def f1():
- x = Foo()
- def f2():
- return x
- f2()
+ def f1():
+ x = Foo()
+ def f2():
+ return x
+ f2()
-for i in range(100):
- f1()
+ for i in range(100):
+ f1()
-vereq(Foo.count, 0)
+ self.assertEqual(Foo.count, 0)
-print "17. class and global"
+ def testClassAndGlobal(self):
+ exec("""\
def test(x):
class Foo:
global x
@@ -438,9 +447,9 @@ def test(x):
return Foo()
x = 0
-vereq(test(6)(2), 8)
+self.assertEqual(test(6)(2), 8)
x = -1
-vereq(test(3)(2), 5)
+self.assertEqual(test(3)(2), 5)
looked_up_by_load_name = False
class X:
@@ -449,104 +458,106 @@ class X:
locals()['looked_up_by_load_name'] = True
passed = looked_up_by_load_name
-verify(X.passed)
+self.assert_(X.passed)
+""")
-print "18. verify that locals() works"
+ def testLocalsFunction(self):
-def f(x):
- def g(y):
- def h(z):
- return y + z
- w = x + y
- y += 3
- return locals()
- return g
+ def f(x):
+ def g(y):
+ def h(z):
+ return y + z
+ w = x + y
+ y += 3
+ return locals()
+ return g
-d = f(2)(4)
-verify('h' in d)
-del d['h']
-vereq(d, {'x': 2, 'y': 7, 'w': 6})
+ d = f(2)(4)
+ self.assert_('h' in d)
+ del d['h']
+ self.assertEqual(d, {'x': 2, 'y': 7, 'w': 6})
-print "19. var is bound and free in class"
+ def testBoundAndFree(self):
+ # var is bound and free in class
-def f(x):
- class C:
- def m(self):
- return x
- a = x
- return C
+ def f(x):
+ class C:
+ def m(self):
+ return x
+ a = x
+ return C
-inst = f(3)()
-vereq(inst.a, inst.m())
+ inst = f(3)()
+ self.assertEqual(inst.a, inst.m())
-print "20. interaction with trace function"
+ def testInteractionWithTraceFunc(self):
-import sys
-def tracer(a,b,c):
- return tracer
+ import sys
+ def tracer(a,b,c):
+ return tracer
-def adaptgetter(name, klass, getter):
- kind, des = getter
- if kind == 1: # AV happens when stepping from this line to next
- if des == "":
- des = "_%s__%s" % (klass.__name__, name)
- return lambda obj: getattr(obj, des)
+ def adaptgetter(name, klass, getter):
+ kind, des = getter
+ if kind == 1: # AV happens when stepping from this line to next
+ if des == "":
+ des = "_%s__%s" % (klass.__name__, name)
+ return lambda obj: getattr(obj, des)
-class TestClass:
- pass
+ class TestClass:
+ pass
-sys.settrace(tracer)
-adaptgetter("foo", TestClass, (1, ""))
-sys.settrace(None)
+ sys.settrace(tracer)
+ adaptgetter("foo", TestClass, (1, ""))
+ sys.settrace(None)
-try: sys.settrace()
-except TypeError: pass
-else: raise TestFailed, 'sys.settrace() did not raise TypeError'
+ self.assertRaises(TypeError, sys.settrace)
-print "20. eval and exec with free variables"
+ def testEvalExecFreeVars(self):
-def f(x):
- return lambda: x + 1
+ def f(x):
+ return lambda: x + 1
-g = f(3)
-try:
- eval(g.func_code)
-except TypeError:
- pass
-else:
- print "eval() should have failed, because code contained free vars"
+ g = f(3)
+ self.assertRaises(TypeError, eval, g.func_code)
-try:
- exec(g.func_code)
-except TypeError:
- pass
-else:
- print "exec should have failed, because code contained free vars"
+ try:
+ exec(g.func_code, {})
+ except TypeError:
+ pass
+ else:
+ self.fail("exec should have failed, because code contained free vars")
-print "21. list comprehension with local variables"
+ def testListCompLocalVars(self):
-try:
- print bad
-except NameError:
- pass
-else:
- print "bad should not be defined"
+ try:
+ print bad
+ except NameError:
+ pass
+ else:
+ print "bad should not be defined"
-def x():
- [bad for s in 'a b' for bad in s.split()]
+ def x():
+ [bad for s in 'a b' for bad in s.split()]
-x()
-try:
- print bad
-except NameError:
- pass
+ x()
+ try:
+ print bad
+ except NameError:
+ pass
-print "22. eval with free variables"
+ def testEvalFreeVars(self):
-def f(x):
- def g():
- x
- eval("x + 1")
- return g
+ def f(x):
+ def g():
+ x
+ eval("x + 1")
+ return g
+
+ f(4)()
+
+
+def test_main():
+ run_unittest(ScopeTests)
-f(4)()
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py
index 03621a6..a4830d4 100644
--- a/Lib/test/test_set.py
+++ b/Lib/test/test_set.py
@@ -298,6 +298,17 @@ class TestSet(TestJointOps):
self.assert_(self.thetype(self.word) not in s)
self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
+ def test_remove_keyerror_unpacking(self):
+ # bug: www.python.org/sf/1576657
+ for v1 in ['Q', (1,)]:
+ try:
+ self.s.remove(v1)
+ except KeyError, e:
+ v2 = e.args[0]
+ self.assertEqual(v1, v2)
+ else:
+ self.fail()
+
def test_discard(self):
self.s.discard('a')
self.assert_('a' not in self.s)
diff --git a/Lib/test/test_sgmllib.py b/Lib/test/test_sgmllib.py
index 28a21a4..b698636 100644
--- a/Lib/test/test_sgmllib.py
+++ b/Lib/test/test_sgmllib.py
@@ -286,21 +286,6 @@ DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'
('codepoint', 'convert', 42),
])
- def test_attr_values_quoted_markup(self):
- """Multi-line and markup in attribute values"""
- self.check_events("""<a title='foo\n<br>bar'>text</a>""",
- [("starttag", "a", [("title", "foo\n<br>bar")]),
- ("data", "text"),
- ("endtag", "a")])
- self.check_events("""<a title='less < than'>text</a>""",
- [("starttag", "a", [("title", "less < than")]),
- ("data", "text"),
- ("endtag", "a")])
- self.check_events("""<a title='greater > than'>text</a>""",
- [("starttag", "a", [("title", "greater > than")]),
- ("data", "text"),
- ("endtag", "a")])
-
def test_attr_funky_names(self):
self.check_events("""<a a.b='v' c:d=v e-f=v>""", [
("starttag", "a", [("a.b", "v"), ("c:d", "v"), ("e-f", "v")]),
@@ -376,6 +361,19 @@ DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'
('decl', 'DOCTYPE doc [<!ATTLIST doc attr (a | b) >]'),
])
+ def test_read_chunks(self):
+ # SF bug #1541697, this caused sgml parser to hang
+ # Just verify this code doesn't cause a hang.
+ CHUNK = 1024 # increasing this to 8212 makes the problem go away
+
+ f = open(test_support.findfile('sgml_input.html'))
+ fp = sgmllib.SGMLParser()
+ while 1:
+ data = f.read(CHUNK)
+ fp.feed(data)
+ if len(data) != CHUNK:
+ break
+
# XXX These tests have been disabled by prefixing their names with
# an underscore. The first two exercise outstanding bugs in the
# sgmllib module, and the third exhibits questionable behavior
diff --git a/Lib/test/test_sha.py b/Lib/test/test_sha.py
index c438cc6..ea224e4 100644
--- a/Lib/test/test_sha.py
+++ b/Lib/test/test_sha.py
@@ -11,9 +11,23 @@ from test import test_support
class SHATestCase(unittest.TestCase):
def check(self, data, digest):
- computed = sha.new(data).hexdigest()
+ # Check digest matches the expected value
+ obj = sha.new(data)
+ computed = obj.hexdigest()
self.assert_(computed == digest)
+ # Verify that the value doesn't change between two consecutive
+ # digest operations.
+ computed_again = obj.hexdigest()
+ self.assert_(computed == computed_again)
+
+ # Check hexdigest() output matches digest()'s output
+ digest = obj.digest()
+ hexd = ""
+ for c in digest:
+ hexd += '%02x' % ord(c)
+ self.assert_(computed == hexd)
+
def test_case_1(self):
self.check("abc",
"a9993e364706816aba3e25717850c26c9cd0d89d")
@@ -26,6 +40,9 @@ class SHATestCase(unittest.TestCase):
self.check("a" * 1000000,
"34aa973cd4c4daa4f61eeb2bdbad27316534016f")
+ def test_case_4(self):
+ self.check(chr(0xAA) * 80,
+ '4ca0ef38f1794b28a8f8ee110ee79d48ce13be25')
def test_main():
test_support.run_unittest(SHATestCase)
diff --git a/Lib/test/test_structmembers.py b/Lib/test/test_structmembers.py
new file mode 100644
index 0000000..93dd2ac
--- /dev/null
+++ b/Lib/test/test_structmembers.py
@@ -0,0 +1,80 @@
+from _testcapi import test_structmembersType, \
+ CHAR_MAX, CHAR_MIN, UCHAR_MAX, \
+ SHRT_MAX, SHRT_MIN, USHRT_MAX, \
+ INT_MAX, INT_MIN, UINT_MAX, \
+ LONG_MAX, LONG_MIN, ULONG_MAX
+
+import warnings, exceptions, unittest, test.test_warnings
+from test import test_support
+
+ts=test_structmembersType(1,2,3,4,5,6,7,8,9.99999,10.1010101010)
+
+class ReadWriteTests(unittest.TestCase):
+ def test_types(self):
+ ts.T_BYTE=CHAR_MAX
+ self.assertEquals(ts.T_BYTE, CHAR_MAX)
+ ts.T_BYTE=CHAR_MIN
+ self.assertEquals(ts.T_BYTE, CHAR_MIN)
+ ts.T_UBYTE=UCHAR_MAX
+ self.assertEquals(ts.T_UBYTE, UCHAR_MAX)
+
+ ts.T_SHORT=SHRT_MAX
+ self.assertEquals(ts.T_SHORT, SHRT_MAX)
+ ts.T_SHORT=SHRT_MIN
+ self.assertEquals(ts.T_SHORT, SHRT_MIN)
+ ts.T_USHORT=USHRT_MAX
+ self.assertEquals(ts.T_USHORT, USHRT_MAX)
+
+ ts.T_INT=INT_MAX
+ self.assertEquals(ts.T_INT, INT_MAX)
+ ts.T_INT=INT_MIN
+ self.assertEquals(ts.T_INT, INT_MIN)
+ ts.T_UINT=UINT_MAX
+ self.assertEquals(ts.T_UINT, UINT_MAX)
+
+ ts.T_LONG=LONG_MAX
+ self.assertEquals(ts.T_LONG, LONG_MAX)
+ ts.T_LONG=LONG_MIN
+ self.assertEquals(ts.T_LONG, LONG_MIN)
+ ts.T_ULONG=ULONG_MAX
+ self.assertEquals(ts.T_ULONG, ULONG_MAX)
+
+class TestWarnings(test.test_warnings.TestModule):
+ def has_warned(self):
+ self.assertEqual(test.test_warnings.msg.category,
+ exceptions.RuntimeWarning.__name__)
+
+ def test_byte_max(self):
+ ts.T_BYTE=CHAR_MAX+1
+ self.has_warned()
+
+ def test_byte_min(self):
+ ts.T_BYTE=CHAR_MIN-1
+ self.has_warned()
+
+ def test_ubyte_max(self):
+ ts.T_UBYTE=UCHAR_MAX+1
+ self.has_warned()
+
+ def test_short_max(self):
+ ts.T_SHORT=SHRT_MAX+1
+ self.has_warned()
+
+ def test_short_min(self):
+ ts.T_SHORT=SHRT_MIN-1
+ self.has_warned()
+
+ def test_ushort_max(self):
+ ts.T_USHORT=USHRT_MAX+1
+ self.has_warned()
+
+
+
+def test_main(verbose=None):
+ test_support.run_unittest(
+ ReadWriteTests,
+ TestWarnings
+ )
+
+if __name__ == "__main__":
+ test_main(verbose=True)
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 8c8ac40..64f8d40 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -234,6 +234,12 @@ class ProcessTestCase(unittest.TestCase):
stripped = remove_stderr_debug_decorations(output)
self.assertEqual(stripped, "appleorange")
+ def test_stdout_filedes_of_stdout(self):
+ # stdout is set to 1 (#1531862).
+ cmd = r"import sys, os; sys.exit(os.write(sys.stdout.fileno(), '.\n'))"
+ rc = subprocess.call([sys.executable, "-c", cmd], stdout=1)
+ self.assertEquals(rc, 2)
+
def test_cwd(self):
tmpdir = os.getenv("TEMP", "/tmp")
# We cannot use os.path.realpath to canonicalize the path,
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
index d260fc5..2829c55 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -244,13 +244,13 @@ def sortdict(dict):
withcommas = ", ".join(reprpairs)
return "{%s}" % withcommas
-def check_syntax(statement):
+def check_syntax_error(testcase, statement):
try:
- compile(statement, '<string>', 'exec')
+ compile(statement, '<test string>', 'exec')
except SyntaxError:
pass
else:
- print 'Missing SyntaxError: "%s"' % statement
+ testcase.fail('Missing SyntaxError: "%s"' % statement)
def open_urlresource(url):
import urllib, urlparse
diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py
index acb3f10..a0eaac6 100644
--- a/Lib/test/test_syntax.py
+++ b/Lib/test/test_syntax.py
@@ -235,6 +235,138 @@ SyntaxError: assignment to None (<doctest test.test_syntax[32]>, line 1)
>>> f() += 1
Traceback (most recent call last):
SyntaxError: illegal expression for augmented assignment (<doctest test.test_syntax[33]>, line 1)
+
+
+Test continue in finally in weird combinations.
+
+continue in for loop under finally shouuld be ok.
+
+ >>> def test():
+ ... try:
+ ... pass
+ ... finally:
+ ... for abc in range(10):
+ ... continue
+ ... print abc
+ >>> test()
+ 9
+
+Start simple, a continue in a finally should not be allowed.
+
+ >>> def test():
+ ... for abc in range(10):
+ ... try:
+ ... pass
+ ... finally:
+ ... continue
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[36]>, line 6)
+
+This is essentially a continue in a finally which should not be allowed.
+
+ >>> def test():
+ ... for abc in range(10):
+ ... try:
+ ... pass
+ ... finally:
+ ... try:
+ ... continue
+ ... except:
+ ... pass
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[37]>, line 7)
+
+ >>> def foo():
+ ... try:
+ ... pass
+ ... finally:
+ ... continue
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[38]>, line 5)
+
+ >>> def foo():
+ ... for a in ():
+ ... try:
+ ... pass
+ ... finally:
+ ... continue
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[39]>, line 6)
+
+ >>> def foo():
+ ... for a in ():
+ ... try:
+ ... pass
+ ... finally:
+ ... try:
+ ... continue
+ ... finally:
+ ... pass
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[40]>, line 7)
+
+ >>> def foo():
+ ... for a in ():
+ ... try: pass
+ ... finally:
+ ... try:
+ ... pass
+ ... except:
+ ... continue
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[41]>, line 8)
+
+There is one test for a break that is not in a loop. The compiler
+uses a single data structure to keep track of try-finally and loops,
+so we need to be sure that a break is actually inside a loop. If it
+isn't, there should be a syntax error.
+
+ >>> try:
+ ... print 1
+ ... break
+ ... print 2
+ ... finally:
+ ... print 3
+ Traceback (most recent call last):
+ ...
+ SyntaxError: 'break' outside loop (<doctest test.test_syntax[42]>, line 3)
+
+This should probably raise a better error than a SystemError (or none at all).
+In 2.5 there was a missing exception and an assert was triggered in a debug
+build. The number of blocks must be greater than CO_MAXBLOCKS. SF #1565514
+
+ >>> while 1:
+ ... while 2:
+ ... while 3:
+ ... while 4:
+ ... while 5:
+ ... while 6:
+ ... while 8:
+ ... while 9:
+ ... while 10:
+ ... while 11:
+ ... while 12:
+ ... while 13:
+ ... while 14:
+ ... while 15:
+ ... while 16:
+ ... while 17:
+ ... while 18:
+ ... while 19:
+ ... while 20:
+ ... while 21:
+ ... while 22:
+ ... break
+ Traceback (most recent call last):
+ ...
+ SystemError: too many statically nested blocks
+
"""
import re
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
index a47afa4..0cebb29 100644
--- a/Lib/test/test_tarfile.py
+++ b/Lib/test/test_tarfile.py
@@ -280,6 +280,32 @@ class WriteTest(BaseTest):
else:
self.dst.addfile(tarinfo, f)
+
+class Write100Test(BaseTest):
+ # The name field in a tar header stores strings of at most 100 chars.
+ # If a string is shorter than 100 chars it has to be padded with '\0',
+ # which implies that a string of exactly 100 chars is stored without
+ # a trailing '\0'.
+
+ def setUp(self):
+ self.name = "01234567890123456789012345678901234567890123456789"
+ self.name += "01234567890123456789012345678901234567890123456789"
+
+ self.tar = tarfile.open(tmpname(), "w")
+ t = tarfile.TarInfo(self.name)
+ self.tar.addfile(t)
+ self.tar.close()
+
+ self.tar = tarfile.open(tmpname())
+
+ def tearDown(self):
+ self.tar.close()
+
+ def test(self):
+ self.assertEqual(self.tar.getnames()[0], self.name,
+ "failed to store 100 char filename")
+
+
class WriteSize0Test(BaseTest):
mode = 'w'
@@ -362,13 +388,6 @@ class WriteGNULongTest(unittest.TestCase):
is tested as well.
"""
- def setUp(self):
- self.tar = tarfile.open(tmpname(), "w")
- self.tar.posix = False
-
- def tearDown(self):
- self.tar.close()
-
def _length(self, s):
blocks, remainder = divmod(len(s) + 1, 512)
if remainder:
@@ -397,12 +416,23 @@ class WriteGNULongTest(unittest.TestCase):
tarinfo.linkname = link
tarinfo.type = tarfile.LNKTYPE
- self.tar.addfile(tarinfo)
+ tar = tarfile.open(tmpname(), "w")
+ tar.posix = False
+ tar.addfile(tarinfo)
v1 = self._calc_size(name, link)
- v2 = self.tar.offset
+ v2 = tar.offset
self.assertEqual(v1, v2, "GNU longname/longlink creation failed")
+ tar.close()
+
+ tar = tarfile.open(tmpname())
+ member = tar.next()
+ self.failIf(member is None, "unable to read longname member")
+ self.assert_(tarinfo.name == member.name and \
+ tarinfo.linkname == member.linkname, \
+ "unable to read longname member")
+
def test_longname_1023(self):
self._test(("longnam/" * 127) + "longnam")
@@ -623,6 +653,7 @@ def test_main():
ReadAsteriskTest,
ReadStreamAsteriskTest,
WriteTest,
+ Write100Test,
WriteSize0Test,
WriteStreamTest,
WriteGNULongTest,
diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py
index aeaa77e..2047a63 100644
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -27,7 +27,7 @@ has_spawnl = hasattr(os, 'spawnl')
# number of files that can be opened at one time (see ulimit -n)
if sys.platform == 'mac':
TEST_FILES = 32
-elif sys.platform == 'openbsd3':
+elif sys.platform in ('openbsd3', 'openbsd4'):
TEST_FILES = 48
else:
TEST_FILES = 100
diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py
index 4fd7834..18129da 100644
--- a/Lib/test/test_time.py
+++ b/Lib/test/test_time.py
@@ -102,15 +102,19 @@ class TimeTestCase(unittest.TestCase):
self.assertEquals(expected, result)
def test_strptime(self):
+ # Should be able to go round-trip from strftime to strptime without
+ # throwing an exception.
tt = time.gmtime(self.t)
for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I',
'j', 'm', 'M', 'p', 'S',
'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
- format = ' %' + directive
+ format = '%' + directive
+ strf_output = time.strftime(format, tt)
try:
- time.strptime(time.strftime(format, tt), format)
+ time.strptime(strf_output, format)
except ValueError:
- self.fail('conversion specifier: %r failed.' % format)
+ self.fail("conversion specifier %r failed with '%s' input." %
+ (format, strf_output))
def test_asctime(self):
time.asctime(time.gmtime(self.t))
diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py
index b064967..be6c18d 100644
--- a/Lib/test/test_tokenize.py
+++ b/Lib/test/test_tokenize.py
@@ -1,9 +1,93 @@
-import os, glob, random
+"""Tests for the tokenize module.
+
+The tests were originally written in the old Python style, where the
+test output was compared to a golden file. This docstring represents
+the first steps towards rewriting the entire test as a doctest.
+
+The tests can be really simple. Given a small fragment of source
+code, print out a table with the tokens. The ENDMARK is omitted for
+brevity.
+
+>>> dump_tokens("1 + 1")
+NUMBER '1' (1, 0) (1, 1)
+OP '+' (1, 2) (1, 3)
+NUMBER '1' (1, 4) (1, 5)
+
+A comment generates a token here, unlike in the parser module. The
+comment token is followed by an NL or a NEWLINE token, depending on
+whether the line contains the completion of a statement.
+
+>>> dump_tokens("if False:\\n"
+... " # NL\\n"
+... " True = False # NEWLINE\\n")
+NAME 'if' (1, 0) (1, 2)
+NAME 'False' (1, 3) (1, 8)
+OP ':' (1, 8) (1, 9)
+NEWLINE '\\n' (1, 9) (1, 10)
+COMMENT '# NL' (2, 4) (2, 8)
+NL '\\n' (2, 8) (2, 9)
+INDENT ' ' (3, 0) (3, 4)
+NAME 'True' (3, 4) (3, 8)
+OP '=' (3, 9) (3, 10)
+NAME 'False' (3, 11) (3, 16)
+COMMENT '# NEWLINE' (3, 17) (3, 26)
+NEWLINE '\\n' (3, 26) (3, 27)
+DEDENT '' (4, 0) (4, 0)
+
+
+There will be a bunch more tests of specific source patterns.
+
+The tokenize module also defines an untokenize function that should
+regenerate the original program text from the tokens.
+
+There are some standard formatting practices that are easy to get right.
+
+>>> roundtrip("if x == 1:\\n"
+... " print x\\n")
+if x == 1:
+ print x
+
+Some people use different formatting conventions, which makes
+untokenize a little trickier. Note that this test involves trailing
+whitespace after the colon. Note that we use hex escapes to make the
+two trailing blanks apparent in the expected output.
+
+>>> roundtrip("if x == 1 : \\n"
+... " print x\\n")
+if x == 1 :\x20\x20
+ print x
+
+Comments need to go in the right place.
+
+>>> roundtrip("if x == 1:\\n"
+... " # A comment by itself.\\n"
+... " print x # Comment here, too.\\n"
+... " # Another comment.\\n"
+... "after_if = True\\n")
+if x == 1:
+ # A comment by itself.
+ print x # Comment here, too.
+ # Another comment.
+after_if = True
+
+>>> roundtrip("if (x # The comments need to go in the right place\\n"
+... " == 1):\\n"
+... " print 'x == 1'\\n")
+if (x # The comments need to go in the right place
+ == 1):
+ print 'x == 1'
+
+"""
+
+import os, glob, random, time, sys
from cStringIO import StringIO
from test.test_support import (verbose, findfile, is_resource_enabled,
TestFailed)
-from tokenize import (tokenize, generate_tokens, untokenize,
- NUMBER, NAME, OP, STRING)
+from tokenize import (tokenize, generate_tokens, untokenize, tok_name,
+ ENDMARKER, NUMBER, NAME, OP, STRING, COMMENT)
+
+# How much time in seconds can pass before we print a 'Still working' message.
+_PRINT_WORKING_MSG_INTERVAL = 5 * 60
# Test roundtrip for `untokenize`. `f` is a file path. The source code in f
# is tokenized, converted back to source code via tokenize.untokenize(),
@@ -24,6 +108,23 @@ def test_roundtrip(f):
if t1 != t2:
raise TestFailed("untokenize() roundtrip failed for %r" % f)
+def dump_tokens(s):
+ """Print out the tokens in s in a table format.
+
+ The ENDMARKER is omitted.
+ """
+ f = StringIO(s)
+ for type, token, start, end, line in generate_tokens(f.readline):
+ if type == ENDMARKER:
+ break
+ type = tok_name[type]
+ print "%(type)-10.10s %(token)-13.13r %(start)s %(end)s" % locals()
+
+def roundtrip(s):
+ f = StringIO(s)
+ source = untokenize(generate_tokens(f.readline))
+ print source,
+
# This is an example from the docs, set up as a doctest.
def decistmt(s):
"""Substitute Decimals for floats in a string of statements.
@@ -66,6 +167,8 @@ def test_main():
if verbose:
print 'starting...'
+ next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
+
# This displays the tokenization of tokenize_tests.py to stdout, and
# regrtest.py checks that this equals the expected output (in the
# test/output/ directory).
@@ -85,6 +188,12 @@ def test_main():
testfiles = random.sample(testfiles, 10)
for f in testfiles:
+ # Print still working message since this test can be really slow
+ if next_time <= time.time():
+ next_time = time.time() + _PRINT_WORKING_MSG_INTERVAL
+ print >>sys.__stdout__, ' test_main still working, be patient...'
+ sys.__stdout__.flush()
+
test_roundtrip(f)
# Test detecton of IndentationError.
@@ -105,7 +214,7 @@ def foo():
# Run the doctests in this module.
from test import test_tokenize # i.e., this module
from test.test_support import run_doctest
- run_doctest(test_tokenize)
+ run_doctest(test_tokenize, verbose)
if verbose:
print 'finished'
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index 9ba1dca..48c5d19 100644
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -122,6 +122,10 @@ def test():
X.__name__,
str_value))
+ def test_without_exception(self):
+ err = traceback.format_exception_only(None, None)
+ self.assertEqual(err, ['None\n'])
+
def test_main():
run_unittest(TracebackCases)
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index f0bdfde..8d26914 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -1,285 +1,271 @@
# Python test set -- part 6, built-in types
-from test.test_support import *
-
-print '6. Built-in types'
-
-print '6.1 Truth value testing'
-if None: raise TestFailed, 'None is true instead of false'
-if 0: raise TestFailed, '0 is true instead of false'
-if 0L: raise TestFailed, '0L is true instead of false'
-if 0.0: raise TestFailed, '0.0 is true instead of false'
-if '': raise TestFailed, '\'\' is true instead of false'
-if not 1: raise TestFailed, '1 is false instead of true'
-if not 1L: raise TestFailed, '1L is false instead of true'
-if not 1.0: raise TestFailed, '1.0 is false instead of true'
-if not 'x': raise TestFailed, '\'x\' is false instead of true'
-if not {'x': 1}: raise TestFailed, '{\'x\': 1} is false instead of true'
-def f(): pass
-class C: pass
+from test.test_support import run_unittest, have_unicode
+import unittest
import sys
-x = C()
-if not f: raise TestFailed, 'f is false instead of true'
-if not C: raise TestFailed, 'C is false instead of true'
-if not sys: raise TestFailed, 'sys is false instead of true'
-if not x: raise TestFailed, 'x is false instead of true'
-
-print '6.2 Boolean operations'
-if 0 or 0: raise TestFailed, '0 or 0 is true instead of false'
-if 1 and 1: pass
-else: raise TestFailed, '1 and 1 is false instead of true'
-if not 1: raise TestFailed, 'not 1 is true instead of false'
-
-print '6.3 Comparisons'
-if 0 < 1 <= 1 == 1 >= 1 > 0 != 1: pass
-else: raise TestFailed, 'int comparisons failed'
-if 0L < 1L <= 1L == 1L >= 1L > 0L != 1L: pass
-else: raise TestFailed, 'long int comparisons failed'
-if 0.0 < 1.0 <= 1.0 == 1.0 >= 1.0 > 0.0 != 1.0: pass
-else: raise TestFailed, 'float comparisons failed'
-if '' < 'a' <= 'a' == 'a' < 'abc' < 'abd' < 'b': pass
-else: raise TestFailed, 'string comparisons failed'
-if None is None: pass
-else: raise TestFailed, 'identity test failed'
-
-try: float('')
-except ValueError: pass
-else: raise TestFailed, "float('') didn't raise ValueError"
-
-try: float('5\0')
-except ValueError: pass
-else: raise TestFailed, "float('5\0') didn't raise ValueError"
-
-try: 5.0 / 0.0
-except ZeroDivisionError: pass
-else: raise TestFailed, "5.0 / 0.0 didn't raise ZeroDivisionError"
-
-try: 5.0 // 0.0
-except ZeroDivisionError: pass
-else: raise TestFailed, "5.0 // 0.0 didn't raise ZeroDivisionError"
-
-try: 5.0 % 0.0
-except ZeroDivisionError: pass
-else: raise TestFailed, "5.0 % 0.0 didn't raise ZeroDivisionError"
-
-try: 5 / 0L
-except ZeroDivisionError: pass
-else: raise TestFailed, "5 / 0L didn't raise ZeroDivisionError"
-
-try: 5 // 0L
-except ZeroDivisionError: pass
-else: raise TestFailed, "5 // 0L didn't raise ZeroDivisionError"
-
-try: 5 % 0L
-except ZeroDivisionError: pass
-else: raise TestFailed, "5 % 0L didn't raise ZeroDivisionError"
-
-print '6.4 Numeric types (mostly conversions)'
-if 0 != 0L or 0 != 0.0 or 0L != 0.0: raise TestFailed, 'mixed comparisons'
-if 1 != 1L or 1 != 1.0 or 1L != 1.0: raise TestFailed, 'mixed comparisons'
-if -1 != -1L or -1 != -1.0 or -1L != -1.0:
- raise TestFailed, 'int/long/float value not equal'
-# calling built-in types without argument must return 0
-if int() != 0: raise TestFailed, 'int() does not return 0'
-if long() != 0L: raise TestFailed, 'long() does not return 0L'
-if float() != 0.0: raise TestFailed, 'float() does not return 0.0'
-if int(1.9) == 1 == int(1.1) and int(-1.1) == -1 == int(-1.9): pass
-else: raise TestFailed, 'int() does not round properly'
-if long(1.9) == 1L == long(1.1) and long(-1.1) == -1L == long(-1.9): pass
-else: raise TestFailed, 'long() does not round properly'
-if float(1) == 1.0 and float(-1) == -1.0 and float(0) == 0.0: pass
-else: raise TestFailed, 'float() does not work properly'
-print '6.4.1 32-bit integers'
-# Ensure the first 256 integers are shared
-a = 256
-b = 128*2
-if a is not b: raise TestFailed, '256 is not shared'
-if 12 + 24 != 36: raise TestFailed, 'int op'
-if 12 + (-24) != -12: raise TestFailed, 'int op'
-if (-12) + 24 != 12: raise TestFailed, 'int op'
-if (-12) + (-24) != -36: raise TestFailed, 'int op'
-if not 12 < 24: raise TestFailed, 'int op'
-if not -24 < -12: raise TestFailed, 'int op'
-# Test for a particular bug in integer multiply
-xsize, ysize, zsize = 238, 356, 4
-if not (xsize*ysize*zsize == zsize*xsize*ysize == 338912):
- raise TestFailed, 'int mul commutativity'
-# And another.
-m = -sys.maxint - 1
-for divisor in 1, 2, 4, 8, 16, 32:
- j = m // divisor
- prod = divisor * j
- if prod != m:
- raise TestFailed, "%r * %r == %r != %r" % (divisor, j, prod, m)
- if type(prod) is not int:
- raise TestFailed, ("expected type(prod) to be int, not %r" %
- type(prod))
-# Check for expected * overflow to long.
-for divisor in 1, 2, 4, 8, 16, 32:
- j = m // divisor - 1
- prod = divisor * j
- if type(prod) is not long:
- raise TestFailed, ("expected type(%r) to be long, not %r" %
- (prod, type(prod)))
-# Check for expected * overflow to long.
-m = sys.maxint
-for divisor in 1, 2, 4, 8, 16, 32:
- j = m // divisor + 1
- prod = divisor * j
- if type(prod) is not long:
- raise TestFailed, ("expected type(%r) to be long, not %r" %
- (prod, type(prod)))
-
-print '6.4.2 Long integers'
-if 12L + 24L != 36L: raise TestFailed, 'long op'
-if 12L + (-24L) != -12L: raise TestFailed, 'long op'
-if (-12L) + 24L != 12L: raise TestFailed, 'long op'
-if (-12L) + (-24L) != -36L: raise TestFailed, 'long op'
-if not 12L < 24L: raise TestFailed, 'long op'
-if not -24L < -12L: raise TestFailed, 'long op'
-x = sys.maxint
-if int(long(x)) != x: raise TestFailed, 'long op'
-try: y = int(long(x)+1L)
-except OverflowError: raise TestFailed, 'long op'
-if not isinstance(y, long): raise TestFailed, 'long op'
-x = -x
-if int(long(x)) != x: raise TestFailed, 'long op'
-x = x-1
-if int(long(x)) != x: raise TestFailed, 'long op'
-try: y = int(long(x)-1L)
-except OverflowError: raise TestFailed, 'long op'
-if not isinstance(y, long): raise TestFailed, 'long op'
-
-try: 5 << -5
-except ValueError: pass
-else: raise TestFailed, 'int negative shift <<'
-
-try: 5L << -5L
-except ValueError: pass
-else: raise TestFailed, 'long negative shift <<'
-
-try: 5 >> -5
-except ValueError: pass
-else: raise TestFailed, 'int negative shift >>'
-
-try: 5L >> -5L
-except ValueError: pass
-else: raise TestFailed, 'long negative shift >>'
-
-print '6.4.3 Floating point numbers'
-if 12.0 + 24.0 != 36.0: raise TestFailed, 'float op'
-if 12.0 + (-24.0) != -12.0: raise TestFailed, 'float op'
-if (-12.0) + 24.0 != 12.0: raise TestFailed, 'float op'
-if (-12.0) + (-24.0) != -36.0: raise TestFailed, 'float op'
-if not 12.0 < 24.0: raise TestFailed, 'float op'
-if not -24.0 < -12.0: raise TestFailed, 'float op'
-
-print '6.5 Sequence types'
-
-print '6.5.1 Strings'
-if len('') != 0: raise TestFailed, 'len(\'\')'
-if len('a') != 1: raise TestFailed, 'len(\'a\')'
-if len('abcdef') != 6: raise TestFailed, 'len(\'abcdef\')'
-if 'xyz' + 'abcde' != 'xyzabcde': raise TestFailed, 'string concatenation'
-if 'xyz'*3 != 'xyzxyzxyz': raise TestFailed, 'string repetition *3'
-if 0*'abcde' != '': raise TestFailed, 'string repetition 0*'
-if min('abc') != 'a' or max('abc') != 'c': raise TestFailed, 'min/max string'
-if 'a' in 'abc' and 'b' in 'abc' and 'c' in 'abc' and 'd' not in 'abc': pass
-else: raise TestFailed, 'in/not in string'
-x = 'x'*103
-if '%s!'%x != x+'!': raise TestFailed, 'nasty string formatting bug'
-
-#extended slices for strings
-a = '0123456789'
-vereq(a[::], a)
-vereq(a[::2], '02468')
-vereq(a[1::2], '13579')
-vereq(a[::-1],'9876543210')
-vereq(a[::-2], '97531')
-vereq(a[3::-2], '31')
-vereq(a[-100:100:], a)
-vereq(a[100:-100:-1], a[::-1])
-vereq(a[-100L:100L:2L], '02468')
-
-if have_unicode:
- a = unicode('0123456789', 'ascii')
- vereq(a[::], a)
- vereq(a[::2], unicode('02468', 'ascii'))
- vereq(a[1::2], unicode('13579', 'ascii'))
- vereq(a[::-1], unicode('9876543210', 'ascii'))
- vereq(a[::-2], unicode('97531', 'ascii'))
- vereq(a[3::-2], unicode('31', 'ascii'))
- vereq(a[-100:100:], a)
- vereq(a[100:-100:-1], a[::-1])
- vereq(a[-100L:100L:2L], unicode('02468', 'ascii'))
-
-
-print '6.5.2 Tuples [see test_tuple.py]'
-
-print '6.5.3 Lists [see test_list.py]'
-
-print '6.6 Mappings == Dictionaries [see test_dict.py]'
-
-
-try: type(1, 2)
-except TypeError: pass
-else: raise TestFailed, 'type(), w/2 args expected TypeError'
-
-try: type(1, 2, 3, 4)
-except TypeError: pass
-else: raise TestFailed, 'type(), w/4 args expected TypeError'
-
-print 'Buffers'
-try: buffer('asdf', -1)
-except ValueError: pass
-else: raise TestFailed, "buffer('asdf', -1) should raise ValueError"
-
-try: buffer(None)
-except TypeError: pass
-else: raise TestFailed, "buffer(None) should raise TypeError"
-
-a = buffer('asdf')
-hash(a)
-b = a * 5
-if a == b:
- raise TestFailed, 'buffers should not be equal'
-if str(b) != ('asdf' * 5):
- raise TestFailed, 'repeated buffer has wrong content'
-if str(a * 0) != '':
- raise TestFailed, 'repeated buffer zero times has wrong content'
-if str(a + buffer('def')) != 'asdfdef':
- raise TestFailed, 'concatenation of buffers yields wrong content'
-if str(buffer(a)) != 'asdf':
- raise TestFailed, 'composing buffers failed'
-if str(buffer(a, 2)) != 'df':
- raise TestFailed, 'specifying buffer offset failed'
-if str(buffer(a, 0, 2)) != 'as':
- raise TestFailed, 'specifying buffer size failed'
-if str(buffer(a, 1, 2)) != 'sd':
- raise TestFailed, 'specifying buffer offset and size failed'
-try: buffer(buffer('asdf', 1), -1)
-except ValueError: pass
-else: raise TestFailed, "buffer(buffer('asdf', 1), -1) should raise ValueError"
-if str(buffer(buffer('asdf', 0, 2), 0)) != 'as':
- raise TestFailed, 'composing length-specified buffer failed'
-if str(buffer(buffer('asdf', 0, 2), 0, 5000)) != 'as':
- raise TestFailed, 'composing length-specified buffer failed'
-if str(buffer(buffer('asdf', 0, 2), 0, -1)) != 'as':
- raise TestFailed, 'composing length-specified buffer failed'
-if str(buffer(buffer('asdf', 0, 2), 1, 2)) != 's':
- raise TestFailed, 'composing length-specified buffer failed'
-
-try: a[1] = 'g'
-except TypeError: pass
-else: raise TestFailed, "buffer assignment should raise TypeError"
-
-try: a[0:1] = 'g'
-except TypeError: pass
-else: raise TestFailed, "buffer slice assignment should raise TypeError"
-
-# array.array() returns an object that does not implement a char buffer,
-# something which int() uses for conversion.
-import array
-try: int(buffer(array.array('c')))
-except TypeError :pass
-else: raise TestFailed, "char buffer (at C level) not working"
+
+class TypesTests(unittest.TestCase):
+
+ def test_truth_values(self):
+ if None: self.fail('None is true instead of false')
+ if 0: self.fail('0 is true instead of false')
+ if 0L: self.fail('0L is true instead of false')
+ if 0.0: self.fail('0.0 is true instead of false')
+ if '': self.fail('\'\' is true instead of false')
+ if not 1: self.fail('1 is false instead of true')
+ if not 1L: self.fail('1L is false instead of true')
+ if not 1.0: self.fail('1.0 is false instead of true')
+ if not 'x': self.fail('\'x\' is false instead of true')
+ if not {'x': 1}: self.fail('{\'x\': 1} is false instead of true')
+ def f(): pass
+ class C: pass
+ import sys
+ x = C()
+ if not f: self.fail('f is false instead of true')
+ if not C: self.fail('C is false instead of true')
+ if not sys: self.fail('sys is false instead of true')
+ if not x: self.fail('x is false instead of true')
+
+ def test_boolean_ops(self):
+ if 0 or 0: self.fail('0 or 0 is true instead of false')
+ if 1 and 1: pass
+ else: self.fail('1 and 1 is false instead of true')
+ if not 1: self.fail('not 1 is true instead of false')
+
+ def test_comparisons(self):
+ if 0 < 1 <= 1 == 1 >= 1 > 0 != 1: pass
+ else: self.fail('int comparisons failed')
+ if 0L < 1L <= 1L == 1L >= 1L > 0L != 1L: pass
+ else: self.fail('long int comparisons failed')
+ if 0.0 < 1.0 <= 1.0 == 1.0 >= 1.0 > 0.0 != 1.0: pass
+ else: self.fail('float comparisons failed')
+ if '' < 'a' <= 'a' == 'a' < 'abc' < 'abd' < 'b': pass
+ else: self.fail('string comparisons failed')
+ if None is None: pass
+ else: self.fail('identity test failed')
+
+ def test_float_constructor(self):
+ self.assertRaises(ValueError, float, '')
+ self.assertRaises(ValueError, float, '5\0')
+
+ def test_zero_division(self):
+ try: 5.0 / 0.0
+ except ZeroDivisionError: pass
+ else: self.fail("5.0 / 0.0 didn't raise ZeroDivisionError")
+
+ try: 5.0 // 0.0
+ except ZeroDivisionError: pass
+ else: self.fail("5.0 // 0.0 didn't raise ZeroDivisionError")
+
+ try: 5.0 % 0.0
+ except ZeroDivisionError: pass
+ else: self.fail("5.0 % 0.0 didn't raise ZeroDivisionError")
+
+ try: 5 / 0L
+ except ZeroDivisionError: pass
+ else: self.fail("5 / 0L didn't raise ZeroDivisionError")
+
+ try: 5 // 0L
+ except ZeroDivisionError: pass
+ else: self.fail("5 // 0L didn't raise ZeroDivisionError")
+
+ try: 5 % 0L
+ except ZeroDivisionError: pass
+ else: self.fail("5 % 0L didn't raise ZeroDivisionError")
+
+ def test_numeric_types(self):
+ if 0 != 0L or 0 != 0.0 or 0L != 0.0: self.fail('mixed comparisons')
+ if 1 != 1L or 1 != 1.0 or 1L != 1.0: self.fail('mixed comparisons')
+ if -1 != -1L or -1 != -1.0 or -1L != -1.0:
+ self.fail('int/long/float value not equal')
+ # calling built-in types without argument must return 0
+ if int() != 0: self.fail('int() does not return 0')
+ if long() != 0L: self.fail('long() does not return 0L')
+ if float() != 0.0: self.fail('float() does not return 0.0')
+ if int(1.9) == 1 == int(1.1) and int(-1.1) == -1 == int(-1.9): pass
+ else: self.fail('int() does not round properly')
+ if long(1.9) == 1L == long(1.1) and long(-1.1) == -1L == long(-1.9): pass
+ else: self.fail('long() does not round properly')
+ if float(1) == 1.0 and float(-1) == -1.0 and float(0) == 0.0: pass
+ else: self.fail('float() does not work properly')
+
+ def test_normal_integers(self):
+ # Ensure the first 256 integers are shared
+ a = 256
+ b = 128*2
+ if a is not b: self.fail('256 is not shared')
+ if 12 + 24 != 36: self.fail('int op')
+ if 12 + (-24) != -12: self.fail('int op')
+ if (-12) + 24 != 12: self.fail('int op')
+ if (-12) + (-24) != -36: self.fail('int op')
+ if not 12 < 24: self.fail('int op')
+ if not -24 < -12: self.fail('int op')
+ # Test for a particular bug in integer multiply
+ xsize, ysize, zsize = 238, 356, 4
+ if not (xsize*ysize*zsize == zsize*xsize*ysize == 338912):
+ self.fail('int mul commutativity')
+ # And another.
+ m = -sys.maxint - 1
+ for divisor in 1, 2, 4, 8, 16, 32:
+ j = m // divisor
+ prod = divisor * j
+ if prod != m:
+ self.fail("%r * %r == %r != %r" % (divisor, j, prod, m))
+ if type(prod) is not int:
+ self.fail("expected type(prod) to be int, not %r" %
+ type(prod))
+ # Check for expected * overflow to long.
+ for divisor in 1, 2, 4, 8, 16, 32:
+ j = m // divisor - 1
+ prod = divisor * j
+ if type(prod) is not long:
+ self.fail("expected type(%r) to be long, not %r" %
+ (prod, type(prod)))
+ # Check for expected * overflow to long.
+ m = sys.maxint
+ for divisor in 1, 2, 4, 8, 16, 32:
+ j = m // divisor + 1
+ prod = divisor * j
+ if type(prod) is not long:
+ self.fail("expected type(%r) to be long, not %r" %
+ (prod, type(prod)))
+
+ def test_long_integers(self):
+ if 12L + 24L != 36L: self.fail('long op')
+ if 12L + (-24L) != -12L: self.fail('long op')
+ if (-12L) + 24L != 12L: self.fail('long op')
+ if (-12L) + (-24L) != -36L: self.fail('long op')
+ if not 12L < 24L: self.fail('long op')
+ if not -24L < -12L: self.fail('long op')
+ x = sys.maxint
+ if int(long(x)) != x: self.fail('long op')
+ try: y = int(long(x)+1L)
+ except OverflowError: self.fail('long op')
+ if not isinstance(y, long): self.fail('long op')
+ x = -x
+ if int(long(x)) != x: self.fail('long op')
+ x = x-1
+ if int(long(x)) != x: self.fail('long op')
+ try: y = int(long(x)-1L)
+ except OverflowError: self.fail('long op')
+ if not isinstance(y, long): self.fail('long op')
+
+ try: 5 << -5
+ except ValueError: pass
+ else: self.fail('int negative shift <<')
+
+ try: 5L << -5L
+ except ValueError: pass
+ else: self.fail('long negative shift <<')
+
+ try: 5 >> -5
+ except ValueError: pass
+ else: self.fail('int negative shift >>')
+
+ try: 5L >> -5L
+ except ValueError: pass
+ else: self.fail('long negative shift >>')
+
+ def test_floats(self):
+ if 12.0 + 24.0 != 36.0: self.fail('float op')
+ if 12.0 + (-24.0) != -12.0: self.fail('float op')
+ if (-12.0) + 24.0 != 12.0: self.fail('float op')
+ if (-12.0) + (-24.0) != -36.0: self.fail('float op')
+ if not 12.0 < 24.0: self.fail('float op')
+ if not -24.0 < -12.0: self.fail('float op')
+
+ def test_strings(self):
+ if len('') != 0: self.fail('len(\'\')')
+ if len('a') != 1: self.fail('len(\'a\')')
+ if len('abcdef') != 6: self.fail('len(\'abcdef\')')
+ if 'xyz' + 'abcde' != 'xyzabcde': self.fail('string concatenation')
+ if 'xyz'*3 != 'xyzxyzxyz': self.fail('string repetition *3')
+ if 0*'abcde' != '': self.fail('string repetition 0*')
+ if min('abc') != 'a' or max('abc') != 'c': self.fail('min/max string')
+ if 'a' in 'abc' and 'b' in 'abc' and 'c' in 'abc' and 'd' not in 'abc': pass
+ else: self.fail('in/not in string')
+ x = 'x'*103
+ if '%s!'%x != x+'!': self.fail('nasty string formatting bug')
+
+ #extended slices for strings
+ a = '0123456789'
+ self.assertEqual(a[::], a)
+ self.assertEqual(a[::2], '02468')
+ self.assertEqual(a[1::2], '13579')
+ self.assertEqual(a[::-1],'9876543210')
+ self.assertEqual(a[::-2], '97531')
+ self.assertEqual(a[3::-2], '31')
+ self.assertEqual(a[-100:100:], a)
+ self.assertEqual(a[100:-100:-1], a[::-1])
+ self.assertEqual(a[-100L:100L:2L], '02468')
+
+ if have_unicode:
+ a = unicode('0123456789', 'ascii')
+ self.assertEqual(a[::], a)
+ self.assertEqual(a[::2], unicode('02468', 'ascii'))
+ self.assertEqual(a[1::2], unicode('13579', 'ascii'))
+ self.assertEqual(a[::-1], unicode('9876543210', 'ascii'))
+ self.assertEqual(a[::-2], unicode('97531', 'ascii'))
+ self.assertEqual(a[3::-2], unicode('31', 'ascii'))
+ self.assertEqual(a[-100:100:], a)
+ self.assertEqual(a[100:-100:-1], a[::-1])
+ self.assertEqual(a[-100L:100L:2L], unicode('02468', 'ascii'))
+
+
+ def test_type_function(self):
+ self.assertRaises(TypeError, type, 1, 2)
+ self.assertRaises(TypeError, type, 1, 2, 3, 4)
+
+ def test_buffers(self):
+ self.assertRaises(ValueError, buffer, 'asdf', -1)
+ self.assertRaises(TypeError, buffer, None)
+
+ a = buffer('asdf')
+ hash(a)
+ b = a * 5
+ if a == b:
+ self.fail('buffers should not be equal')
+ if str(b) != ('asdf' * 5):
+ self.fail('repeated buffer has wrong content')
+ if str(a * 0) != '':
+ self.fail('repeated buffer zero times has wrong content')
+ if str(a + buffer('def')) != 'asdfdef':
+ self.fail('concatenation of buffers yields wrong content')
+ if str(buffer(a)) != 'asdf':
+ self.fail('composing buffers failed')
+ if str(buffer(a, 2)) != 'df':
+ self.fail('specifying buffer offset failed')
+ if str(buffer(a, 0, 2)) != 'as':
+ self.fail('specifying buffer size failed')
+ if str(buffer(a, 1, 2)) != 'sd':
+ self.fail('specifying buffer offset and size failed')
+ self.assertRaises(ValueError, buffer, buffer('asdf', 1), -1)
+ if str(buffer(buffer('asdf', 0, 2), 0)) != 'as':
+ self.fail('composing length-specified buffer failed')
+ if str(buffer(buffer('asdf', 0, 2), 0, 5000)) != 'as':
+ self.fail('composing length-specified buffer failed')
+ if str(buffer(buffer('asdf', 0, 2), 0, -1)) != 'as':
+ self.fail('composing length-specified buffer failed')
+ if str(buffer(buffer('asdf', 0, 2), 1, 2)) != 's':
+ self.fail('composing length-specified buffer failed')
+
+ try: a[1] = 'g'
+ except TypeError: pass
+ else: self.fail("buffer assignment should raise TypeError")
+
+ try: a[0:1] = 'g'
+ except TypeError: pass
+ else: self.fail("buffer slice assignment should raise TypeError")
+
+ # array.array() returns an object that does not implement a char buffer,
+ # something which int() uses for conversion.
+ import array
+ try: int(buffer(array.array('c')))
+ except TypeError: pass
+ else: self.fail("char buffer (at C level) not working")
+
+def test_main():
+ run_unittest(TypesTests)
+
+if __name__ == '__main__':
+ test_main()
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index 517ecfd..38ff9ac 100644
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -92,6 +92,9 @@ class UnicodeTest(
"\\xfe\\xff'")
testrepr = repr(u''.join(map(unichr, xrange(256))))
self.assertEqual(testrepr, latin1repr)
+ # Test repr works on wide unicode escapes without overflow.
+ self.assertEqual(repr(u"\U00010000" * 39 + u"\uffff" * 4096),
+ repr(u"\U00010000" * 39 + u"\uffff" * 4096))
def test_iterators(self):
# Make sure unicode objects have an __iter__ method
diff --git a/Lib/test/test_xdrlib.py b/Lib/test/test_xdrlib.py
index e9517c5..8fc88a5 100644
--- a/Lib/test/test_xdrlib.py
+++ b/Lib/test/test_xdrlib.py
@@ -1,3 +1,56 @@
+from test import test_support
+import unittest
+
import xdrlib
-xdrlib._test()
+class XDRTest(unittest.TestCase):
+
+ def test_xdr(self):
+ p = xdrlib.Packer()
+
+ s = 'hello world'
+ a = ['what', 'is', 'hapnin', 'doctor']
+
+ p.pack_int(42)
+ p.pack_uint(9)
+ p.pack_bool(True)
+ p.pack_bool(False)
+ p.pack_uhyper(45L)
+ p.pack_float(1.9)
+ p.pack_double(1.9)
+ p.pack_string(s)
+ p.pack_list(range(5), p.pack_uint)
+ p.pack_array(a, p.pack_string)
+
+ # now verify
+ data = p.get_buffer()
+ up = xdrlib.Unpacker(data)
+
+ self.assertEqual(up.get_position(), 0)
+
+ self.assertEqual(up.unpack_int(), 42)
+ self.assertEqual(up.unpack_uint(), 9)
+ self.assert_(up.unpack_bool() is True)
+
+ # remember position
+ pos = up.get_position()
+ self.assert_(up.unpack_bool() is False)
+
+ # rewind and unpack again
+ up.set_position(pos)
+ self.assert_(up.unpack_bool() is False)
+
+ self.assertEqual(up.unpack_uhyper(), 45L)
+ self.assertAlmostEqual(up.unpack_float(), 1.9)
+ self.assertAlmostEqual(up.unpack_double(), 1.9)
+ self.assertEqual(up.unpack_string(), s)
+ self.assertEqual(up.unpack_list(up.unpack_uint), range(5))
+ self.assertEqual(up.unpack_array(up.unpack_string), a)
+ up.done()
+ self.assertRaises(EOFError, up.unpack_uint)
+
+def test_main():
+ test_support.run_unittest(XDRTest)
+
+if __name__ == "__main__":
+ test_main()
diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py
index 64d8fe8..ccc1b60 100644
--- a/Lib/test/test_xmlrpc.py
+++ b/Lib/test/test_xmlrpc.py
@@ -86,6 +86,15 @@ class XMLRPCTestCase(unittest.TestCase):
s = xmlrpclib.dumps((new_d,), methodresponse=True)
self.assert_(isinstance(s, str))
+ def test_newstyle_class(self):
+ class T(object):
+ pass
+ t = T()
+ t.x = 100
+ t.y = "Hello"
+ ((t2,), dummy) = xmlrpclib.loads(xmlrpclib.dumps((t,)))
+ self.assertEquals(t2, t.__dict__)
+
def test_dump_big_long(self):
self.assertRaises(OverflowError, xmlrpclib.dumps, (2L**99,))
diff --git a/Lib/tokenize.py b/Lib/tokenize.py
index 5d65267..1253822 100644
--- a/Lib/tokenize.py
+++ b/Lib/tokenize.py
@@ -24,7 +24,7 @@ each time a new token is found."""
__author__ = 'Ka-Ping Yee <ping@lfw.org>'
__credits__ = \
- 'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro'
+ 'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro, Raymond Hettinger'
import string, re
from token import *
@@ -159,14 +159,73 @@ def tokenize_loop(readline, tokeneater):
for token_info in generate_tokens(readline):
tokeneater(*token_info)
+class Untokenizer:
+
+ def __init__(self):
+ self.tokens = []
+ self.prev_row = 1
+ self.prev_col = 0
+
+ def add_whitespace(self, start):
+ row, col = start
+ assert row <= self.prev_row
+ col_offset = col - self.prev_col
+ if col_offset:
+ self.tokens.append(" " * col_offset)
+
+ def untokenize(self, iterable):
+ for t in iterable:
+ if len(t) == 2:
+ self.compat(t, iterable)
+ break
+ tok_type, token, start, end, line = t
+ self.add_whitespace(start)
+ self.tokens.append(token)
+ self.prev_row, self.prev_col = end
+ if tok_type in (NEWLINE, NL):
+ self.prev_row += 1
+ self.prev_col = 0
+ return "".join(self.tokens)
+
+ def compat(self, token, iterable):
+ startline = False
+ indents = []
+ toks_append = self.tokens.append
+ toknum, tokval = token
+ if toknum in (NAME, NUMBER):
+ tokval += ' '
+ if toknum in (NEWLINE, NL):
+ startline = True
+ for tok in iterable:
+ toknum, tokval = tok[:2]
+
+ if toknum in (NAME, NUMBER):
+ tokval += ' '
+
+ if toknum == INDENT:
+ indents.append(tokval)
+ continue
+ elif toknum == DEDENT:
+ indents.pop()
+ continue
+ elif toknum in (NEWLINE, NL):
+ startline = True
+ elif startline and indents:
+ toks_append(indents[-1])
+ startline = False
+ toks_append(tokval)
def untokenize(iterable):
"""Transform tokens back into Python source code.
Each element returned by the iterable must be a token sequence
- with at least two elements, a token number and token value.
+ with at least two elements, a token number and token value. If
+ only two tokens are passed, the resulting output is poor.
+
+ Round-trip invariant for full input:
+ Untokenized source will match input source exactly
- Round-trip invariant:
+ Round-trip invariant for limited intput:
# Output text will tokenize the back to the input
t1 = [tok[:2] for tok in generate_tokens(f.readline)]
newcode = untokenize(t1)
@@ -174,31 +233,8 @@ def untokenize(iterable):
t2 = [tok[:2] for tokin generate_tokens(readline)]
assert t1 == t2
"""
-
- startline = False
- indents = []
- toks = []
- toks_append = toks.append
- for tok in iterable:
- toknum, tokval = tok[:2]
-
- if toknum in (NAME, NUMBER):
- tokval += ' '
-
- if toknum == INDENT:
- indents.append(tokval)
- continue
- elif toknum == DEDENT:
- indents.pop()
- continue
- elif toknum in (NEWLINE, COMMENT, NL):
- startline = True
- elif startline and indents:
- toks_append(indents[-1])
- startline = False
- toks_append(tokval)
- return ''.join(toks)
-
+ ut = Untokenizer()
+ return ut.untokenize(iterable)
def generate_tokens(readline):
"""
@@ -237,7 +273,7 @@ def generate_tokens(readline):
if endmatch:
pos = end = endmatch.end(0)
yield (STRING, contstr + line[:end],
- strstart, (lnum, end), contline + line)
+ strstart, (lnum, end), contline + line)
contstr, needcont = '', 0
contline = None
elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n':
@@ -263,7 +299,15 @@ def generate_tokens(readline):
if pos == max: break
if line[pos] in '#\r\n': # skip comments or blank lines
- yield ((NL, COMMENT)[line[pos] == '#'], line[pos:],
+ if line[pos] == '#':
+ comment_token = line[pos:].rstrip('\r\n')
+ nl_pos = pos + len(comment_token)
+ yield (COMMENT, comment_token,
+ (lnum, pos), (lnum, pos + len(comment_token)), line)
+ yield (NL, line[nl_pos:],
+ (lnum, nl_pos), (lnum, len(line)), line)
+ else:
+ yield ((NL, COMMENT)[line[pos] == '#'], line[pos:],
(lnum, pos), (lnum, len(line)), line)
continue
@@ -294,9 +338,10 @@ def generate_tokens(readline):
(initial == '.' and token != '.'): # ordinary number
yield (NUMBER, token, spos, epos, line)
elif initial in '\r\n':
- yield (parenlev > 0 and NL or NEWLINE,
- token, spos, epos, line)
+ yield (NL if parenlev > 0 else NEWLINE,
+ token, spos, epos, line)
elif initial == '#':
+ assert not token.endswith("\n")
yield (COMMENT, token, spos, epos, line)
elif token in triple_quoted:
endprog = endprogs[token]
diff --git a/Lib/traceback.py b/Lib/traceback.py
index eb2fdf6..e395ad7 100644
--- a/Lib/traceback.py
+++ b/Lib/traceback.py
@@ -162,6 +162,11 @@ def format_exception_only(etype, value):
"""
+ # Gracefully handle (the way Python 2.4 and earlier did) the case of
+ # being called with (None, None).
+ if etype is None:
+ return [_format_final_exc_line(etype, value)]
+
stype = etype.__name__
smod = etype.__module__
if smod not in ("exceptions", "__main__", "__builtin__"):
diff --git a/Lib/urllib.py b/Lib/urllib.py
index e01f421..90f7aa0 100644
--- a/Lib/urllib.py
+++ b/Lib/urllib.py
@@ -302,13 +302,13 @@ class URLopener:
if proxy_passwd:
import base64
- proxy_auth = base64.encodestring(proxy_passwd).strip()
+ proxy_auth = base64.b64encode(proxy_passwd).strip()
else:
proxy_auth = None
if user_passwd:
import base64
- auth = base64.encodestring(user_passwd).strip()
+ auth = base64.b64encode(user_passwd).strip()
else:
auth = None
h = httplib.HTTP(host)
@@ -387,12 +387,12 @@ class URLopener:
if not host: raise IOError, ('https error', 'no host given')
if proxy_passwd:
import base64
- proxy_auth = base64.encodestring(proxy_passwd).strip()
+ proxy_auth = base64.b64encode(proxy_passwd).strip()
else:
proxy_auth = None
if user_passwd:
import base64
- auth = base64.encodestring(user_passwd).strip()
+ auth = base64.b64encode(user_passwd).strip()
else:
auth = None
h = httplib.HTTPS(host, 0,
diff --git a/Lib/urllib2.py b/Lib/urllib2.py
index 1e19f33..a880e64 100644
--- a/Lib/urllib2.py
+++ b/Lib/urllib2.py
@@ -674,7 +674,7 @@ class ProxyHandler(BaseHandler):
proxy_type = orig_type
if user and password:
user_pass = '%s:%s' % (unquote(user), unquote(password))
- creds = base64.encodestring(user_pass).strip()
+ creds = base64.b64encode(user_pass).strip()
req.add_header('Proxy-authorization', 'Basic ' + creds)
hostport = unquote(hostport)
req.set_proxy(hostport, proxy_type)
@@ -798,7 +798,7 @@ class AbstractBasicAuthHandler:
user, pw = self.passwd.find_user_password(realm, host)
if pw is not None:
raw = "%s:%s" % (user, pw)
- auth = 'Basic %s' % base64.encodestring(raw).strip()
+ auth = 'Basic %s' % base64.b64encode(raw).strip()
if req.headers.get(self.auth_header, None) == auth:
return None
req.add_header(self.auth_header, auth)
diff --git a/Lib/uu.py b/Lib/uu.py
index 3ccedb0..da89f72 100755
--- a/Lib/uu.py
+++ b/Lib/uu.py
@@ -114,6 +114,7 @@ def decode(in_file, out_file=None, mode=None, quiet=0):
#
# Open the output file
#
+ opened = False
if out_file == '-':
out_file = sys.stdout
elif isinstance(out_file, basestring):
@@ -123,6 +124,7 @@ def decode(in_file, out_file=None, mode=None, quiet=0):
except AttributeError:
pass
out_file = fp
+ opened = True
#
# Main decoding loop
#
@@ -140,6 +142,8 @@ def decode(in_file, out_file=None, mode=None, quiet=0):
s = in_file.readline()
if not s:
raise Error('Truncated input file')
+ if opened:
+ out_file.close()
def test():
"""uuencode/uudecode main program"""
diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py
index 9fd1615..0d5f44f 100644
--- a/Lib/webbrowser.py
+++ b/Lib/webbrowser.py
@@ -165,7 +165,10 @@ class GenericBrowser(BaseBrowser):
cmdline = [self.name] + [arg.replace("%s", url)
for arg in self.args]
try:
- p = subprocess.Popen(cmdline, close_fds=True)
+ if sys.platform[:3] == 'win':
+ p = subprocess.Popen(cmdline)
+ else:
+ p = subprocess.Popen(cmdline, close_fds=True)
return not p.wait()
except OSError:
return False
@@ -178,11 +181,14 @@ class BackgroundBrowser(GenericBrowser):
def open(self, url, new=0, autoraise=1):
cmdline = [self.name] + [arg.replace("%s", url)
for arg in self.args]
- setsid = getattr(os, 'setsid', None)
- if not setsid:
- setsid = getattr(os, 'setpgrp', None)
try:
- p = subprocess.Popen(cmdline, close_fds=True, preexec_fn=setsid)
+ if sys.platform[:3] == 'win':
+ p = subprocess.Popen(cmdline)
+ else:
+ setsid = getattr(os, 'setsid', None)
+ if not setsid:
+ setsid = getattr(os, 'setpgrp', None)
+ p = subprocess.Popen(cmdline, close_fds=True, preexec_fn=setsid)
return (p.poll() is None)
except OSError:
return False
@@ -441,7 +447,7 @@ def register_X_browsers():
# if successful, register it
if retncode is None and commd:
- register("gnome", None, BackgroundBrowser(commd))
+ register("gnome", None, BackgroundBrowser(commd.split()))
# First, the Mozilla/Netscape browsers
for browser in ("mozilla-firefox", "firefox",
diff --git a/Lib/xdrlib.py b/Lib/xdrlib.py
index b349eb9..796dfaf 100644
--- a/Lib/xdrlib.py
+++ b/Lib/xdrlib.py
@@ -227,61 +227,3 @@ class Unpacker:
def unpack_array(self, unpack_item):
n = self.unpack_uint()
return self.unpack_farray(n, unpack_item)
-
-
-# test suite
-def _test():
- p = Packer()
- packtest = [
- (p.pack_uint, (9,)),
- (p.pack_bool, (True,)),
- (p.pack_bool, (False,)),
- (p.pack_uhyper, (45L,)),
- (p.pack_float, (1.9,)),
- (p.pack_double, (1.9,)),
- (p.pack_string, ('hello world',)),
- (p.pack_list, (range(5), p.pack_uint)),
- (p.pack_array, (['what', 'is', 'hapnin', 'doctor'], p.pack_string)),
- ]
- succeedlist = [1] * len(packtest)
- count = 0
- for method, args in packtest:
- print 'pack test', count,
- try:
- method(*args)
- print 'succeeded'
- except ConversionError, var:
- print 'ConversionError:', var.msg
- succeedlist[count] = 0
- count = count + 1
- data = p.get_buffer()
- # now verify
- up = Unpacker(data)
- unpacktest = [
- (up.unpack_uint, (), lambda x: x == 9),
- (up.unpack_bool, (), lambda x: x is True),
- (up.unpack_bool, (), lambda x: x is False),
- (up.unpack_uhyper, (), lambda x: x == 45L),
- (up.unpack_float, (), lambda x: 1.89 < x < 1.91),
- (up.unpack_double, (), lambda x: 1.89 < x < 1.91),
- (up.unpack_string, (), lambda x: x == 'hello world'),
- (up.unpack_list, (up.unpack_uint,), lambda x: x == range(5)),
- (up.unpack_array, (up.unpack_string,),
- lambda x: x == ['what', 'is', 'hapnin', 'doctor']),
- ]
- count = 0
- for method, args, pred in unpacktest:
- print 'unpack test', count,
- try:
- if succeedlist[count]:
- x = method(*args)
- print pred(x) and 'succeeded' or 'failed', ':', x
- else:
- print 'skipping'
- except ConversionError, var:
- print 'ConversionError:', var.msg
- count = count + 1
-
-
-if __name__ == '__main__':
- _test()
diff --git a/Lib/xmlrpclib.py b/Lib/xmlrpclib.py
index 72866f1..da3d396 100644
--- a/Lib/xmlrpclib.py
+++ b/Lib/xmlrpclib.py
@@ -593,9 +593,21 @@ class Marshaller:
try:
f = self.dispatch[type(value)]
except KeyError:
- raise TypeError, "cannot marshal %s objects" % type(value)
- else:
- f(self, value, write)
+ # check if this object can be marshalled as a structure
+ try:
+ value.__dict__
+ except:
+ raise TypeError, "cannot marshal %s objects" % type(value)
+ # check if this class is a sub-class of a basic type,
+ # because we don't know how to marshal these types
+ # (e.g. a string sub-class)
+ for type_ in type(value).__mro__:
+ if type_ in self.dispatch.keys():
+ raise TypeError, "cannot marshal %s objects" % type(value)
+ # XXX(twouters): using "_arbitrary_instance" as key as a quick-fix
+ # for the p3yk merge, this should probably be fixed more neatly.
+ f = self.dispatch["_arbitrary_instance"]
+ f(self, value, write)
def dump_nil (self, value, write):
if not self.allow_none:
@@ -713,6 +725,9 @@ class Marshaller:
self.dump_struct(value.__dict__, write)
dispatch[DateTime] = dump_instance
dispatch[Binary] = dump_instance
+ # XXX(twouters): using "_arbitrary_instance" as key as a quick-fix
+ # for the p3yk merge, this should probably be fixed more neatly.
+ dispatch["_arbitrary_instance"] = dump_instance
##
# XML-RPC unmarshaller.