From f3a0b86408b50432619fe5baebd2279a3ec00964 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 7 Dec 2008 14:47:12 +0000 Subject: Merged revisions 67571,67574-67576,67579-67581,67583,67591,67597,67608,67631 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r67571 | georg.brandl | 2008-12-05 10:13:45 +0100 (Fri, 05 Dec 2008) | 2 lines Use markup. ........ r67574 | georg.brandl | 2008-12-05 10:25:32 +0100 (Fri, 05 Dec 2008) | 2 lines #4441 followup: Add link to open() docs for Windows. ........ r67575 | georg.brandl | 2008-12-05 12:34:51 +0100 (Fri, 05 Dec 2008) | 2 lines #4544: add `dedent` to textwrap.__all__. ........ r67576 | georg.brandl | 2008-12-05 13:09:41 +0100 (Fri, 05 Dec 2008) | 2 lines #4529: fix parser's validation for try-except-finally statements. ........ r67579 | georg.brandl | 2008-12-05 16:29:39 +0100 (Fri, 05 Dec 2008) | 2 lines #4517: add "special method" glossary entry and clarify when __getattribute__ is bypassed. ........ r67580 | georg.brandl | 2008-12-05 16:32:29 +0100 (Fri, 05 Dec 2008) | 2 lines #4478: document that copyfile() can raise Error. ........ r67581 | georg.brandl | 2008-12-05 16:42:03 +0100 (Fri, 05 Dec 2008) | 2 lines #3171: document that *slice are removed in 3k. ........ r67583 | georg.brandl | 2008-12-05 16:52:20 +0100 (Fri, 05 Dec 2008) | 4 lines Move __import__ to the bottom of the functions list. It doesn't make sense for such a fundamental document to have the most obscure function listed at the top. ........ r67591 | georg.brandl | 2008-12-05 19:00:06 +0100 (Fri, 05 Dec 2008) | 2 lines Followup to #4511: add link from decorator glossary entry to definition. ........ r67597 | georg.brandl | 2008-12-05 20:03:19 +0100 (Fri, 05 Dec 2008) | 2 lines Remove confusing sentence part. ........ r67608 | georg.brandl | 2008-12-06 12:57:12 +0100 (Sat, 06 Dec 2008) | 2 lines Follow-up to #4488: document PIPE and STDOUT properly. ........ r67631 | georg.brandl | 2008-12-07 12:54:07 +0100 (Sun, 07 Dec 2008) | 2 lines Add link to the favicon to the docs. ........ --- Doc/documenting/rest.rst | 2 +- Doc/glossary.rst | 9 +++ Doc/library/functions.rst | 122 ++++++++++++++++++++-------------------- Doc/library/getopt.rst | 4 +- Doc/library/operator.rst | 13 +++++ Doc/library/os.rst | 4 +- Doc/library/shutil.rst | 3 +- Doc/library/subprocess.rst | 51 +++++++++++------ Doc/reference/datamodel.rst | 2 +- Doc/tools/sphinxext/layout.html | 8 ++- Lib/test/test_parser.py | 10 ++++ Lib/textwrap.py | 2 +- Misc/NEWS | 9 +++ Modules/parsermodule.c | 46 +++++++-------- 14 files changed, 174 insertions(+), 111 deletions(-) diff --git a/Doc/documenting/rest.rst b/Doc/documenting/rest.rst index e018373..9b6b89b 100644 --- a/Doc/documenting/rest.rst +++ b/Doc/documenting/rest.rst @@ -98,7 +98,7 @@ Source Code ----------- Literal code blocks are introduced by ending a paragraph with the special marker -``::``. The literal block must be indented, to be able to include blank lines:: +``::``. The literal block must be indented:: This is a normal text paragraph. The next paragraph is a code sample:: diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 7a87dd5..2894f35 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -123,6 +123,9 @@ Glossary def f(...): ... + See :ref:`the documentation for function definition ` for more + about decorators. + descriptor Any *new-style* object which defines the methods :meth:`__get__`, :meth:`__set__`, or :meth:`__delete__`. When a class attribute is a @@ -498,6 +501,12 @@ Glossary (subscript) notation uses :class:`slice` objects internally (or in older versions, :meth:`__getslice__` and :meth:`__setslice__`). + special method + A method that is called implicitly by Python to execute a certain + operation on a type, such as addition. Such methods have names starting + and ending with double underscores. Special methods are documented in + :ref:`specialnames`. + statement A statement is part of a suite (a "block" of code). A statement is either an :term:`expression` or a one of several constructs with a keyword, such diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index daa2704..d6c8d05 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -8,67 +8,6 @@ The Python interpreter has a number of functions built into it that are always available. They are listed here in alphabetical order. -.. function:: __import__(name[, globals[, locals[, fromlist[, level]]]]) - - .. index:: - statement: import - module: ihooks - module: rexec - module: imp - - .. note:: - - This is an advanced function that is not needed in everyday Python - programming. - - The function is invoked by the :keyword:`import` statement. It mainly exists - so that you can replace it with another function that has a compatible - interface, in order to change the semantics of the :keyword:`import` statement. - See the built-in module :mod:`imp`, which defines some useful operations out - of which you can build your own :func:`__import__` function. - - For example, the statement ``import spam`` results in the following call: - ``__import__('spam', globals(), locals(), [], -1)``; the statement - ``from spam.ham import eggs`` results in ``__import__('spam.ham', globals(), - locals(), ['eggs'], -1)``. Note that even though ``locals()`` and ``['eggs']`` - are passed in as arguments, the :func:`__import__` function does not set the - local variable named ``eggs``; this is done by subsequent code that is generated - for the import statement. (In fact, the standard implementation does not use - its *locals* argument at all, and uses its *globals* only to determine the - package context of the :keyword:`import` statement.) - - When the *name* variable is of the form ``package.module``, normally, the - top-level package (the name up till the first dot) is returned, *not* the - module named by *name*. However, when a non-empty *fromlist* argument is - given, the module named by *name* is returned. This is done for - compatibility with the :term:`bytecode` generated for the different kinds of import - statement; when using ``import spam.ham.eggs``, the top-level package - :mod:`spam` must be placed in the importing namespace, but when using ``from - spam.ham import eggs``, the ``spam.ham`` subpackage must be used to find the - ``eggs`` variable. As a workaround for this behavior, use :func:`getattr` to - extract the desired components. For example, you could define the following - helper:: - - def my_import(name): - mod = __import__(name) - components = name.split('.') - for comp in components[1:]: - mod = getattr(mod, comp) - return mod - - *level* specifies whether to use absolute or relative imports. The default is - ``-1`` which indicates both absolute and relative imports will be attempted. - ``0`` means only perform absolute imports. Positive values for *level* indicate - the number of parent directories to search relative to the directory of the - module calling :func:`__import__`. - - .. versionchanged:: 2.5 - The level parameter was added. - - .. versionchanged:: 2.5 - Keyword support for parameters was added. - - .. function:: abs(x) Return the absolute value of a number. The argument may be a plain or long @@ -1419,6 +1358,67 @@ available. They are listed here in alphabetical order. Formerly, :func:`zip` required at least one argument and ``zip()`` raised a :exc:`TypeError` instead of returning an empty list. + +.. function:: __import__(name[, globals[, locals[, fromlist[, level]]]]) + + .. index:: + statement: import + module: ihooks + module: rexec + module: imp + + .. note:: + + This is an advanced function that is not needed in everyday Python + programming. + + The function is invoked by the :keyword:`import` statement. It mainly exists + so that you can replace it with another function that has a compatible + interface, in order to change the semantics of the :keyword:`import` statement. + See the built-in module :mod:`imp`, which defines some useful operations out + of which you can build your own :func:`__import__` function. + + For example, the statement ``import spam`` results in the following call: + ``__import__('spam', globals(), locals(), [], -1)``; the statement + ``from spam.ham import eggs`` results in ``__import__('spam.ham', globals(), + locals(), ['eggs'], -1)``. Note that even though ``locals()`` and ``['eggs']`` + are passed in as arguments, the :func:`__import__` function does not set the + local variable named ``eggs``; this is done by subsequent code that is generated + for the import statement. (In fact, the standard implementation does not use + its *locals* argument at all, and uses its *globals* only to determine the + package context of the :keyword:`import` statement.) + + When the *name* variable is of the form ``package.module``, normally, the + top-level package (the name up till the first dot) is returned, *not* the + module named by *name*. However, when a non-empty *fromlist* argument is + given, the module named by *name* is returned. This is done for + compatibility with the :term:`bytecode` generated for the different kinds of import + statement; when using ``import spam.ham.eggs``, the top-level package + :mod:`spam` must be placed in the importing namespace, but when using ``from + spam.ham import eggs``, the ``spam.ham`` subpackage must be used to find the + ``eggs`` variable. As a workaround for this behavior, use :func:`getattr` to + extract the desired components. For example, you could define the following + helper:: + + def my_import(name): + mod = __import__(name) + components = name.split('.') + for comp in components[1:]: + mod = getattr(mod, comp) + return mod + + *level* specifies whether to use absolute or relative imports. The default is + ``-1`` which indicates both absolute and relative imports will be attempted. + ``0`` means only perform absolute imports. Positive values for *level* indicate + the number of parent directories to search relative to the directory of the + module calling :func:`__import__`. + + .. versionchanged:: 2.5 + The level parameter was added. + + .. versionchanged:: 2.5 + Keyword support for parameters was added. + .. --------------------------------------------------------------------------- diff --git a/Doc/library/getopt.rst b/Doc/library/getopt.rst index a666d0a..2c0fad9 100644 --- a/Doc/library/getopt.rst +++ b/Doc/library/getopt.rst @@ -63,8 +63,8 @@ exception: non-option argument is encountered. If the first character of the option string is '+', or if the environment - variable POSIXLY_CORRECT is set, then option processing stops as soon as a - non-option argument is encountered. + variable :envvar:`POSIXLY_CORRECT` is set, then option processing stops as + soon as a non-option argument is encountered. .. versionadded:: 2.3 diff --git a/Doc/library/operator.rst b/Doc/library/operator.rst index 4921898..2ab54db 100644 --- a/Doc/library/operator.rst +++ b/Doc/library/operator.rst @@ -240,6 +240,10 @@ Operations which work with sequences include: Delete the slice of *a* from index *b* to index *c-1*. + .. deprecated:: 2.6 + This function is removed in Python 3.x. Use :func:`delitem` with a slice + index. + .. function:: getitem(a, b) __getitem__(a, b) @@ -252,6 +256,10 @@ Operations which work with sequences include: Return the slice of *a* from index *b* to index *c-1*. + .. deprecated:: 2.6 + This function is removed in Python 3.x. Use :func:`getitem` with a slice + index. + .. function:: indexOf(a, b) @@ -283,6 +291,11 @@ Operations which work with sequences include: Set the slice of *a* from index *b* to index *c-1* to the sequence *v*. + .. deprecated:: 2.6 + This function is removed in Python 3.x. Use :func:`setitem` with a slice + index. + + Many operations have an "in-place" version. The following functions provide a more primitive access to in-place operators than the usual syntax does; for example, the :term:`statement` ``x += y`` is equivalent to diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 6136e41..8111fa3 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -684,8 +684,8 @@ by file descriptors. The following constants are options for the *flags* parameter to the :func:`open` function. They can be combined using the bitwise OR operator ``|``. Some of them are not available on all platforms. For descriptions of -their availability and use, consult the :manpage:`open(2)` manual page or the -respective documentation for your operating system. +their availability and use, consult the :manpage:`open(2)` manual page on Unix +or `the MSDN ` on Windows. .. data:: O_RDONLY diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 944b9f1..b409bb7 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -43,7 +43,8 @@ copying and removal. For operations on individual files, see also the Copy the contents (no metadata) of the file named *src* to a file named *dst*. *dst* must be the complete target file name; look at :func:`copy` for a copy that - accepts a target directory path. + accepts a target directory path. If *src* and *dst* are the same files, + :exc:`Error` is raised. The destination location must be writable; otherwise, an :exc:`IOError` exception will be raised. If *dst* already exists, it will be replaced. Special files such as character or block devices and pipes cannot be copied with this diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index dae582c..cea8b72 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -73,13 +73,13 @@ This module defines one class called :class:`Popen`: specified by the :envvar:`COMSPEC` environment variable. *stdin*, *stdout* and *stderr* specify the executed programs' standard input, - standard output and standard error file handles, respectively. Valid values are - ``PIPE``, an existing file descriptor (a positive integer), an existing file - object, and ``None``. ``PIPE`` indicates that a new pipe to the child should be - created. With ``None``, no redirection will occur; the child's file handles - will be inherited from the parent. Additionally, *stderr* can be ``STDOUT``, - which indicates that the stderr data from the applications should be captured - into the same file handle as for stdout. + standard output and standard error file handles, respectively. Valid values + are :data:`PIPE`, an existing file descriptor (a positive integer), an + existing file object, and ``None``. :data:`PIPE` indicates that a new pipe + to the child should be created. With ``None``, no redirection will occur; + the child's file handles will be inherited from the parent. Additionally, + *stderr* can be :data:`STDOUT`, which indicates that the stderr data from the + applications should be captured into the same file handle as for stdout. If *preexec_fn* is set to a callable object, this object will be called in the child process just before the child is executed. (Unix only) @@ -119,6 +119,20 @@ This module defines one class called :class:`Popen`: of the main window and priority for the new process. (Windows only) +.. data:: PIPE + + Special value that can be used as the *stdin*, *stdout* or *stderr* argument + to :class:`Popen` and indicates that a pipe to the standard stream should be + opened. + + +.. data:: STDOUT + + Special value that can be used as the *stderr* argument to :class:`Popen` and + indicates that standard error should go into the same handle as standard + output. + + Convenience Functions ^^^^^^^^^^^^^^^^^^^^^ @@ -261,20 +275,21 @@ The following attributes are also available: .. attribute:: Popen.stdin - If the *stdin* argument is ``PIPE``, this attribute is a file object that - provides input to the child process. Otherwise, it is ``None``. + If the *stdin* argument was :data:`PIPE`, this attribute is a file object + that provides input to the child process. Otherwise, it is ``None``. .. attribute:: Popen.stdout - If the *stdout* argument is ``PIPE``, this attribute is a file object that - provides output from the child process. Otherwise, it is ``None``. + If the *stdout* argument was :data:`PIPE`, this attribute is a file object + that provides output from the child process. Otherwise, it is ``None``. .. attribute:: Popen.stderr - If the *stderr* argument is ``PIPE``, this attribute is file object that - provides error output from the child process. Otherwise, it is ``None``. + If the *stderr* argument was :data:`PIPE`, this attribute is a file object + that provides error output from the child process. Otherwise, it is + ``None``. .. attribute:: Popen.pid @@ -454,15 +469,15 @@ Replacing functions from the popen2 module stdin=PIPE, stdout=PIPE, close_fds=True) (child_stdout, child_stdin) = (p.stdout, p.stdin) -The popen2.Popen3 and popen2.Popen4 basically works as subprocess.Popen, except -that: +:class:`popen2.Popen3` and :class:`popen2.Popen4` basically work as +:class:`subprocess.Popen`, except that: -* subprocess.Popen raises an exception if the execution fails +* :class:`Popen` raises an exception if the execution fails. * the *capturestderr* argument is replaced with the *stderr* argument. -* stdin=PIPE and stdout=PIPE must be specified. +* ``stdin=PIPE`` and ``stdout=PIPE`` must be specified. * popen2 closes all file descriptors by default, but you have to specify - close_fds=True with subprocess.Popen. + ``close_fds=True`` with :class:`Popen`. diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 4dcc96f..068f0fd 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2370,7 +2370,7 @@ the instance when looking up special methods:: True In addition to bypassing any instance attributes in the interest of -correctness, implicit special method lookup may also bypass the +correctness, implicit special method lookup generally also bypasses the :meth:`__getattribute__` method even of the object's metaclass:: >>> class Meta(type): diff --git a/Doc/tools/sphinxext/layout.html b/Doc/tools/sphinxext/layout.html index a6afd15..6029871 100644 --- a/Doc/tools/sphinxext/layout.html +++ b/Doc/tools/sphinxext/layout.html @@ -1,4 +1,10 @@ {% extends "!layout.html" %} {% block rootrellink %} -
  • {{ shorttitle }}{{ reldelim1 }}
  • +
  • +
  • {{ shorttitle }}{{ reldelim1 }}
  • +{% endblock %} +{% block extrahead %} + +{{ super() }} {% endblock %} diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py index 1069606..23f418e 100644 --- a/Lib/test/test_parser.py +++ b/Lib/test/test_parser.py @@ -200,6 +200,16 @@ class RoundtripLegalSyntaxTestCase(unittest.TestCase): self.check_suite("with open('x'): pass\n") self.check_suite("with open('x') as f: pass\n") + def test_try_stmt(self): + self.check_suite("try: pass\nexcept: pass\n") + self.check_suite("try: pass\nfinally: pass\n") + self.check_suite("try: pass\nexcept A: pass\nfinally: pass\n") + self.check_suite("try: pass\nexcept A: pass\nexcept: pass\n" + "finally: pass\n") + self.check_suite("try: pass\nexcept: pass\nelse: pass\n") + self.check_suite("try: pass\nexcept: pass\nelse: pass\n" + "finally: pass\n") + def test_position(self): # An absolutely minimal test of position information. Better # tests would be a big project. diff --git a/Lib/textwrap.py b/Lib/textwrap.py index 2286c7a..53f2f1b 100644 --- a/Lib/textwrap.py +++ b/Lib/textwrap.py @@ -17,7 +17,7 @@ import string, re #except NameError: # (True, False) = (1, 0) -__all__ = ['TextWrapper', 'wrap', 'fill'] +__all__ = ['TextWrapper', 'wrap', 'fill', 'dedent'] # Hardcode the recognized whitespace characters to the US-ASCII # whitespace characters. The main reason for doing this is that in diff --git a/Misc/NEWS b/Misc/NEWS index 6711179..effcf20 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -80,6 +80,15 @@ Core and Builtins Library ------- +- Issue #4529: fix the parser module's validation of try-except-finally + statements. + +- Issue #4458: getopt.gnu_getopt() now recognizes a single "-" as an argument, + not a malformed option. + +- Added the subprocess.check_output() convenience function to get output + from a subprocess on success or raise an exception on error. + - Issue #1055234: cgi.parse_header(): Fixed parsing of header parameters to support unusual filenames (such as those containing semi-colons) in Content-Disposition headers. diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 95fcdcd..12b7fc3 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -2057,6 +2057,7 @@ validate_for(node *tree) /* try_stmt: * 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] + ['finally' ':' suite] * | 'try' ':' suite 'finally' ':' suite * */ @@ -2082,35 +2083,34 @@ validate_try(node *tree) PyErr_Format(parser_error, "Illegal number of children for try/%s node.", name); } - /* Skip past except_clause sections: */ + /* Handle try/finally statement */ + if (res && (TYPE(CHILD(tree, pos)) == NAME) && + (strcmp(STR(CHILD(tree, pos)), "finally") == 0)) { + res = (validate_numnodes(tree, 6, "try/finally") + && validate_colon(CHILD(tree, 4)) + && validate_suite(CHILD(tree, 5))); + return (res); + } + /* try/except statement: skip past except_clause sections */ while (res && (TYPE(CHILD(tree, pos)) == except_clause)) { res = (validate_except_clause(CHILD(tree, pos)) && validate_colon(CHILD(tree, pos + 1)) && validate_suite(CHILD(tree, pos + 2))); pos += 3; } - if (res && (pos < nch)) { - res = validate_ntype(CHILD(tree, pos), NAME); - if (res && (strcmp(STR(CHILD(tree, pos)), "finally") == 0)) - res = (validate_numnodes(tree, 6, "try/finally") - && validate_colon(CHILD(tree, 4)) - && validate_suite(CHILD(tree, 5))); - else if (res) { - if (nch == (pos + 3)) { - res = ((strcmp(STR(CHILD(tree, pos)), "except") == 0) - || (strcmp(STR(CHILD(tree, pos)), "else") == 0)); - if (!res) - err_string("illegal trailing triple in try statement"); - } - else if (nch == (pos + 6)) { - res = (validate_name(CHILD(tree, pos), "except") - && validate_colon(CHILD(tree, pos + 1)) - && validate_suite(CHILD(tree, pos + 2)) - && validate_name(CHILD(tree, pos + 3), "else")); - } - else - res = validate_numnodes(tree, pos + 3, "try/except"); - } + /* skip else clause */ + if (res && (TYPE(CHILD(tree, pos)) == NAME) && + (strcmp(STR(CHILD(tree, pos)), "else") == 0)) { + res = (validate_colon(CHILD(tree, pos + 1)) + && validate_suite(CHILD(tree, pos + 2))); + pos += 3; + } + if (res && pos < nch) { + /* last clause must be a finally */ + res = (validate_name(CHILD(tree, pos), "finally") + && validate_numnodes(tree, pos + 3, "try/except/finally") + && validate_colon(CHILD(tree, pos + 1)) + && validate_suite(CHILD(tree, pos + 2))); } return (res); } -- cgit v0.12