diff --git a/Doc/ACKS.txt b/Doc/ACKS.txt index fc3789fea31..07abc6be88c 100644 --- a/Doc/ACKS.txt +++ b/Doc/ACKS.txt @@ -48,6 +48,7 @@ docs@python.org), and we'll be glad to correct the problem. * Carey Evans * Martijn Faassen * Carl Feynman +* Dan Finnie * Hernán Martínez Foffani * Stefan Franke * Jim Fulton diff --git a/Doc/c-api/refcounting.rst b/Doc/c-api/refcounting.rst index e75ff73e740..c0f4ca12dc1 100644 --- a/Doc/c-api/refcounting.rst +++ b/Doc/c-api/refcounting.rst @@ -63,9 +63,9 @@ objects. The following functions are for runtime dynamic embedding of Python: -``Py_IncRef(PyObject \*o)``, `Py_DecRef(PyObject \*o)``. They are simply -exported function versions of :cfunc:`Py_XINCREF` and :cfunc:`Py_XDECREF`, -respectively. +``Py_IncRef(PyObject *o)``, ``Py_DecRef(PyObject *o)``. They are +simply exported function versions of :cfunc:`Py_XINCREF` and +:cfunc:`Py_XDECREF`, respectively. The following functions or macros are only for use within the interpreter core: :cfunc:`_Py_Dealloc`, :cfunc:`_Py_ForgetReference`, :cfunc:`_Py_NewReference`, diff --git a/Doc/documenting/fromlatex.rst b/Doc/documenting/fromlatex.rst index 67abe8a2483..42045f7daf0 100644 --- a/Doc/documenting/fromlatex.rst +++ b/Doc/documenting/fromlatex.rst @@ -183,8 +183,8 @@ directories renamed as follows: * :file:`ext` -> :file:`extending` * :file:`inst` -> :file:`installing` * :file:`lib` -> :file:`library` -* :file:`mac` -> merged into :file:`library`, with `mac/using.tex` - moved to `howto/pythonmac.rst` +* :file:`mac` -> merged into :file:`library`, with :file:`mac/using.tex` + moved to :file:`howto/pythonmac.rst` * :file:`ref` -> :file:`reference` * :file:`tut` -> :file:`tutorial`, with the single TeX file split up diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index bcda1bda16a..678d4d70a02 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -43,8 +43,6 @@ using the :class:`DictReader` and :class:`DictWriter` classes. .. seealso:: - .. % \seemodule{array}{Arrays of uniformly types numeric values.} - :pep:`305` - CSV File API The Python Enhancement Proposal which proposed this addition to Python. @@ -83,6 +81,15 @@ The :mod:`csv` module defines the following functions: consequence, if newlines embedded within fields are important, the input should be split into lines in a manner which preserves the newline characters. + A short usage example:: + + >>> import csv + >>> spamReader = csv.reader(open('eggs.csv'), delimiter=' ', quotechar='|') + >>> for row in spamReader: + ... print ', '.join(row) + Spam, Spam, Spam, Spam, Spam, Baked Beans + Spam, Lovely Spam, Wonderful Spam + .. function:: writer(csvfile[, dialect='excel'][, fmtparam]) @@ -103,6 +110,14 @@ The :mod:`csv` module defines the following functions: CSV files without preprocessing the data returned from a ``cursor.fetch*`` call. All other non-string data are stringified with :func:`str` before being written. + A short usage example:: + + >>> import csv + >>> spamWriter = csv.writer(open('eggs.csv', 'w'), delimiter=' ', + ... quotechar='|', quoting=QUOTE_MINIMAL) + >>> spamWriter.writerow(['Spam'] * 5 + ['Baked Beans']) + >>> spamWriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam']) + .. function:: register_dialect(name[, dialect][, fmtparam]) diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst index d00caba4e33..2e4f3f22e46 100644 --- a/Doc/library/pprint.rst +++ b/Doc/library/pprint.rst @@ -45,30 +45,23 @@ The :mod:`pprint` module defines one class: structure cannot be formatted within the constrained width, a best effort will be made. :: - >>> import pprint, sys - >>> stuff = sys.path[:] + >>> import pprint + >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni'] >>> stuff.insert(0, stuff[:]) >>> pp = pprint.PrettyPrinter(indent=4) >>> pp.pprint(stuff) - [ [ '', - '/usr/local/lib/python1.5', - '/usr/local/lib/python1.5/test', - '/usr/local/lib/python1.5/sunos5', - '/usr/local/lib/python1.5/sharedmodules', - '/usr/local/lib/python1.5/tkinter'], - '', - '/usr/local/lib/python1.5', - '/usr/local/lib/python1.5/test', - '/usr/local/lib/python1.5/sunos5', - '/usr/local/lib/python1.5/sharedmodules', - '/usr/local/lib/python1.5/tkinter'] - >>> - >>> import parser - >>> tup = parser.ast2tuple( - ... parser.suite(open('pprint.py').read()))[1][1][1] + [ ['spam', 'eggs', 'lumberjack', 'knights', 'ni'], + 'spam', + 'eggs', + 'lumberjack', + 'knights', + 'ni'] + >>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', + ... ('parrot', ('fresh fruit',)))))))) >>> pp = pprint.PrettyPrinter(depth=6) >>> pp.pprint(tup) - (266, (267, (307, (287, (288, (...)))))) + ('spam', + ('eggs', ('lumberjack', ('knights', ('ni', ('dead', ('parrot', (...,)))))))) The :class:`PrettyPrinter` class supports several derivative functions: @@ -91,7 +84,8 @@ The :class:`PrettyPrinter` class supports several derivative functions: within a scope). *indent*, *width* and *depth* will be passed to the :class:`PrettyPrinter` constructor as formatting parameters. :: - >>> stuff = sys.path[:] + >>> import pprint + >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni'] >>> stuff.insert(0, stuff) >>> pprint.pprint(stuff) [, @@ -200,3 +194,40 @@ are converted to strings. The default implementation uses the internals of the is no requested limit. This argument should be passed unmodified to recursive calls. The fourth argument, *level*, gives the current level; recursive calls should be passed a value less than that of the current call. + + +.. _pprint-example: + +pprint Example +-------------- + +This example demonstrates several uses of the :func:`pprint` function and its parameters. + + >>> import pprint + >>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', + ... ('parrot', ('fresh fruit',)))))))) + >>> stuff = ['a' * 10, tup, ['a' * 30, 'b' * 30], ['c' * 20, 'd' * 20]] + >>> pprint.pprint(stuff) + ['aaaaaaaaaa', + ('spam', + ('eggs', + ('lumberjack', + ('knights', ('ni', ('dead', ('parrot', ('fresh fruit',)))))))), + ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'], + ['cccccccccccccccccccc', 'dddddddddddddddddddd']] + >>> pprint.pprint(stuff, depth=3) + ['aaaaaaaaaa', + ('spam', ('eggs', ('lumberjack', (...)))), + ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'], + ['cccccccccccccccccccc', 'dddddddddddddddddddd']] + >>> pprint.pprint(stuff, width=60) + ['aaaaaaaaaa', + ('spam', + ('eggs', + ('lumberjack', + ('knights', + ('ni', ('dead', ('parrot', ('fresh fruit',)))))))), + ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'], + ['cccccccccccccccccccc', 'dddddddddddddddddddd']] + diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 2d9fa328b5c..17da18eb1c9 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -31,6 +31,11 @@ prefixed with ``'r'``. So ``r"\n"`` is a two-character string containing newline. Usually patterns will be expressed in Python code using this raw string notation. +It is important to note that most regular expression operations are available as +module-level functions and :class:`RegexObject` methods. The functions are +shortcuts that don't require you to compile a regex object first, but miss some +fine-tuning parameters. + .. seealso:: Mastering Regular Expressions @@ -407,11 +412,9 @@ argument regardless of whether a newline precedes it. :: - re.compile("a").match("ba", 1) # succeeds - re.compile("^a").search("ba", 1) # fails; 'a' not at start - re.compile("^a").search("\na", 1) # fails; 'a' not at start - re.compile("^a", re.M).search("\na", 1) # succeeds - re.compile("^a", re.M).search("ba", 1) # fails; no preceding \n + >>> re.match("c", "abcdef") # No match + >>> re.search("c", "abcdef") + <_sre.SRE_Match object at 0x827e9c0> # Match .. _contents-of-module-re: @@ -501,12 +504,13 @@ form. character class or preceded by an unescaped backslash, all characters from the leftmost such ``'#'`` through the end of the line are ignored. - This means that the two following regular expression objects are equal:: + That means that the two following regular expression objects that match a + decimal number are functionally equal:: - re.compile(r""" [a-z]+ # some letters - \.\. # two dots - [a-z]* # perhaps more letters""") - re.compile(r"[a-z]+\.\.[a-z]*") + a = re.compile(r"""\d + # the integral part + \. # the decimal point + \d * # some fractional digits""", re.X) + b = re.compile(r"\d+\.\d*") .. function:: search(pattern, string[, flags]) @@ -527,7 +531,8 @@ form. .. note:: - If you want to locate a match anywhere in *string*, use :meth:`search` instead. + If you want to locate a match anywhere in *string*, use :meth:`search` + instead. .. function:: split(pattern, string[, maxsplit=0]) @@ -655,7 +660,8 @@ attributes: .. note:: - If you want to locate a match anywhere in *string*, use :meth:`search` instead. + If you want to locate a match anywhere in *string*, use :meth:`search` + instead. The optional second parameter *pos* gives an index in the string where the search is to start; it defaults to ``0``. This is not completely equivalent to @@ -668,7 +674,12 @@ attributes: from *pos* to ``endpos - 1`` will be searched for a match. If *endpos* is less than *pos*, no match will be found, otherwise, if *rx* is a compiled regular expression object, ``rx.match(string, 0, 50)`` is equivalent to - ``rx.match(string[:50], 0)``. + ``rx.match(string[:50], 0)``. :: + + >>> pattern = re.compile("o") + >>> pattern.match("dog") # No match as "o" is not at the start of "dog." + >>> pattern.match("dog", 1) # Match as "o" is the 2nd character of "dog". + <_sre.SRE_Match object at 0x827eb10> .. method:: RegexObject.search(string[, pos[, endpos]]) @@ -756,7 +767,17 @@ support the following methods and attributes: pattern, an :exc:`IndexError` exception is raised. If a group is contained in a part of the pattern that did not match, the corresponding result is ``None``. If a group is contained in a part of the pattern that matched multiple times, - the last match is returned. + the last match is returned. :: + + >>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist") + >>> m.group(0) + 'Isaac Newton' # The entire match + >>> m.group(1) + 'Isaac' # The first parenthesized subgroup. + >>> m.group(2) + 'Newton' # The second parenthesized subgroup. + >>> m.group(1, 2) + ('Isaac', 'Newton') # Multiple arguments give us a tuple. If the regular expression uses the ``(?P...)`` syntax, the *groupN* arguments may also be strings identifying groups by their group name. If a @@ -765,10 +786,23 @@ support the following methods and attributes: A moderately complicated example:: - m = re.match(r"(?P\d+)\.(\d*)", '3.14') + >>> m = re.match(r"(?P\w+) (?P\w+)", "Malcom Reynolds") + >>> m.group('first_name') + 'Malcom' + >>> m.group('last_name') + 'Reynolds' - After performing this match, ``m.group(1)`` is ``'3'``, as is - ``m.group('int')``, and ``m.group(2)`` is ``'14'``. + Named groups can also be referred to by their index:: + + >>> m.group(1) + 'Malcom' + >>> m.group(2) + 'Reynolds' + + If a group matches multiple times, only the last match is accessible:: + >>> m = re.match(r"(..)+", "a1b2c3") # Matches 3 times. + >>> m.group(1) # Returns only the last match. + 'c3' .. method:: MatchObject.groups([default]) @@ -780,12 +814,32 @@ support the following methods and attributes: string would be returned instead. In later versions (from 1.5.1 on), a singleton tuple is returned in such cases.) + For example:: + + >>> m = re.match(r"(\d+)\.(\d+)", "24.1632") + >>> m.groups() + ('24', '1632') + + If we make the decimal place and everything after it optional, not all groups + might participate in the match. These groups will default to ``None`` unless + the *default* argument is given:: + + >>> m = re.match(r"(\d+)\.?(\d+)?", "24") + >>> m.groups() + ('24', None) # Second group defaults to None. + >>> m.groups('0') + ('24', '0') # Now, the second group defaults to '0'. + .. method:: MatchObject.groupdict([default]) Return a dictionary containing all the *named* subgroups of the match, keyed by the subgroup name. The *default* argument is used for groups that did not - participate in the match; it defaults to ``None``. + participate in the match; it defaults to ``None``. For example:: + + >>> m = re.match(r"(?P\w+) (?P\w+)", "Malcom Reynolds") + >>> m.groupdict() + {'first_name': 'Malcom', 'last_name': 'Reynolds'} .. method:: MatchObject.start([group]) @@ -804,12 +858,19 @@ support the following methods and attributes: ``m.start(0)`` is 1, ``m.end(0)`` is 2, ``m.start(1)`` and ``m.end(1)`` are both 2, and ``m.start(2)`` raises an :exc:`IndexError` exception. + An example that will remove *remove_this* from email addresses:: + + >>> email = "tony@tiremove_thisger.net" + >>> m = re.search("remove_this", email) + >>> email[:m.start()] + email[m.end():] + 'tony@tiger.net' + .. method:: MatchObject.span([group]) For :class:`MatchObject` *m*, return the 2-tuple ``(m.start(group), m.end(group))``. Note that if *group* did not contribute to the match, this is - ``(-1, -1)``. Again, *group* defaults to zero. + ``(-1, -1)``. *group* defaults to zero, the entire match. .. attribute:: MatchObject.pos @@ -855,7 +916,62 @@ support the following methods and attributes: Examples -------- -**Simulating scanf()** + +Checking For a Pair +^^^^^^^^^^^^^^^^^^^ + +In this example, we'll use the following helper function to display match +objects a little more gracefully:: + + def displaymatch(match): + if match is None: + return None + return '' % (match.group(), match.groups()) + +Suppose you are writing a poker program where a player's hand is represented as +a 5-character string with each character representing a card, "a" for ace, "k" +for king, "q" for queen, j for jack, "0" for 10, and "1" through "9" +representing the card with that value. + +To see if a given string is a valid hand, one could do the following:: + + >>> valid = re.compile(r"[0-9akqj]{5}$" + >>> displaymatch(valid.match("ak05q")) # Valid. + + >>> displaymatch(valid.match("ak05e")) # Invalid. + >>> displaymatch(valid.match("ak0")) # Invalid. + >>> displaymatch(valid.match("727ak")) # Valid. + + +That last hand, ``"727ak"``, contained a pair, or two of the same valued cards. +To match this with a regular expression, one could use backreferences as such:: + + >>> pair = re.compile(r".*(.).*\1") + >>> displaymatch(pair.match("717ak")) # Pair of 7s. + + >>> displaymatch(pair.match("718ak")) # No pairs. + >>> displaymatch(pair.match("354aa")) # Pair of aces. + + +To find out what card the pair consists of, one could use the :func:`group` +method of :class:`MatchObject` in the following manner:: + + >>> pair.match("717ak").group(1) + '7' + + # Error because re.match() returns None, which doesn't have a group() method: + >>> pair.match("718ak").group(1) + Traceback (most recent call last): + File "", line 1, in + re.match(r".*(.).*\1", "718ak").group(1) + AttributeError: 'NoneType' object has no attribute 'group' + + >>> pair.match("354aa").group(1) + 'a' + + +Simulating scanf() +^^^^^^^^^^^^^^^^^^ .. index:: single: scanf() @@ -899,7 +1015,9 @@ The equivalent regular expression would be :: (\S+) - (\d+) errors, (\d+) warnings -**Avoiding recursion** + +Avoiding recursion +^^^^^^^^^^^^^^^^^^ If you create regular expressions that require the engine to perform a lot of recursion, you may encounter a :exc:`RuntimeError` exception with the message @@ -921,3 +1039,148 @@ avoid recursion. Thus, the above regular expression can avoid recursion by being recast as ``Begin [a-zA-Z0-9_ ]*?end``. As a further benefit, such regular expressions will run faster than their recursive equivalents. + +search() vs. match() +^^^^^^^^^^^^^^^^^^^^ + +In a nutshell, :func:`match` only attempts to match a pattern at the beginning +of a string where :func:`search` will match a pattern anywhere in a string. +For example:: + + >>> re.match("o", "dog") # No match as "o" is not the first letter of "dog". + >>> re.search("o", "dog") # Match as search() looks everywhere in the string. + <_sre.SRE_Match object at 0x827e9f8> + +.. note:: + + The following applies only to regular expression objects like those created + with ``re.compile("pattern")``, not the primitives + ``re.match(pattern, string)`` or ``re.search(pattern, string)``. + +:func:`match` has an optional second parameter that gives an index in the string +where the search is to start:: + + >>> pattern = re.compile("o") + >>> pattern.match("dog") # No match as "o" is not at the start of "dog." + # Equivalent to the above expression as 0 is the default starting index: + >>> pattern.match("dog", 0) + # Match as "o" is the 2nd character of "dog" (index 0 is the first): + >>> pattern.match("dog", 1) + <_sre.SRE_Match object at 0x827eb10> + >>> pattern.match("dog", 2) # No match as "o" is not the 3rd character of "dog." + + +Making a Phonebook +^^^^^^^^^^^^^^^^^^ + +:func:`split` splits a string into a list delimited by the passed pattern. The +method is invaluable for converting textual data into data structures that can be +easily read and modified by Python as demonstrated in the following example that +creates a phonebook. + +First, get the input using triple-quoted string syntax:: + + >>> input = """Ross McFluff 834.345.1254 155 Elm Street + Ronald Heathmore 892.345.3428 436 Finley Avenue + Frank Burger 925.541.7625 662 South Dogwood Way + Heather Albrecht 548.326.4584 919 Park Place""" + +Then, convert the string into a list with each line having its own entry:: + + >>> entries = re.split("\n", input) + >>> entries + ['Ross McFluff 834.345.1254 155 Elm Street', + 'Ronald Heathmore 892.345.3428 436 Finley Avenue', + 'Frank Burger 925.541.7625 662 South Dogwood Way', + 'Heather Albrecht 548.326.4584 919 Park Place'] + +Finally, split each entry into a list with first name, last name, telephone +number, and address. We use the ``maxsplit`` paramater of :func:`split` +because the address has spaces, our splitting pattern, in it:: + + >>> [re.split(" ", entry, 3) for entry in entries] + [['Ross', 'McFluff', '834.345.1254', '155 Elm Street'], + ['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'], + ['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'], + ['Heather', 'Albrecht', '548.326.4584', '919 Park Place']] + +With a ``maxsplit`` of ``4``, we could seperate the house number from the street +name:: + + >>> [re.split(" ", entry, 4) for entry in entries] + [['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'], + ['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'], + ['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'], + ['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']] + + +Text Munging +^^^^^^^^^^^^ + +:func:`sub` replaces every occurrence of a pattern with a string or the +result of a function. This example demonstrates using :func:`sub` with +a function to "munge" text, or randomize the order of all the characters +in each word of a sentence except for the first and last characters:: + + >>> def repl(m): + ... inner_word = list(m.group(2)) + ... random.shuffle(inner_word) + ... return m.group(1) + "".join(inner_word) + m.group(3) + >>> text = "Professor Abdolmalek, please report your absences promptly." + >>> re.sub("(\w)(\w+)(\w)", repl, text) + 'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.' + >>> re.sub("(\w)(\w+)(\w)", repl, text) + 'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.' + + +Finding all Adverbs +^^^^^^^^^^^^^^^^^^^ + +:func:`findall` matches *all* occurences of a pattern, not just the first +one as :func:`search` does. For example, if one was a writer and wanted to +find all of the adverbs in some text, he or she might use :func:`findall` in +the following manner:: + + >>> text = "He was carefully disguised but captured quickly by police." + >>> re.findall(r"\w+ly", text) + ['carefully', 'quickly'] + + +Finding all Adverbs and their Positions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If one wants more information about all matches of a pattern than the matched +text, :func:`finditer` is useful as it provides instances of +:class:`MatchObject` instead of strings. Continuing with the previous example, +if one was a writer who wanted to find all of the adverbs *and their positions* +in some text, he or she would use :func:`finditer` in the following manner:: + + >>> text = "He was carefully disguised but captured quickly by police." + >>> for m in re.finditer(r"\w+ly", text): + print '%02d-%02d: %s' % (m.start(), m.end(), m.group(0)) + 07-16: carefully + 40-47: quickly + + +Raw String Notation +^^^^^^^^^^^^^^^^^^^ + +Raw string notation (``r"text"``) keeps regular expressions sane. Without it, +every backslash (``'\'``) in a regular expression would have to be prefixed with +another one to escape it. For example, the two following lines of code are +functionally identical:: + + >>> re.match(r"\W(.)\1\W", " ff ") + <_sre.SRE_Match object at 0x8262760> + >>> re.match("\\W(.)\\1\\W", " ff ") + <_sre.SRE_Match object at 0x82627a0> + +When one wants to match a literal backslash, it must be escaped in the regular +expression. With raw string notation, this means ``r"\\"``. Without raw string +notation, one must use ``"\\\\"``, making the following lines of code +functionally identical:: + + >>> re.match(r"\\", r"\\") + <_sre.SRE_Match object at 0x827eb48> + >>> re.match("\\\\", r"\\") + <_sre.SRE_Match object at 0x827ec60> diff --git a/Doc/library/traceback.rst b/Doc/library/traceback.rst index ca8aea3b484..179e04eea97 100644 --- a/Doc/library/traceback.rst +++ b/Doc/library/traceback.rst @@ -132,8 +132,8 @@ The module defines the following functions: .. _traceback-example: -Traceback Example ------------------ +Traceback Examples +------------------ This simple example implements a basic read-eval-print loop, similar to (but less useful than) the standard Python interactive interpreter loop. For a more @@ -156,3 +156,124 @@ module. :: while True: run_user_code(envdir) + +The following example demonstrates the different ways to print and format the +exception and traceback:: + + import sys, traceback + + def lumberjack(): + bright_side_of_death() + + def bright_side_of_death(): + return tuple()[0] + + try: + lumberjack() + except: + exceptionType, exceptionValue, exceptionTraceback = sys.exc_info() + print "*** print_tb:" + traceback.print_tb(exceptionTraceback, limit=1, file=sys.stdout) + print "*** print_exception:" + traceback.print_exception(exceptionType, exceptionValue, exceptionTraceback, + limit=2, file=sys.stdout) + print "*** print_exc:" + traceback.print_exc() + print "*** format_exc, first and last line:" + formatted_lines = traceback.format_exc().splitlines() + print formatted_lines[0] + print formatted_lines[-1] + print "*** format_exception:" + print repr(traceback.format_exception(exceptionType, exceptionValue, + exceptionTraceback)) + print "*** extract_tb:" + print repr(traceback.extract_tb(exceptionTraceback)) + print "*** format_tb:" + print repr(traceback.format_tb(exceptionTraceback)) + print "*** tb_lineno:", traceback.tb_lineno(exceptionTraceback) + print "*** print_last:" + traceback.print_last() + + +The output for the example would look similar to this:: + + *** print_tb: + File "", line 9, in + lumberjack() + *** print_exception: + Traceback (most recent call last): + File "", line 9, in + lumberjack() + File "", line 3, in lumberjack + bright_side_of_death() + IndexError: tuple index out of range + *** print_exc: + Traceback (most recent call last): + File "", line 9, in + lumberjack() + File "", line 3, in lumberjack + bright_side_of_death() + IndexError: tuple index out of range + *** format_exc, first and last line: + Traceback (most recent call last): + IndexError: tuple index out of range + *** format_exception: + ['Traceback (most recent call last):\n', + ' File "", line 9, in \n lumberjack()\n', + ' File "", line 3, in lumberjack\n bright_side_of_death()\n', + ' File "", line 6, in bright_side_of_death\n return tuple()[0]\n', + 'IndexError: tuple index out of range\n'] + *** extract_tb: + [('', 9, '', 'lumberjack()'), + ('', 3, 'lumberjack', 'bright_side_of_death()'), + ('', 6, 'bright_side_of_death', 'return tuple()[0]')] + *** format_tb: + [' File "", line 9, in \n lumberjack()\n', + ' File "", line 3, in lumberjack\n bright_side_of_death()\n', + ' File "", line 6, in bright_side_of_death\n return tuple()[0]\n'] + *** tb_lineno: 2 + *** print_last: + Traceback (most recent call last): + File "", line 9, in + lumberjack() + File "", line 3, in lumberjack + bright_side_of_death() + IndexError: tuple index out of range + + +The following example shows the different ways to print and format the stack:: + + >>> import traceback + >>> def another_function(): + ... lumberstack() + ... + >>> def lumberstack(): + ... traceback.print_stack() + ... print repr(traceback.extract_stack()) + ... print repr(traceback.format_stack()) + ... + >>> another_function() + File "", line 10, in + another_function() + File "", line 3, in another_function + lumberstack() + File "", line 6, in lumberstack + traceback.print_stack() + [('', 10, '', 'another_function()'), + ('', 3, 'another_function', 'lumberstack()'), + ('', 7, 'lumberstack', 'print repr(traceback.extract_stack())')] + [' File "", line 10, in \n another_function()\n', + ' File "", line 3, in another_function\n lumberstack()\n', + ' File "", line 8, in lumberstack\n print repr(traceback.format_stack())\n'] + + +This last example demonstrates the final few formatting functions:: + + >>> import traceback + >>> format_list([('spam.py', 3, '', 'spam.eggs()'), + ... ('eggs.py', 42, 'eggs', 'return "bacon"')]) + [' File "spam.py", line 3, in \n spam.eggs()\n', + ' File "eggs.py", line 42, in eggs\n return "bacon"\n'] + >>> theError = IndexError('tuple indx out of range') + >>> traceback.format_exception_only(type(theError), theError) + ['IndexError: tuple index out of range\n'] diff --git a/Lib/collections.py b/Lib/collections.py index a553c9f04f0..f5c524b25a8 100644 --- a/Lib/collections.py +++ b/Lib/collections.py @@ -40,7 +40,7 @@ def namedtuple(typename, field_names, verbose=False): field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas field_names = tuple(field_names) for name in (typename,) + field_names: - if not name.replace('_', '').isalnum(): + if not all(c.isalnum() or c=='_' for c in name): raise ValueError('Type names and field names can only contain alphanumeric characters and underscores: %r' % name) if _iskeyword(name): raise ValueError('Type names and field names cannot be a keyword: %r' % name) @@ -48,7 +48,7 @@ def namedtuple(typename, field_names, verbose=False): raise ValueError('Type names and field names cannot start with a number: %r' % name) seen_names = set() for name in field_names: - if name.startswith('__') and name.endswith('__'): + if name.startswith('__') and name.endswith('__') and len(name) > 3: raise ValueError('Field names cannot start and end with double underscores: %r' % name) if name in seen_names: raise ValueError('Encountered duplicate field name: %r' % name) diff --git a/Lib/distutils/msvc9compiler.py b/Lib/distutils/msvc9compiler.py index a6cff2c04e7..828d7fbf7a1 100644 --- a/Lib/distutils/msvc9compiler.py +++ b/Lib/distutils/msvc9compiler.py @@ -254,10 +254,13 @@ def query_vcvarsall(version, arch="x86"): popen = subprocess.Popen('"%s" %s & set' % (vcvarsall, arch), stdout=subprocess.PIPE, stderr=subprocess.PIPE) - if popen.wait() != 0: - raise IOError(popen.stderr.read()) - for line in popen.stdout: + stdout, stderr = popen.communicate() + if popen.wait() != 0: + raise IOError(stderr.decode("mbcs")) + + stdout = stdout.decode("mbcs") + for line in stdout.split("\n"): line = Reg.convert_mbcs(line) if '=' not in line: continue diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 62da9c5c3fe..45b408223f5 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -32,6 +32,7 @@ class TestNamedTuple(unittest.TestCase): self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names + namedtuple('_', '_ __ ___') # Verify that underscores are allowed def test_instance(self): Point = namedtuple('Point', 'x y') diff --git a/Mac/Modules/osa/_OSAmodule.c b/Mac/Modules/osa/_OSAmodule.c index 45be617a4c2..6351e1cbc49 100644 --- a/Mac/Modules/osa/_OSAmodule.c +++ b/Mac/Modules/osa/_OSAmodule.c @@ -726,314 +726,6 @@ static PyObject *OSAObj_OSAMakeContext(OSAComponentInstanceObject *_self, PyObje return _res; } -static PyObject *OSAObj_OSADebuggerCreateSession(OSAComponentInstanceObject *_self, PyObject *_args) -{ - PyObject *_res = NULL; - OSAError _err; - OSAID inScript; - OSAID inContext; - OSADebugSessionRef outSession; -#ifndef OSADebuggerCreateSession - PyMac_PRECHECK(OSADebuggerCreateSession); -#endif - if (!PyArg_ParseTuple(_args, "ll", - &inScript, - &inContext)) - return NULL; - _err = OSADebuggerCreateSession(_self->ob_itself, - inScript, - inContext, - &outSession); - if (_err != noErr) return PyMac_Error(_err); - _res = Py_BuildValue("l", - outSession); - return _res; -} - -static PyObject *OSAObj_OSADebuggerGetSessionState(OSAComponentInstanceObject *_self, PyObject *_args) -{ - PyObject *_res = NULL; - OSAError _err; - OSADebugSessionRef inSession; - AERecord outState; -#ifndef OSADebuggerGetSessionState - PyMac_PRECHECK(OSADebuggerGetSessionState); -#endif - if (!PyArg_ParseTuple(_args, "l", - &inSession)) - return NULL; - _err = OSADebuggerGetSessionState(_self->ob_itself, - inSession, - &outState); - if (_err != noErr) return PyMac_Error(_err); - _res = Py_BuildValue("O&", - AEDesc_New, &outState); - return _res; -} - -static PyObject *OSAObj_OSADebuggerSessionStep(OSAComponentInstanceObject *_self, PyObject *_args) -{ - PyObject *_res = NULL; - OSAError _err; - OSADebugSessionRef inSession; - OSADebugStepKind inKind; -#ifndef OSADebuggerSessionStep - PyMac_PRECHECK(OSADebuggerSessionStep); -#endif - if (!PyArg_ParseTuple(_args, "ll", - &inSession, - &inKind)) - return NULL; - _err = OSADebuggerSessionStep(_self->ob_itself, - inSession, - inKind); - if (_err != noErr) return PyMac_Error(_err); - Py_INCREF(Py_None); - _res = Py_None; - return _res; -} - -static PyObject *OSAObj_OSADebuggerDisposeSession(OSAComponentInstanceObject *_self, PyObject *_args) -{ - PyObject *_res = NULL; - OSAError _err; - OSADebugSessionRef inSession; -#ifndef OSADebuggerDisposeSession - PyMac_PRECHECK(OSADebuggerDisposeSession); -#endif - if (!PyArg_ParseTuple(_args, "l", - &inSession)) - return NULL; - _err = OSADebuggerDisposeSession(_self->ob_itself, - inSession); - if (_err != noErr) return PyMac_Error(_err); - Py_INCREF(Py_None); - _res = Py_None; - return _res; -} - -static PyObject *OSAObj_OSADebuggerGetStatementRanges(OSAComponentInstanceObject *_self, PyObject *_args) -{ - PyObject *_res = NULL; - OSAError _err; - OSADebugSessionRef inSession; - AEDescList outStatementRangeArray; -#ifndef OSADebuggerGetStatementRanges - PyMac_PRECHECK(OSADebuggerGetStatementRanges); -#endif - if (!PyArg_ParseTuple(_args, "l", - &inSession)) - return NULL; - _err = OSADebuggerGetStatementRanges(_self->ob_itself, - inSession, - &outStatementRangeArray); - if (_err != noErr) return PyMac_Error(_err); - _res = Py_BuildValue("O&", - AEDesc_New, &outStatementRangeArray); - return _res; -} - -static PyObject *OSAObj_OSADebuggerGetBreakpoint(OSAComponentInstanceObject *_self, PyObject *_args) -{ - PyObject *_res = NULL; - OSAError _err; - OSADebugSessionRef inSession; - UInt32 inSrcOffset; - OSAID outBreakpoint; -#ifndef OSADebuggerGetBreakpoint - PyMac_PRECHECK(OSADebuggerGetBreakpoint); -#endif - if (!PyArg_ParseTuple(_args, "ll", - &inSession, - &inSrcOffset)) - return NULL; - _err = OSADebuggerGetBreakpoint(_self->ob_itself, - inSession, - inSrcOffset, - &outBreakpoint); - if (_err != noErr) return PyMac_Error(_err); - _res = Py_BuildValue("l", - outBreakpoint); - return _res; -} - -static PyObject *OSAObj_OSADebuggerSetBreakpoint(OSAComponentInstanceObject *_self, PyObject *_args) -{ - PyObject *_res = NULL; - OSAError _err; - OSADebugSessionRef inSession; - UInt32 inSrcOffset; - OSAID inBreakpoint; -#ifndef OSADebuggerSetBreakpoint - PyMac_PRECHECK(OSADebuggerSetBreakpoint); -#endif - if (!PyArg_ParseTuple(_args, "lll", - &inSession, - &inSrcOffset, - &inBreakpoint)) - return NULL; - _err = OSADebuggerSetBreakpoint(_self->ob_itself, - inSession, - inSrcOffset, - inBreakpoint); - if (_err != noErr) return PyMac_Error(_err); - Py_INCREF(Py_None); - _res = Py_None; - return _res; -} - -static PyObject *OSAObj_OSADebuggerGetDefaultBreakpoint(OSAComponentInstanceObject *_self, PyObject *_args) -{ - PyObject *_res = NULL; - OSAError _err; - OSADebugSessionRef inSession; - OSAID outBreakpoint; -#ifndef OSADebuggerGetDefaultBreakpoint - PyMac_PRECHECK(OSADebuggerGetDefaultBreakpoint); -#endif - if (!PyArg_ParseTuple(_args, "l", - &inSession)) - return NULL; - _err = OSADebuggerGetDefaultBreakpoint(_self->ob_itself, - inSession, - &outBreakpoint); - if (_err != noErr) return PyMac_Error(_err); - _res = Py_BuildValue("l", - outBreakpoint); - return _res; -} - -static PyObject *OSAObj_OSADebuggerGetCurrentCallFrame(OSAComponentInstanceObject *_self, PyObject *_args) -{ - PyObject *_res = NULL; - OSAError _err; - OSADebugSessionRef inSession; - OSADebugCallFrameRef outCallFrame; -#ifndef OSADebuggerGetCurrentCallFrame - PyMac_PRECHECK(OSADebuggerGetCurrentCallFrame); -#endif - if (!PyArg_ParseTuple(_args, "l", - &inSession)) - return NULL; - _err = OSADebuggerGetCurrentCallFrame(_self->ob_itself, - inSession, - &outCallFrame); - if (_err != noErr) return PyMac_Error(_err); - _res = Py_BuildValue("l", - outCallFrame); - return _res; -} - -static PyObject *OSAObj_OSADebuggerGetCallFrameState(OSAComponentInstanceObject *_self, PyObject *_args) -{ - PyObject *_res = NULL; - OSAError _err; - OSADebugCallFrameRef inCallFrame; - AERecord outState; -#ifndef OSADebuggerGetCallFrameState - PyMac_PRECHECK(OSADebuggerGetCallFrameState); -#endif - if (!PyArg_ParseTuple(_args, "l", - &inCallFrame)) - return NULL; - _err = OSADebuggerGetCallFrameState(_self->ob_itself, - inCallFrame, - &outState); - if (_err != noErr) return PyMac_Error(_err); - _res = Py_BuildValue("O&", - AEDesc_New, &outState); - return _res; -} - -static PyObject *OSAObj_OSADebuggerGetVariable(OSAComponentInstanceObject *_self, PyObject *_args) -{ - PyObject *_res = NULL; - OSAError _err; - OSADebugCallFrameRef inCallFrame; - AEDesc inVariableName; - OSAID outVariable; -#ifndef OSADebuggerGetVariable - PyMac_PRECHECK(OSADebuggerGetVariable); -#endif - if (!PyArg_ParseTuple(_args, "lO&", - &inCallFrame, - AEDesc_Convert, &inVariableName)) - return NULL; - _err = OSADebuggerGetVariable(_self->ob_itself, - inCallFrame, - &inVariableName, - &outVariable); - if (_err != noErr) return PyMac_Error(_err); - _res = Py_BuildValue("l", - outVariable); - return _res; -} - -static PyObject *OSAObj_OSADebuggerSetVariable(OSAComponentInstanceObject *_self, PyObject *_args) -{ - PyObject *_res = NULL; - OSAError _err; - OSADebugCallFrameRef inCallFrame; - AEDesc inVariableName; - OSAID inVariable; -#ifndef OSADebuggerSetVariable - PyMac_PRECHECK(OSADebuggerSetVariable); -#endif - if (!PyArg_ParseTuple(_args, "lO&l", - &inCallFrame, - AEDesc_Convert, &inVariableName, - &inVariable)) - return NULL; - _err = OSADebuggerSetVariable(_self->ob_itself, - inCallFrame, - &inVariableName, - inVariable); - if (_err != noErr) return PyMac_Error(_err); - Py_INCREF(Py_None); - _res = Py_None; - return _res; -} - -static PyObject *OSAObj_OSADebuggerGetPreviousCallFrame(OSAComponentInstanceObject *_self, PyObject *_args) -{ - PyObject *_res = NULL; - OSAError _err; - OSADebugCallFrameRef inCurrentFrame; - OSADebugCallFrameRef outPrevFrame; -#ifndef OSADebuggerGetPreviousCallFrame - PyMac_PRECHECK(OSADebuggerGetPreviousCallFrame); -#endif - if (!PyArg_ParseTuple(_args, "l", - &inCurrentFrame)) - return NULL; - _err = OSADebuggerGetPreviousCallFrame(_self->ob_itself, - inCurrentFrame, - &outPrevFrame); - if (_err != noErr) return PyMac_Error(_err); - _res = Py_BuildValue("l", - outPrevFrame); - return _res; -} - -static PyObject *OSAObj_OSADebuggerDisposeCallFrame(OSAComponentInstanceObject *_self, PyObject *_args) -{ - PyObject *_res = NULL; - OSAError _err; - OSADebugCallFrameRef inCallFrame; -#ifndef OSADebuggerDisposeCallFrame - PyMac_PRECHECK(OSADebuggerDisposeCallFrame); -#endif - if (!PyArg_ParseTuple(_args, "l", - &inCallFrame)) - return NULL; - _err = OSADebuggerDisposeCallFrame(_self->ob_itself, - inCallFrame); - if (_err != noErr) return PyMac_Error(_err); - Py_INCREF(Py_None); - _res = Py_None; - return _res; -} - static PyMethodDef OSAObj_methods[] = { {"OSALoad", (PyCFunction)OSAObj_OSALoad, 1, PyDoc_STR("(AEDesc scriptData, long modeFlags) -> (OSAID resultingScriptID)")}, @@ -1091,34 +783,6 @@ static PyMethodDef OSAObj_methods[] = { PyDoc_STR("(AppleEvent theAppleEvent, OSAID contextID, long modeFlags) -> (AppleEvent reply)")}, {"OSAMakeContext", (PyCFunction)OSAObj_OSAMakeContext, 1, PyDoc_STR("(AEDesc contextName, OSAID parentContext) -> (OSAID resultingContextID)")}, - {"OSADebuggerCreateSession", (PyCFunction)OSAObj_OSADebuggerCreateSession, 1, - PyDoc_STR("(OSAID inScript, OSAID inContext) -> (OSADebugSessionRef outSession)")}, - {"OSADebuggerGetSessionState", (PyCFunction)OSAObj_OSADebuggerGetSessionState, 1, - PyDoc_STR("(OSADebugSessionRef inSession) -> (AERecord outState)")}, - {"OSADebuggerSessionStep", (PyCFunction)OSAObj_OSADebuggerSessionStep, 1, - PyDoc_STR("(OSADebugSessionRef inSession, OSADebugStepKind inKind) -> None")}, - {"OSADebuggerDisposeSession", (PyCFunction)OSAObj_OSADebuggerDisposeSession, 1, - PyDoc_STR("(OSADebugSessionRef inSession) -> None")}, - {"OSADebuggerGetStatementRanges", (PyCFunction)OSAObj_OSADebuggerGetStatementRanges, 1, - PyDoc_STR("(OSADebugSessionRef inSession) -> (AEDescList outStatementRangeArray)")}, - {"OSADebuggerGetBreakpoint", (PyCFunction)OSAObj_OSADebuggerGetBreakpoint, 1, - PyDoc_STR("(OSADebugSessionRef inSession, UInt32 inSrcOffset) -> (OSAID outBreakpoint)")}, - {"OSADebuggerSetBreakpoint", (PyCFunction)OSAObj_OSADebuggerSetBreakpoint, 1, - PyDoc_STR("(OSADebugSessionRef inSession, UInt32 inSrcOffset, OSAID inBreakpoint) -> None")}, - {"OSADebuggerGetDefaultBreakpoint", (PyCFunction)OSAObj_OSADebuggerGetDefaultBreakpoint, 1, - PyDoc_STR("(OSADebugSessionRef inSession) -> (OSAID outBreakpoint)")}, - {"OSADebuggerGetCurrentCallFrame", (PyCFunction)OSAObj_OSADebuggerGetCurrentCallFrame, 1, - PyDoc_STR("(OSADebugSessionRef inSession) -> (OSADebugCallFrameRef outCallFrame)")}, - {"OSADebuggerGetCallFrameState", (PyCFunction)OSAObj_OSADebuggerGetCallFrameState, 1, - PyDoc_STR("(OSADebugCallFrameRef inCallFrame) -> (AERecord outState)")}, - {"OSADebuggerGetVariable", (PyCFunction)OSAObj_OSADebuggerGetVariable, 1, - PyDoc_STR("(OSADebugCallFrameRef inCallFrame, AEDesc inVariableName) -> (OSAID outVariable)")}, - {"OSADebuggerSetVariable", (PyCFunction)OSAObj_OSADebuggerSetVariable, 1, - PyDoc_STR("(OSADebugCallFrameRef inCallFrame, AEDesc inVariableName, OSAID inVariable) -> None")}, - {"OSADebuggerGetPreviousCallFrame", (PyCFunction)OSAObj_OSADebuggerGetPreviousCallFrame, 1, - PyDoc_STR("(OSADebugCallFrameRef inCurrentFrame) -> (OSADebugCallFrameRef outPrevFrame)")}, - {"OSADebuggerDisposeCallFrame", (PyCFunction)OSAObj_OSADebuggerDisposeCallFrame, 1, - PyDoc_STR("(OSADebugCallFrameRef inCallFrame) -> None")}, {NULL, NULL, 0} }; diff --git a/PCbuild9/build_tkinter.py b/PCbuild9/build_tkinter.py index 5423a3b1130..d76ea264b11 100644 --- a/PCbuild9/build_tkinter.py +++ b/PCbuild9/build_tkinter.py @@ -12,12 +12,10 @@ import shutil here = os.path.abspath(os.path.dirname(__file__)) par = os.path.pardir -#TCL = "tcl8.4.16" -#TIX = "Tix8.4.2" -#TK = "tk8.4.16" -TCL = "tcl8.4.12" +TCL = "tcl8.4.16" +TK = "tk8.4.16" TIX = "Tix8.4.0" -TK = "tk8.4.12" +#TIX = "Tix8.4.2" ROOT = os.path.abspath(os.path.join(here, par, par)) NMAKE = "nmake /nologo " @@ -57,9 +55,9 @@ def build(platform, clean): if True: os.chdir(os.path.join(ROOT, TIX, "win")) if clean: - system(NMAKE + "/f makefile.vc clean") - system(NMAKE + "/f makefile.vc MACHINE=%s" % machine) - system(NMAKE + "/f makefile.vc INSTALL_DIR=%s install" % dest) + system(NMAKE + "/f python9.mak clean") + system(NMAKE + "/f python9.mak MACHINE=%s" % machine) + system(NMAKE + "/f python9.mak install") def main(): diff --git a/PCbuild9/readme.txt b/PCbuild9/readme.txt index efcd4d70c66..791edb2a0aa 100644 --- a/PCbuild9/readme.txt +++ b/PCbuild9/readme.txt @@ -83,10 +83,19 @@ _tkinter svn export http://svn.python.org/projects/external/tk8.4.16 svn export http://svn.python.org/projects/external/tix-8.4.0 - Build Tcl first (done here w/ MSVC 7.1 on Windows XP) + Build with build_tkinter.py + --------------------------- + The PCbuild9 directory contains a Python script which automates all + steps. Run the script in a Visual Studio 2009 command prompt with + + python build_tkinter.py Win32 + + Use x64 instead of Win32 for the x64 platform. + + Build Tcl first --------------- - Use "Start -> All Programs -> Microsoft Visual Studio .NET 2003 - -> Visual Studio .NET Tools -> Visual Studio .NET 2003 Command Prompt" + Use "Start -> All Programs -> Microsoft Visual Studio 2008 + -> Visual Studio Tools -> Visual Studio 2008 Command Prompt" to get a shell window with the correct environment settings cd dist\tcl8.4.16\win nmake -f makefile.vc diff --git a/Python/ceval.c b/Python/ceval.c index 813f6f636a9..cf2147a31c5 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -625,7 +625,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) next opcode. A successful prediction saves a trip through the eval-loop including - its two unpredictable branches, the HASARG test and the switch-case. + its two unpredictable branches, the HAS_ARG test and the switch-case. If collecting opcode statistics, turn off prediction so that statistics are accurately maintained (the predictions bypass