@@ -25,21 +25,21 @@ is a conditional return (or break etc.) inside a finally block.".
2525Abstract
2626========
2727
28- This PEP proposes to forbid return, break and continue statements within
29- a finally suite where they would break out of the finally. Their use in
28+ This PEP proposes to forbid `` return``, `` break`` and `` continue`` statements within
29+ a `` finally`` suite where they would break out of the `` finally`` . Their use in
3030such a location silently cancels any active exception being raised through
31- the finally, leading to unclear code and possible bugs.
31+ the `` finally`` , leading to unclear code and possible bugs.
3232
33- Continue is currently not supported in a finally in Python 3.7 (due to
33+ ``continue`` is currently not supported in a `` finally`` in Python 3.7 (due to
3434implementation issues) and the proposal is to not add support for it in
35- Python 3.8. For return and break the proposal is to deprecate their use
35+ Python 3.8. For `` return`` and `` break`` the proposal is to deprecate their use
3636in Python 3.9, emit a compilation warning in Python 3.10 and then forbid
3737their use after that.
3838
3939Motivation
4040==========
4141
42- The use of return, break and continue within a finally suite leads to behaviour
42+ The use of `` return``, `` break`` and `` continue`` within a `` finally`` suite leads to behaviour
4343which is not at all obvious. Consider the following function::
4444
4545 def foo():
@@ -49,9 +49,9 @@ which is not at all obvious. Consider the following function::
4949 return
5050
5151This will return cleanly (without an exception) even though it has infinite
52- recursion and raises an exception within the try. The reason is that the return
53- within the finally will silently cancel any exception that propagates through
54- the finally suite. Such behaviour is unexpected and not at all obvious.
52+ recursion and raises an exception within the `` try`` . The reason is that the `` return``
53+ within the `` finally`` will silently cancel any exception that propagates through
54+ the `` finally`` suite. Such behaviour is unexpected and not at all obvious.
5555This function is equivalent to::
5656
5757 def foo():
@@ -61,8 +61,8 @@ This function is equivalent to::
6161 pass
6262 return
6363
64- Break and continue have similar behaviour (they silence exceptions) if they
65- jump to code outside the finally suite. For example::
64+ ``break`` and `` continue`` have similar behaviour (they silence exceptions) if they
65+ jump to code outside the `` finally`` suite. For example::
6666
6767 def bar():
6868 while True:
@@ -83,55 +83,55 @@ This behaviour goes against the following parts of The Zen of Python:
8383If this behaviour of silencing exceptions is really needed then the explicit
8484form of a try-except can be used instead, and this makes the code clearer.
8585
86- Independent to the semantics, implementing return/ break/ continue within a
87- finally suite is non-trivial as it requires to correctly track any active
88- exceptions at runtime (an executing finally suite may or may not have an
86+ Independent to the semantics, implementing `` return``/`` break``/`` continue`` within a
87+ `` finally`` suite is non-trivial as it requires to correctly track any active
88+ exceptions at runtime (an executing `` finally`` suite may or may not have an
8989active exception) and cancel them as appropriate. CPython did have a bug in
90- this for the case of continue and so originally disallowed it [1]. Requiring
91- correct behaviour for return/ break/ continue within a finally puts an
90+ this for the case of `` continue`` and so originally disallowed it [1]_ . Requiring
91+ correct behaviour for `` return``/`` break``/`` continue`` within a `` finally`` puts an
9292unnecessary burden on alternative implementations of Python.
9393
9494Other languages
9595===============
9696
97- Java allows to return from within a finally block, but its use is discouraged
98- according to [2], [3], [4]. The Java compiler later on included a linting
99- option -Xlint:finally to warn against the use of return within a finally block.
97+ Java allows to return from within a `` finally`` block, but its use is discouraged
98+ according to [2]_ , [3]_ , [4]_ . The Java compiler later on included a linting
99+ option `` -Xlint:finally`` to warn against the use of return within a `` finally`` block.
100100The Eclipse editor also warns about this use.
101101
102102Ruby allows return from inside ensure (Python's finally), but it should be an
103- explicit return. It is discouraged and handled by linters [5], [6].
103+ explicit return. It is discouraged and handled by linters [5]_ , [6]_ .
104104
105- Like Ruby, JavaScript also allows use of return/ break/ continue within a finally
106- but it is seen as unsafe and it is handled by eslint [7].
105+ Like Ruby, JavaScript also allows use of `` return``/`` break``/`` continue`` within a `` finally``
106+ but it is seen as unsafe and it is handled by eslint [7]_ .
107107
108- C# forbids the use of ending statements like return/ goto/ break within a finally
109- [8], [9].
108+ C# forbids the use of ending statements like `` return``/`` goto``/`` break`` within a `` finally``
109+ [8]_ , [9]_.
110110
111111Rationale
112112=========
113113
114- Since the behaviour of return/ break/ continue within a finally is unclear, the
114+ Since the behaviour of `` return``/`` break``/`` continue`` within a `` finally`` is unclear, the
115115pattern is rarely used, and there is a simple alternative to writing equivalent
116116code (which is more explicit), forbidding the syntax is the most straightforward
117117approach.
118118
119119Specification
120120=============
121121
122- This is a change to the compiler, not the grammar. The compiler should
123- check for the following in a finally suite:
122+ This is a change to the compiler, not the grammar. The compiler should
123+ check for the following in a `` finally`` suite:
124124
125- * A return in any statement, at any level of nesting.
125+ * A `` return`` in any statement, at any level of nesting.
126126
127- * A break/ continue in any statement, at any level of nesting, that would
128- transfer control flow outside the finally suite.
127+ * A `` break``/`` continue`` in any statement, at any level of nesting, that would
128+ transfer control flow outside the `` finally`` suite.
129129
130130Upon finding such a case it should emit the appropriate exception:
131131
132- * For continue, a SyntaxError (this is the current behaviour of 3.7).
132+ * For `` continue`` , a `` SyntaxError`` (this is the current behaviour of 3.7).
133133
134- * For return/ break, a SyntaxWarning in 3.10, and a SyntaxError after that.
134+ * For `` return``/`` break`` , a `` SyntaxWarning`` in 3.10, and a `` SyntaxError`` after that.
135135
136136For example, the following are all forbidden by this proposal::
137137
@@ -160,26 +160,26 @@ For example, the following are all forbidden by this proposal::
160160 for x in range(10):
161161 return
162162
163- The following is still allowed because the continue doesn't escape the
164- finally::
163+ The following is still allowed because the `` continue`` doesn't escape the
164+ `` finally`` ::
165165
166166 try:
167167 pass
168168 finally:
169169 for x in range(10):
170170 continue
171171
172- Note that yielding from within a finally remains acceptable by this PEP
173- because resuming the generator will resume the finally and eventually
172+ Note that yielding from within a `` finally`` remains acceptable by this PEP
173+ because resuming the generator will resume the `` finally`` and eventually
174174raise any active exceptions (so they are never silenced by yielding).
175175
176176Backwards Compatibility
177177=======================
178178
179- This is a backwards incompatible change, for return and break.
179+ This is a backwards incompatible change, for `` return`` and `` break`` .
180180
181181The following locations in the CPython standard library (at
182- v3.8.0b1-651-g7fcc2088a5) use return within finally:
182+ v3.8.0b1-651-g7fcc2088a5) use `` return`` within `` finally`` :
183183
184184* Lib/subprocess.py:921 - the use here looks like a bug
185185
@@ -189,11 +189,11 @@ v3.8.0b1-651-g7fcc2088a5) use return within finally:
189189* Lib/multiprocessing/connection.py:318 - the use here looks legitimate
190190 but the intention is not clear
191191
192- * Lib/test/test_sys_settrace.py:837 - a test for return within finally
192+ * Lib/test/test_sys_settrace.py:837 - a test for `` return`` within `` finally``
193193
194- * Lib/test/test_sys_settrace.py:1346 - a test for return within finally
194+ * Lib/test/test_sys_settrace.py:1346 - a test for `` return`` within `` finally``
195195
196- There are no uses of break within a finally (that break out of the finally)
196+ There are no uses of `` break`` within a `` finally`` (that break out of the `` finally`` )
197197in the standard library.
198198
199199Security Implications
@@ -207,30 +207,30 @@ How to Teach This
207207
208208This feature is very rarely used so forbidding it will likely only impact
209209advanced users, not beginners and probably not any existing teaching
210- material. Since this is the removal of a feature teaching users will be
211- one by the raising of a SyntaxError if/when the forbidden feature is used.
210+ material. Since this is the removal of a feature teaching users will be
211+ one by the raising of a `` SyntaxError`` if/when the forbidden feature is used.
212212
213213Reference Implementation
214214========================
215215
216216There is currently no reference implementation, although the way continue
217- is currently handled in a finally (raising a SyntaxError) can be extended
218- to return and break.
217+ is currently handled in a `` finally`` (raising a `` SyntaxError`` ) can be extended
218+ to `` return`` and `` break`` .
219219
220220References
221221==========
222222
223- .. [1] https://bugs. python.org/issue37830
223+ .. [1] https://github.com/ python/cpython/issues/82011
224224
225225.. [2] https://stackoverflow.com/questions/48088/returning-from-a-finally-block-in-java
226226
227227.. [3] https://web.archive.org/web/20070922061412/http://weblogs.java.net/blog/staufferjames/archive/2007/06/_dont_return_in.html
228228
229229.. [4] https://wiki.sei.cmu.edu/confluence/display/java/ERR04-J.+Do+not+complete+abruptly+from+a+finally+block
230230
231- .. [5] https://github.com/rubocop-hq /rubocop/issues/5949
231+ .. [5] https://github.com/rubocop/rubocop/issues/5949
232232
233- .. [6] https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Lint/EnsureReturn
233+ .. [6] https://www.rubydoc.info/gems/rubocop/0.74.0/ RuboCop/Cop/Lint/EnsureReturn
234234
235235.. [7] https://eslint.org/docs/rules/no-unsafe-finally
236236
@@ -243,14 +243,3 @@ Copyright
243243
244244This document is placed in the public domain or under the
245245CC0-1.0-Universal license, whichever is more permissive.
246-
247-
248-
249- ..
250- Local Variables:
251- mode: indented-text
252- indent-tabs-mode: nil
253- sentence-end-double-space: t
254- fill-column: 70
255- coding: utf-8
256- End:
0 commit comments