From be2aa58fdc29cf13aabff6d6712e7853e94e88f8 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Wed, 11 Sep 2019 08:12:09 -0700 Subject: [PATCH] bpo-35224: Additional documentation for Assignment Expressions (GH-15935) (GH-15967) Add or update assignment expression documentation for: - FAQ - Design - Reference - Expressions - Reference - Lexical Analysis https://bugs.python.org/issue35224 Automerge-Triggered-By: @matrixise (cherry picked from commit 6357c95716d89ac1f80587fbc4133df8d2e8396c) Co-authored-by: Emily Morehouse --- Doc/faq/design.rst | 63 +++--------------------------- Doc/reference/expressions.rst | 2 + Doc/reference/lexical_analysis.rst | 2 +- Doc/whatsnew/3.8.rst | 2 - 4 files changed, 9 insertions(+), 60 deletions(-) diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index e2d63a0323d..81c0f474ac1 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -149,66 +149,15 @@ to tell Python which namespace to use. Why can't I use an assignment in an expression? ----------------------------------------------- -Many people used to C or Perl complain that they want to use this C idiom: +Starting in Python 3.8, you can! -.. code-block:: c +Assignment expressions using the walrus operator `:=` assign a variable in an +expression:: - while (line = readline(f)) { - // do something with line - } + while chunk := fp.read(200): + print(chunk) -where in Python you're forced to write this:: - - while True: - line = f.readline() - if not line: - break - ... # do something with line - -The reason for not allowing assignment in Python expressions is a common, -hard-to-find bug in those other languages, caused by this construct: - -.. code-block:: c - - if (x = 0) { - // error handling - } - else { - // code that only works for nonzero x - } - -The error is a simple typo: ``x = 0``, which assigns 0 to the variable ``x``, -was written while the comparison ``x == 0`` is certainly what was intended. - -Many alternatives have been proposed. Most are hacks that save some typing but -use arbitrary or cryptic syntax or keywords, and fail the simple criterion for -language change proposals: it should intuitively suggest the proper meaning to a -human reader who has not yet been introduced to the construct. - -An interesting phenomenon is that most experienced Python programmers recognize -the ``while True`` idiom and don't seem to be missing the assignment in -expression construct much; it's only newcomers who express a strong desire to -add this to the language. - -There's an alternative way of spelling this that seems attractive but is -generally less robust than the "while True" solution:: - - line = f.readline() - while line: - ... # do something with line... - line = f.readline() - -The problem with this is that if you change your mind about exactly how you get -the next line (e.g. you want to change it into ``sys.stdin.readline()``) you -have to remember to change two places in your program -- the second occurrence -is hidden at the bottom of the loop. - -The best approach is to use iterators, making it possible to loop through -objects using the ``for`` statement. For example, :term:`file objects -` support the iterator protocol, so you can write simply:: - - for line in f: - ... # do something with line... +See :pep:`572` for more information. diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 73a2f271ca5..d9db33a7856 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -1784,6 +1784,8 @@ precedence and have a left-to-right chaining feature as described in the +-----------------------------------------------+-------------------------------------+ | Operator | Description | +===============================================+=====================================+ +| ``:=`` | Assignment expression | ++-----------------------------------------------+-------------------------------------+ | :keyword:`lambda` | Lambda expression | +-----------------------------------------------+-------------------------------------+ | :keyword:`if ` -- :keyword:`!else` | Conditional expression | diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index 7e1e17edb2d..c0e13b53698 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -887,7 +887,7 @@ The following tokens are operators: + - * ** / // % @ - << >> & | ^ ~ + << >> & | ^ ~ := < > <= >= == != diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index aefe9b53746..c2455f487b1 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -122,8 +122,6 @@ See :pep:`572` for a full description. (Contributed by Emily Morehouse in :issue:`35224`.) -.. TODO: Emily will sprint on docs at PyCon US 2019. - Positional-only parameters --------------------------