classification
Title: Documentation on try statement incorrectly implies target of except clause can be any assignable expression
Type: behavior Stage: resolved
Components: Documentation Versions: Python 3.4, Python 3.5, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: docs@python Nosy List: docs@python, jayanthkoushik, mwilliamson, python-dev, terry.reedy
Priority: normal Keywords: easy

Created on 2014-08-21 15:55 by mwilliamson, last changed 2014-08-23 23:31 by terry.reedy. This issue is now closed.

Messages (10)
msg225611 - (view) Author: Michael Williamson (mwilliamson) Date: 2014-08-21 15:55
In the docs for the try statement [1], part of the grammar is:

try1_stmt ::=  "try" ":" suite
               ("except" [expression ["as" target]] ":" suite)+
               ["else" ":" suite]
               ["finally" ":" suite]

The `target` rule allows any assignable expression (identifier, attributes, etc.). However, CPython appears to only allow identifiers as a target. The abstract grammar in the ast module [2] appears to confirm this.

[1] https://docs.python.org/3.4/reference/compound_stmts.html#the-try-statement
[2] https://docs.python.org/3.4/library/ast.html#abstract-grammar
msg225616 - (view) Author: Jayanth Koushik (jayanthkoushik) Date: 2014-08-21 20:51
Yes. Seems to be a documentation error. The full grammar specification [1] uses 'NAME' instead of 'target'.

[1]: https://docs.python.org/3/reference/grammar.html
msg225650 - (view) Author: Jayanth Koushik (jayanthkoushik) Date: 2014-08-22 07:38
The whole page on compound statements seems to be rife with inconsistencies.
msg225712 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-08-22 20:59
I think 'target' can just be replaced by 'identifier'.
Using 'expression' (or 'expr' in the ast doc) for what should be 'exceptions: identifier' or paranthesized tuple of identifiers;, is also too broad. However, that must be enforced in the compiler rather than the parser, and compiler restrictions are in the text, not the grammar.
msg225713 - (view) Author: Michael Williamson (mwilliamson) Date: 2014-08-22 21:10
> Using 'expression' (or 'expr' in the ast doc) for what should be 'exceptions: identifier' or paranthesized tuple of identifiers;, is also too broad. However, that must be enforced in the compiler rather than the parser, and compiler restrictions are in the text, not the grammar.

I would expect any expression to be valid so long as it evaluates at runtime to an exception type (or tuple of exception types), so the use of expression seems correct to me. In other words, the following is valid Python (but would not be allowed if I've understood your statement correctly):

    def f():
        try:
            "".blah
        except some_error():
            print("caught")
            
    def some_error():
        return AttributeError

    f()
msg225717 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-08-22 22:54
You are right, only the result, and not the form of 'expression' is constrained. I will let Jayanth propose other errors.
msg225732 - (view) Author: Jayanth Koushik (jayanthkoushik) Date: 2014-08-23 05:30
The page on compound statements defines compound statements as:

compound_stmt ::=  if_stmt
                   | while_stmt
                   | for_stmt
                   | try_stmt
                   | with_stmt
                   | funcdef
                   | classdef

The full grammar specification on the other hand says:

compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated

This accordingly leads to different definitions of funcdef and classdef. This is not necessarily 'incorrect', but for the sake of clarity, it might be better if both pages followed the same conventions.
msg225753 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-08-23 17:36
The grammar presented in the doc is intentionally slightly simplified from the one actually used by the LL(1) parser.  The parser has to know what type of statement it is parsing after the first token or so, so it needs a separate production (concept) for statements that start with '@'.  Human readers are more capable and can look backwards from 'def' and 'class'.

A separate section on 'Decorated statements' would be possible, but not necessarily better. A section of 'Decorators' (without calling them 'statements') would be slightly different and also possible.  Discussion would have to start on Python ideas and any action a separate issue.
msg225754 - (view) Author: Jayanth Koushik (jayanthkoushik) Date: 2014-08-23 17:46
Oh ok. That makes sense.
msg225770 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2014-08-23 23:30
New changeset 5496bf8972b6 by Terry Jan Reedy in branch '2.7':
Issue #22243: fix except grammar in reference.
http://hg.python.org/cpython/rev/5496bf8972b6

New changeset a249f1f879be by Terry Jan Reedy in branch '3.4':
Issue #22243: fix except grammar in reference.
http://hg.python.org/cpython/rev/a249f1f879be
History
Date User Action Args
2014-08-23 23:31:28terry.reedysetstatus: open -> closed
type: enhancement -> behavior
resolution: fixed
stage: resolved
2014-08-23 23:30:53python-devsetnosy: + python-dev
messages: + msg225770
2014-08-23 17:46:00jayanthkoushiksetmessages: + msg225754
2014-08-23 17:36:36terry.reedysetmessages: + msg225753
2014-08-23 05:30:43jayanthkoushiksetmessages: + msg225732
2014-08-22 22:54:26terry.reedysetmessages: + msg225717
2014-08-22 21:10:44mwilliamsonsetmessages: + msg225713
2014-08-22 20:59:43terry.reedysetnosy: + terry.reedy
messages: + msg225712
2014-08-22 07:38:56jayanthkoushiksetmessages: + msg225650
2014-08-22 06:29:44benjamin.petersonsetkeywords: + easy
versions: + Python 2.7
2014-08-21 20:51:56jayanthkoushiksettype: enhancement

messages: + msg225616
nosy: + jayanthkoushik
2014-08-21 15:55:55mwilliamsoncreate