From aa7886dd3fd56f02a4f5ef239c869e97cbde4a57 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Mon, 26 May 2014 22:20:37 -0700 Subject: [PATCH] Issue 21439: Minor issues in the reference manual. (Contributed by Feliks Kluzniak.) --- Doc/reference/compound_stmts.rst | 28 +++++++---- Doc/reference/datamodel.rst | 4 +- Doc/reference/executionmodel.rst | 12 ++--- Doc/reference/expressions.rst | 80 ++++++++++++++++---------------- Doc/reference/simple_stmts.rst | 62 ++++++++++++++----------- 5 files changed, 102 insertions(+), 84 deletions(-) diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 5e093cc993e..52fc2830a35 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -22,14 +22,14 @@ also syntactically compound statements. single: clause single: suite -Compound statements consist of one or more 'clauses.' A clause consists of a +A compound statement consists of one or more 'clauses.' A clause consists of a header and a 'suite.' The clause headers of a particular compound statement are all at the same indentation level. Each clause header begins with a uniquely identifying keyword and ends with a colon. A suite is a group of statements controlled by a clause. A suite can be one or more semicolon-separated simple statements on the same line as the header, following the header's colon, or it can be one or more indented statements on subsequent lines. Only the latter -form of suite can contain nested compound statements; the following is illegal, +form of a suite can contain nested compound statements; the following is illegal, mostly because it wouldn't be clear to which :keyword:`if` clause a following :keyword:`else` clause would belong:: @@ -156,8 +156,8 @@ The :keyword:`for` statement is used to iterate over the elements of a sequence The expression list is evaluated once; it should yield an iterable object. An iterator is created for the result of the ``expression_list``. The suite is -then executed once for each item provided by the iterator, in the order of -ascending indices. Each item in turn is assigned to the target list using the +then executed once for each item provided by the iterator, in the order returned +by the iterator. Each item in turn is assigned to the target list using the standard rules for assignments (see :ref:`assignment`), and then the suite is executed. When the items are exhausted (which is immediately when the sequence is empty or an iterator raises a :exc:`StopIteration` exception), the suite in @@ -170,17 +170,25 @@ the :keyword:`else` clause, if present, is executed, and the loop terminates. A :keyword:`break` statement executed in the first suite terminates the loop without executing the :keyword:`else` clause's suite. A :keyword:`continue` statement executed in the first suite skips the rest of the suite and continues -with the next item, or with the :keyword:`else` clause if there was no next +with the next item, or with the :keyword:`else` clause if there is no next item. -The suite may assign to the variable(s) in the target list; this does not affect -the next item assigned to it. +The for-loop makes assignments to the variables(s) in the target list. +This overwrites all previous assignments to those variables including +those made in the suite of the for-loop:: + + for i in range(10): + print(i) + i = 5 # this will not affect the for-loop + # be i will be overwritten with the next + # index in the range + .. index:: builtin: range Names in the target list are not deleted when the loop is finished, but if the -sequence is empty, it will not have been assigned to at all by the loop. Hint: +sequence is empty, they will not have been assigned to at all by the loop. Hint: the built-in function :func:`range` returns an iterator of integers suitable to emulate the effect of Pascal's ``for i := a to b do``; e.g., ``list(range(3))`` returns the list ``[0, 1, 2]``. @@ -284,7 +292,7 @@ keeping all locals in that frame alive until the next garbage collection occurs. object: traceback Before an except clause's suite is executed, details about the exception are -stored in the :mod:`sys` module and can be access via :func:`sys.exc_info`. +stored in the :mod:`sys` module and can be accessed via :func:`sys.exc_info`. :func:`sys.exc_info` returns a 3-tuple consisting of the exception class, the exception instance and a traceback object (see section :ref:`types`) identifying the point in the program where the exception occurred. :func:`sys.exc_info` @@ -461,7 +469,7 @@ A function definition defines a user-defined function object (see section decorator: "@" `dotted_name` ["(" [`parameter_list` [","]] ")"] NEWLINE dotted_name: `identifier` ("." `identifier`)* parameter_list: (`defparameter` ",")* - : ( "*" [`parameter`] ("," `defparameter`)* ["," "**" `parameter`] + : | "*" [`parameter`] ("," `defparameter`)* ["," "**" `parameter`] : | "**" `parameter` : | `defparameter` [","] ) parameter: `identifier` [":" `expression`] diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 78dfd79b007..c0ed5af4293 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -77,7 +77,7 @@ are still reachable. module for information on controlling the collection of cyclic garbage. Other implementations act differently and CPython may change. Do not depend on immediate finalization of objects when they become - unreachable (ex: always close files). + unreachable (so you should always close files explicitly). Note that the use of the implementation's tracing or debugging facilities may keep objects alive that would normally be collectable. Also note that catching @@ -1722,7 +1722,7 @@ property creation, proxies, frameworks, and automatic resource locking/synchronization. Here is an example of a metaclass that uses an :class:`collections.OrderedDict` -to remember the order that class members were defined:: +to remember the order that class variables are defined:: class OrderedClass(type): diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst index 82e37a21fab..664d736db1c 100644 --- a/Doc/reference/executionmodel.rst +++ b/Doc/reference/executionmodel.rst @@ -31,11 +31,11 @@ that name established in the innermost function block containing the use. A :dfn:`block` is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition. Each command typed interactively is a block. A script file (a file given as -standard input to the interpreter or specified on the interpreter command line -the first argument) is a code block. A script command (a command specified on -the interpreter command line with the '**-c**' option) is a code block. The -string argument passed to the built-in functions :func:`eval` and :func:`exec` -is a code block. +standard input to the interpreter or specified as a command line argument to the +interpreter) is a code block. A script command (a command specified on the +interpreter command line with the '**-c**' option) is a code block. The string +argument passed to the built-in functions :func:`eval` and :func:`exec` is a +code block. .. index:: pair: execution; frame @@ -77,7 +77,7 @@ global.) If a variable is used in a code block but not defined there, it is a single: UnboundLocalError When a name is not found at all, a :exc:`NameError` exception is raised. If the -name refers to a local variable that has not been bound, a +name refers to a local variable that has not been bound, an :exc:`UnboundLocalError` exception is raised. :exc:`UnboundLocalError` is a subclass of :exc:`NameError`. diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 06baba0d605..5c86fbd7e56 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -29,7 +29,7 @@ Arithmetic conversions When a description of an arithmetic operator below uses the phrase "the numeric arguments are converted to a common type," this means that the operator -implementation for built-in types works that way: +implementation for built-in types works as follows: * If either argument is a complex number, the other is converted to complex; @@ -38,8 +38,9 @@ implementation for built-in types works that way: * otherwise, both must be integers and no conversion is necessary. -Some additional rules apply for certain operators (e.g., a string left argument -to the '%' operator). Extensions must define their own conversion behavior. +Some additional rules apply for certain operators (e.g., a string as a left +argument to the '%' operator). Extensions must define their own conversion +behavior. .. _atoms: @@ -183,7 +184,7 @@ nesting from left to right, and evaluating the expression to produce an element each time the innermost block is reached. Note that the comprehension is executed in a separate scope, so names assigned -to in the target list don't "leak" in the enclosing scope. +to in the target list don't "leak" into the enclosing scope. .. _lists: @@ -293,7 +294,7 @@ for comprehensions, except that it is enclosed in parentheses instead of brackets or curly braces. Variables used in the generator expression are evaluated lazily when the -:meth:`~generator.__next__` method is called for generator object (in the same +:meth:`~generator.__next__` method is called for the generator object (in the same fashion as normal generators). However, the leftmost :keyword:`for` clause is immediately evaluated, so that an error produced by it can be seen before any other possible error in the code that handles the generator expression. @@ -302,7 +303,7 @@ may depend on the previous :keyword:`for` loop. For example: ``(x*y for x in range(10) for y in bar(x))``. The parentheses can be omitted on calls with only one argument. See section -:ref:`calls` for the detail. +:ref:`calls` for details. .. _yieldexpr: @@ -327,12 +328,12 @@ When a generator function is called, it returns an iterator known as a generator. That generator then controls the execution of a generator function. The execution starts when one of the generator's methods is called. At that time, the execution proceeds to the first yield expression, where it is -suspended again, returning the value of :token:`expression_list` to generator's +suspended again, returning the value of :token:`expression_list` to the generator's caller. By suspended, we mean that all local state is retained, including the current bindings of local variables, the instruction pointer, and the internal evaluation stack. When the execution is resumed by calling one of the generator's methods, the function can proceed exactly as if the yield expression -was just another external call. The value of the yield expression after +were just another external call. The value of the yield expression after resuming depends on the method which resumed the execution. If :meth:`~generator.__next__` is used (typically via either a :keyword:`for` or the :func:`next` builtin) then the result is :const:`None`. Otherwise, if @@ -344,10 +345,10 @@ that method. All of this makes generator functions quite similar to coroutines; they yield multiple times, they have more than one entry point and their execution can be suspended. The only difference is that a generator function cannot control -where should the execution continue after it yields; the control is always +where the execution should continue after it yields; the control is always transferred to the generator's caller. -yield expressions are allowed in the :keyword:`try` clause of a :keyword:`try` +Yield expressions are allowed in the :keyword:`try` clause of a :keyword:`try` ... :keyword:`finally` construct. If the generator is not resumed before it is finalized (by reaching a zero reference count or by being garbage collected), the generator-iterator's :meth:`~generator.close` method will be called, @@ -430,7 +431,7 @@ is already executing raises a :exc:`ValueError` exception. .. method:: generator.throw(type[, value[, traceback]]) - Raises an exception of type ``type`` at the point where generator was paused, + Raises an exception of type ``type`` at the point where the generator was paused, and returns the next value yielded by the generator function. If the generator exits without yielding another value, a :exc:`StopIteration` exception is raised. If the generator function does not catch the passed-in exception, or @@ -520,11 +521,11 @@ An attribute reference is a primary followed by a period and a name: The primary must evaluate to an object of a type that supports attribute references, which most objects do. This object is then asked to produce the -attribute whose name is the identifier (which can be customized by overriding -the :meth:`__getattr__` method). If this attribute is not available, the -exception :exc:`AttributeError` is raised. Otherwise, the type and value of the -object produced is determined by the object. Multiple evaluations of the same -attribute reference may yield different objects. +attribute whose name is the identifier. This production can be customized by +overriding the :meth:`__getattr__` method). If this attribute is not available, +the exception :exc:`AttributeError` is raised. Otherwise, the type and value of +the object produced is determined by the object. Multiple evaluations of the +same attribute reference may yield different objects. .. _subscriptions: @@ -549,9 +550,9 @@ A subscription selects an item of a sequence (string, tuple or list) or mapping .. productionlist:: subscription: `primary` "[" `expression_list` "]" -The primary must evaluate to an object that supports subscription, e.g. a list -or dictionary. User-defined objects can support subscription by defining a -:meth:`__getitem__` method. +The primary must evaluate to an object that supports subscription (lists or +dictionaries for example). User-defined objects can support subscription by +defining a :meth:`__getitem__` method. For built-in objects, there are two types of objects that support subscription: @@ -660,8 +661,8 @@ series of :term:`arguments `: keyword_arguments: `keyword_item` ("," `keyword_item`)* keyword_item: `identifier` "=" `expression` -A trailing comma may be present after the positional and keyword arguments but -does not affect the semantics. +An optional trailing comma may be present after the positional and keyword arguments +but does not affect the semantics. .. index:: single: parameter; call semantics @@ -943,9 +944,9 @@ point number using the :func:`abs` function if appropriate. .. index:: single: addition The ``+`` (addition) operator yields the sum of its arguments. The arguments -must either both be numbers or both sequences of the same type. In the former -case, the numbers are converted to a common type and then added together. In -the latter case, the sequences are concatenated. +must either both be numbers or both be sequences of the same type. In the +former case, the numbers are converted to a common type and then added together. +In the latter case, the sequences are concatenated. .. index:: single: subtraction @@ -1106,7 +1107,7 @@ Comparison of objects of the same type depends on the type: another one is made arbitrarily but consistently within one execution of a program. -Comparison of objects of the differing types depends on whether either of the +Comparison of objects of differing types depends on whether either of the types provide explicit support for the comparison. Most numeric types can be compared with one another. When cross-type comparison is not supported, the comparison method returns ``NotImplemented``. @@ -1116,7 +1117,7 @@ comparison method returns ``NotImplemented``. The operators :keyword:`in` and :keyword:`not in` test for membership. ``x in s`` evaluates to true if *x* is a member of *s*, and false otherwise. ``x not in s`` returns the negation of ``x in s``. All built-in sequences and set types -support this as well as dictionary, for which :keyword:`in` tests whether a the +support this as well as dictionary, for which :keyword:`in` tests whether the dictionary has a given key. For container types such as list, tuple, set, frozenset, dict, or collections.deque, the expression ``x in y`` is equivalent to ``any(x is e or x == e for e in y)``. @@ -1202,9 +1203,9 @@ returned; otherwise, *y* is evaluated and the resulting value is returned. they return to ``False`` and ``True``, but rather return the last evaluated argument. This is sometimes useful, e.g., if ``s`` is a string that should be replaced by a default value if it is empty, the expression ``s or 'foo'`` yields -the desired value. Because :keyword:`not` has to invent a value anyway, it does -not bother to return a value of the same type as its argument, so e.g., ``not -'foo'`` yields ``False``, not ``''``.) +the desired value. Because :keyword:`not` has to create a new value, it +returns a boolean value regardless of the type of its argument +(for example, ``not 'foo'`` produces ``False`` rather than ``''``.) Conditional expressions @@ -1222,8 +1223,8 @@ Conditional expressions Conditional expressions (sometimes called a "ternary operator") have the lowest priority of all Python operations. -The expression ``x if C else y`` first evaluates the condition, *C* (*not* *x*); -if *C* is true, *x* is evaluated and its value is returned; otherwise, *y* is +The expression ``x if C else y`` first evaluates the condition, *C* rather than *x*. +If *C* is true, *x* is evaluated and its value is returned; otherwise, *y* is evaluated and its value is returned. See :pep:`308` for more details about conditional expressions. @@ -1244,10 +1245,9 @@ Lambdas lambda_expr: "lambda" [`parameter_list`]: `expression` lambda_expr_nocond: "lambda" [`parameter_list`]: `expression_nocond` -Lambda expressions (sometimes called lambda forms) have the same syntactic position as -expressions. They are a shorthand to create anonymous functions; the expression -``lambda arguments: expression`` yields a function object. The unnamed object -behaves like a function object defined with :: +Lambda expressions (sometimes called lambda forms) are create anonymous +functions. The expression ``lambda arguments: expression`` yields a function +object. The unnamed object behaves like a function object defined with :: def (arguments): return expression @@ -1310,13 +1310,15 @@ Operator precedence .. index:: pair: operator; precedence -The following table summarizes the operator precedences in Python, from lowest +The following table summarizes the operator precedence in Python, from lowest precedence (least binding) to highest precedence (most binding). Operators in the same box have the same precedence. Unless the syntax is explicitly given, operators are binary. Operators in the same box group left to right (except for -comparisons, including tests, which all have the same precedence and chain from -left to right --- see section :ref:`comparisons` --- and exponentiation, which -groups from right to left). +exponentiation, which groups from right to left). + +Note that comparisons, membership tests, and identity tests, all have the same +precedence and have a left-to-right chaining feature as described in the +:ref:`comparisons` section. +-----------------------------------------------+-------------------------------------+ diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index 66c234c6b28..1748d5ad7d0 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -7,7 +7,7 @@ Simple statements .. index:: pair: simple; statement -Simple statements are comprised within a single logical line. Several simple +A simple statement is comprised within a single logical line. Several simple statements may occur on a single line separated by semicolons. The syntax for simple statements is: @@ -91,8 +91,8 @@ attributes or items of mutable objects: : | `slicing` : | "*" `target` -(See section :ref:`primaries` for the syntax definitions for the last three -symbols.) +(See section :ref:`primaries` for the syntax definitions for *attributeref*, +*subscription*, and *slicing*.) An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and @@ -228,7 +228,7 @@ Assignment of an object to a single target is recursively defined as follows. inclusive. Finally, the sequence object is asked to replace the slice with the items of the assigned sequence. The length of the slice may be different from the length of the assigned sequence, thus changing the length of the - target sequence, if the object allows it. + target sequence, if the target sequence allows it. .. impl-detail:: @@ -236,14 +236,15 @@ Assignment of an object to a single target is recursively defined as follows. as for expressions, and invalid syntax is rejected during the code generation phase, causing less detailed error messages. -WARNING: Although the definition of assignment implies that overlaps between the -left-hand side and the right-hand side are 'safe' (for example ``a, b = b, a`` -swaps two variables), overlaps *within* the collection of assigned-to variables -are not safe! For instance, the following program prints ``[0, 2]``:: +Although the definition of assignment implies that overlaps between the +left-hand side and the right-hand side are 'simultanenous' (for example ``a, b = +b, a`` swaps two variables), overlaps *within* the collection of assigned-to +variables occur left-to-right, sometimes resulting in confusion. For instance, +the following program prints ``[0, 2]``:: x = [0, 1] i = 0 - i, x[i] = 1, 2 + i, x[i] = 1, 2 # i is updated, then x[i] is updated print(x) @@ -283,7 +284,7 @@ operation and an assignment statement: augop: "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**=" : | ">>=" | "<<=" | "&=" | "^=" | "|=" -(See section :ref:`primaries` for the syntax definitions for the last three +(See section :ref:`primaries` for the syntax definitions of the last three symbols.) An augmented assignment evaluates the target (which, unlike normal assignment @@ -297,6 +298,11 @@ version, ``x`` is only evaluated once. Also, when possible, the actual operation is performed *in-place*, meaning that rather than creating a new object and assigning that to the target, the old object is modified instead. +Unlike normal assignments, augmented assignments evaluate the left-hand side +*before* evaluating the right-hand side. For example, ``a[i] += f(x)`` first +looks-up ``a[i]``, then it evaluates ``f(x)`` and performs the addition, and +lastly, it writes the result back to ``a[i]``. + With the exception of assigning to tuples and multiple targets in a single statement, the assignment done by augmented assignment statements is handled the same way as normal assignments. Similarly, with the exception of the possible @@ -658,7 +664,7 @@ commas) the two steps are carried out separately for each clause, just as though the clauses had been separated out into individiual import statements. -The details of the first step, finding and loading modules is described in +The details of the first step, finding and loading modules are described in greater detail in the section on the :ref:`import system `, which also describes the various types of packages and modules that can be imported, as well as all the hooks that can be used to customize @@ -689,7 +695,7 @@ available in the local namespace in one of three ways: The :keyword:`from` form uses a slightly more complex process: -#. find the module specified in the :keyword:`from` clause loading and +#. find the module specified in the :keyword:`from` clause, loading and initializing it if necessary; #. for each of the identifiers specified in the :keyword:`import` clauses: @@ -697,7 +703,7 @@ The :keyword:`from` form uses a slightly more complex process: #. if not, attempt to import a submodule with that name and then check the imported module again for that attribute #. if the attribute is not found, :exc:`ImportError` is raised. - #. otherwise, a reference to that value is bound in the local namespace, + #. otherwise, a reference to that value is stored in the local namespace, using the name in the :keyword:`as` clause if it is present, otherwise using the attribute name @@ -726,9 +732,9 @@ to avoid accidentally exporting items that are not part of the API (such as library modules which were imported and used within the module). The :keyword:`from` form with ``*`` may only occur in a module scope. The wild -card form of import --- ``import *`` --- is only allowed at the module level. -Attempting to use it in class or function definitions will raise a -:exc:`SyntaxError`. +card form of import --- ``from module import *`` --- is only allowed at the +module level. Attempting to use it in class or function definitions will raise +a :exc:`SyntaxError`. .. index:: single: relative; import @@ -747,7 +753,7 @@ import mod`` from within ``pkg.subpkg1`` you will import ``pkg.subpkg2.mod``. The specification for relative imports is contained within :pep:`328`. :func:`importlib.import_module` is provided to support applications that -determine which modules need to be loaded dynamically. +determine dynamically the modules to be loaded. .. _future: @@ -759,10 +765,12 @@ Future statements A :dfn:`future statement` is a directive to the compiler that a particular module should be compiled using syntax or semantics that will be available in a -specified future release of Python. The future statement is intended to ease -migration to future versions of Python that introduce incompatible changes to -the language. It allows use of the new features on a per-module basis before -the release in which the feature becomes standard. +specified future release of Python where the feature becomes standard. + +The future statement is intended to ease migration to future versions of Python +that introduce incompatible changes to the language. It allows use of the new +features on a per-module basis before the release in which the feature becomes +standard. .. productionlist:: * future_statement: "from" "__future__" "import" feature ["as" name] @@ -857,7 +865,7 @@ definition, function definition, or :keyword:`import` statement. .. impl-detail:: - The current implementation does not enforce the latter two restrictions, but + The current implementation does not enforce the two restrictions, but programs should not abuse this freedom, as future implementations may enforce them or silently change the meaning of the program. @@ -890,16 +898,16 @@ The :keyword:`nonlocal` statement : | "nonlocal" identifier augop expression_list The :keyword:`nonlocal` statement causes the listed identifiers to refer to -previously bound variables in the nearest enclosing scope. This is important -because the default behavior for binding is to search the local namespace -first. The statement allows encapsulated code to rebind variables outside of -the local scope besides the global (module) scope. +previously bound variables in the nearest enclosing scope excluding globals. +This is important because the default behavior for binding is to search the +local namespace first. The statement allows encapsulated code to rebind +variables outside of the local scope besides the global (module) scope. .. XXX not implemented The :keyword:`nonlocal` statement may prepend an assignment or augmented assignment, but not an expression. -Names listed in a :keyword:`nonlocal` statement, unlike to those listed in a +Names listed in a :keyword:`nonlocal` statement, unlike those listed in a :keyword:`global` statement, must refer to pre-existing bindings in an enclosing scope (the scope in which a new binding should be created cannot be determined unambiguously).