homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Raise a Py3K warning for catching non-BaseException exceptions
Type: behavior Stage:
Components: None Versions: Python 2.6
process
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: gvanrossum Nosy List: belopolsky, brett.cannon, gvanrossum, nnorwitz, taicki, zotbar1234
Priority: critical Keywords:

Created on 2008年03月14日 22:19 by zotbar1234, last changed 2022年04月11日 14:56 by admin. This issue is now closed.

Messages (15)
msg63538 - (view) Author: Schnappi (zotbar1234) Date: 2008年03月14日 22:19
I have discovered the following behaviour in 2.5, which I cannot explain:
>>> try:
... raise ValueError("foo")
... except object:
... print "aiee!"
... 
Traceback (most recent call last):
 File "<stdin>", line 2, in <module>
ValueError: foo
>>> sys.version
'2.5.1 (r251:54863, Jan 23 2008, 16:53:41) \n[GCC 4.2.2 (Gentoo 4.2.2
p1.0)]'
>>> isinstance(ValueError("foo"), object)
True
At first I thought I misunderstood something about exceptions, but the
wording of the try-statement leads me to believe that this should work.
ValueError is a subclass of object and thus, I think, should be a match,
thus catching the exception.
I realize that all exceptions should inherit from Exception
(BaseException?), but for the sake of consistence, shouldn't "except
object" catch *anything* in python 2.5? I.e. be the equivalent of "except:".
Is this a bug? If so, should this be fixed?
msg63543 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008年03月15日 02:58
Py3k behavior seems to be better:
Python 3.0a2+ (py3k:61137M, Feb 29 2008, 15:17:29) 
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
>>> try: 
... raise ValueError("foo")
... except object:
... pass
... 
Traceback (most recent call last):
 File "<stdin>", line 3, in <module>
TypeError: catching classes that do not inherit from BaseException is 
not allowed
Something needs to be done for 2.6: at the minimum a warning should be 
issued under -3 option.
msg63565 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2008年03月15日 22:30
See PEP 352. Currently this is slated for python 2.8. Perhaps the
schedule should be sped up a bit in light the current release schedule.
 Brett, any comments? We should add all the warnings from PEP 352 with
the -3 flag to 2.6.
msg63569 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2008年03月16日 03:00
On Sat, Mar 15, 2008 at 5:30 PM, Neal Norwitz <report@bugs.python.org> wrote:
>
> Neal Norwitz <nnorwitz@gmail.com> added the comment:
>
> See PEP 352. Currently this is slated for python 2.8. Perhaps the
> schedule should be sped up a bit in light the current release schedule.
> Brett, any comments? We should add all the warnings from PEP 352 with
> the -3 flag to 2.6.
We could add warnings for everything slated to go in 3.0. As for 2.x,
I don't think tossing in warnings for 2.6 is good, but it could be
made a PendingDeprecationWarning, with 2.7 being full
DeprecationWarning.
msg63584 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008年03月16日 16:33
I thought some more about this issue and the current behavior seems 
wrong and potentially dangerous. Consider the following code:
class x: 
 pass 
class y(x): 
 pass 
try: 
 raise y 
except y: 
 print "a" 
except: 
 print "b" 
It prints 'b'. Now, suppose in preparation for 3.0 transition someone 
adds "__metaclass__ = type" to the module with that code. The result: 
it prints 'a'. Since the difference in behavior is in error handling 
code, which in my experience is often not thoroughly tested, the bug 
introduced by a seemingly innocuous move from old to new style classes 
is likely to trigger in the worst possible moment. (For example a wrong 
roll-back logic is applied after a failed database commit.)
My understanding is that the current logic of bypassing the subclass 
check in PyErr_GivenExceptionMatches in the case of new style class 
which is not a subclass of BaseException, is designed to support string 
exceptions. Maybe a better choice would be to exclude only string 
subclasses from a subclass check.
I will submit a patch if others agree that this approach is worth 
considering.
msg63585 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2008年03月16日 16:53
Actually, if you go back to 2.4, before BaseException even existed, a
try/except with a new-style class in the 'except' clause was also
possible. Actual enforcement of what can be in an 'except' clause is a
new thing added by PEP 352. Suddenly making this any more than a warning
will be too aggressive. And the PEP already stated the transition path.
As I said, I have no problem speeding up PendingDeprecationWarnings in
2.6 and adding Py3K warnings now, but anything more severe in 2.6 (i.e.,
a DeprecationWarning flat-out) would require python-dev approval.
msg63783 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008年03月17日 21:25
I am commenting on issue2371 patch here, so that I does not get lost in
a non-showstopper issue. Taek, please reattach your patch here when you
get a chance.
With the additional -3 logic, code duplication between tuple and
non-tuple case becomes unbearable. I suggest separating both string and
subclass checks in a separate function.
msg63785 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008年03月17日 21:40
There is also a subtle bug in the issue2371 patch:
$ cat x.py
try:
 raise ValueError
except ((ValueError,),):
 pass
$ ./python -3 x.py
x.py:3: DeprecationWarning: catching classes that do not inherit from
BaseException is not allowed in 3.x.
 except ((ValueError,),):
I am not sure if it would be acceptable to move warnings to
PyErr_GivenExceptionMatches, but if not, the checking logic should
reproduce PyErr_GivenExceptionMatches' recursive behavior.
msg63809 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008年03月18日 00:00
Correction for msg63584: the old/new style difference example should read
"""
class x: 
 pass 
class y(x): 
 pass 
try: 
 raise y 
except y: 
 print "b" 
except: 
 print "a"
"""
As written it prints 'b', but with __metaclass__ = type, it prints 'a'.
In msg63584 I got 'a' and 'b' mixed up.
On python-dev, Guido responded that the result should be the same
regardless of the metaclass:
http://mail.python.org/pipermail/python-dev/2008-March/077713.html 
msg63846 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008年03月18日 02:18
I finally figured this out. The try/except statement is a complete red
herring; the problem is in the raise statement. The behavior is the
same in 2.4, 2.5 and 2.6, even though Exception is a classic class in
2.4 and a new-style class in 2.5 and 2.6.
The rules are relatively straightforward, and explain all observations,
once you realize that attempting to raise something that is not allowed
raises a TypeError:
- you can raise strings (except in 2.6 -- see footnote)
- you can raise any classic class
- you can raise any class that derives from [Base]Exception
(That last rule is subtle, due to standard exceptions changing from
classic to new-style in 2.5.)
I do not believe that there is anything wrong in this set of rules, and
would object to a change that would allow raising any new-style class in
2.6, since this would be a temporary relaxation of the rules, whereas in
3.0 we will be significantly *tightening* the rules!
PEP 352 states that in Python 2.7 we will deprecate raising exceptions
that don't derive from BaseException; in 2.8 we will deprecate catching
those; and 2.9 we may deprecate __getitem__ on exceptions. This was
written before 3.0 was really planned; IMO we should have "-3" warnings
for all these things in 2.6. This implies that "except object:" will
get a -3 warning -- but not a deprecation warning.
I do recommend that these rules be documented more clearly.
(Footnote: if I read PEP 352 carefully, I don't believe raising strings
was supposed to be disallowed before 3.0. I'm not sure it's worth
reverting this though.)
msg63853 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008年03月18日 02:47
What is the pronouncement on the OP's issue? While "except object:" is 
still valid, should it catch anything?
msg63858 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008年03月18日 03:00
"except object:" will continue to be a no-op, if only for compatibility.
With -3 it will issue a warning (I just checked this in, from
issue2371). With -3 -Werror it will be an error.
We still need patches to issue -3 warnings for:
- raising exceptions that don't derive from BaseException
- __getitem__ or __getslice__ on exception instances
msg63862 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008年03月18日 03:09
On Mon, Mar 17, 2008 at 11:00 PM, Guido van Rossum
<report@bugs.python.org> wrote:
..
> - raising exceptions that don't derive from BaseException
See patch at issue2341.
msg63868 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008年03月18日 03:18
On Mon, Mar 17, 2008 at 11:00 PM, Guido van Rossum
<report@bugs.python.org> wrote:
> We still need patches to issue -3 warnings for:
> - __getitem__ or __getslice__ on exception instances
>
I've opened a separate issue for this (see issue2379). I believe this
issue can now be closed.
msg63879 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008年03月18日 04:03
Thanks!
History
Date User Action Args
2022年04月11日 14:56:31adminsetgithub: 46544
2008年03月18日 04:03:23gvanrossumsetstatus: open -> closed
resolution: accepted
messages: + msg63879
2008年03月18日 03:18:13belopolskysetmessages: + msg63868
2008年03月18日 03:09:09belopolskysetmessages: + msg63862
2008年03月18日 03:00:06gvanrossumsetmessages: + msg63858
2008年03月18日 02:47:05belopolskysetmessages: + msg63853
2008年03月18日 02:18:27gvanrossumsetassignee: gvanrossum
messages: + msg63846
nosy: + gvanrossum
2008年03月18日 00:00:21belopolskysetmessages: + msg63809
2008年03月17日 21:40:14belopolskysetmessages: + msg63785
2008年03月17日 21:25:09belopolskysetnosy: + taicki
messages: + msg63783
2008年03月17日 20:11:11brett.cannonsetpriority: release blocker -> critical
2008年03月17日 18:01:01brett.cannonsetpriority: release blocker
title: Catching all exceptions with 'object' -> Raise a Py3K warning for catching non-BaseException exceptions
2008年03月16日 16:53:04brett.cannonsetmessages: + msg63585
2008年03月16日 16:33:49belopolskysetmessages: + msg63584
2008年03月16日 03:00:03brett.cannonsetmessages: + msg63569
2008年03月15日 22:30:21nnorwitzsetnosy: + nnorwitz, brett.cannon
messages: + msg63565
versions: + Python 2.6, - Python 2.5
2008年03月15日 02:59:00belopolskysetnosy: + belopolsky
messages: + msg63543
2008年03月14日 22:19:14zotbar1234create

AltStyle によって変換されたページ (->オリジナル) /