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.
Created on 2011年05月08日 08:53 by acooke, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| issue12029.patch | gcbirzan, 2012年05月12日 10:48 | review | ||
| exception_proper_subclass_matching_v2.patch | georg.brandl, 2014年10月02日 10:09 | review | ||
| exception_proper_subclass_matching_v3.patch | georg.brandl, 2014年10月02日 10:20 | review | ||
| pyobject_issubclass_isinstance_speedup.patch | georg.brandl, 2014年10月02日 11:29 | review | ||
| exception_proper_subclass_matching_v4.patch | georg.brandl, 2014年10月02日 11:29 | review | ||
| Pull Requests | |||
|---|---|---|---|
| URL | Status | Linked | Edit |
| PR 6461 | closed | Michael McCoy, 2018年04月13日 20:13 | |
| PR 32027 | merged | iritkatriel, 2022年03月21日 11:57 | |
| PR 32034 | merged | iritkatriel, 2022年03月21日 20:51 | |
| PR 32035 | merged | iritkatriel, 2022年03月21日 21:03 | |
| Messages (51) | |||
|---|---|---|---|
| msg135521 - (view) | Author: andrew cooke (acooke) | Date: 2011年05月08日 08:53 | |
Hi, In general, registering a class with an ABC is equivalent to making it a subclass (isinstance and issubclass are patched through ABCMeta). However, this does not work for exceptions (see example below, where exception is not caught). This doesn't seem terribly surprising to me - I imagine that checking would slow down exception handling - but I couldn't find any documentation (and posting on c.l.p didn't turn up anything either). So I thought I would raise it here - perhaps there is a possible fix (my obscure use case is that I have a backtracking search; backtracking occurs when a certain exception is encountered; making that exception an ABC and allowing existing exceptions to be registered with it allows the search to work with existing code without a wrapper that catches and translates exceptions that should trigger a backtrack). Or perhaps the docs could be extended. Or perhaps I've misunderstood something... Cheers, Andrew Python 3.2 (r32:88445, Feb 27 2011, 13:00:05) [GCC 4.5.0 20100604 [gcc-4_5-branch revision 160292]] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from abc import ABCMeta >>> class RootException(Exception,metaclass=ABCMeta): pass ... >>> class MyException(Exception): pass ... >>> RootException.register(MyException) >>> try: ... raise MyException ... except RootException: ... print('caught') ... Traceback (most recent call last): File "<stdin>", line 2, in <module> __main__.MyException |
|||
| msg136712 - (view) | Author: Chris Rebert (cvrebert) * | Date: 2011年05月24日 02:10 | |
Scouting around the CPython codebase a bit, I speculate that the cause of this behavior is that PyErr_GivenExceptionMatches() in errors.c uses PyType_IsSubtype() [which simply walks a class's __mro__ checking for pointer equality] rather than PyObject_IsSubclass()/PyObject_IsInstance() [which are smart enough to consult __subclasscheck__()/__instancecheck__() if they exist]. Of course, the more important issue here is whether this behavior is intended or not. I surmise python-dev needs to have a discussion about it? |
|||
| msg136717 - (view) | Author: Chris Rebert (cvrebert) * | Date: 2011年05月24日 02:45 | |
Surveying the docs, the current behavior *is* /technically/ correct (in a suspiciously precise way) according to the Language Reference: http://docs.python.org/dev/reference/compound_stmts.html#grammar-token-try_stmt : "For an except clause with an expression [...] the clause matches the exception if the resulting object is 'compatible' with the exception. An object is compatible with an exception if it is the class or a base class of the exception object" (which exactly describes what PyType_IsSubtype() checks for) The Tutorial is by contrast much more vague: http://docs.python.org/dev/tutorial/errors.html#handling-exceptions : "if [the raised exception's] type matches the exception named after the except keyword, the except clause is executed, and then execution continues after the try statement." No definition of what it means for the types to "match" seems to be given. |
|||
| msg160399 - (view) | Author: James Henstridge (jamesh) | Date: 2012年05月11日 04:44 | |
The documentation for ABCMeta.register() says that it makes the other class a "virtual subclass". That would make the ABC a "virtual base class". So whether the current behaviour is correct depends on whether you consider a "virtual base" to count as a base. From the reasoning behind the introduction of ABCs, it certainly sounds like it should count. Also, this is a feature that works correctly in Pyton 2.7, so could trip people up who are trying to move to Python 3. |
|||
| msg160418 - (view) | Author: Guido van Rossum (gvanrossum) * (Python committer) | Date: 2012年05月11日 16:37 | |
I agree it's a bug and should be fixed. It's too confusing that there would be two slightly different interpretations of isinstance/issubclass where the isinstance() and issubclass() would be using the extended interpretation but the except clause would use the narrow interpretation. The exception matching done by the except clause ought to be explainable in terms of issubclass/isinstance. |
|||
| msg160426 - (view) | Author: Benjamin Peterson (benjamin.peterson) * (Python committer) | Date: 2012年05月11日 17:04 | |
I think being able to catch exception with ABCs is esssentially useless. The originally stated "usecase" can be simply solved by putting classes into a tuple and putting that in the except clause. In general, the whole abc machinary causes lots of code which expects instance and subclass checks to be side-effect free to be able to execute arbitrary code, which creates messes. |
|||
| msg160427 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2012年05月11日 17:08 | |
Perhaps ABCMeta could raise a UserWarning when creating an Exception subclass? |
|||
| msg160428 - (view) | Author: andrew cooke (acooke) | Date: 2012年05月11日 17:20 | |
perhaps it could just work in a simple, consistent way? in my original report i wondered whether there was a significant performance hit. but so far the objections against fixing this seem to be (1) a lawyer could be convinced the current behaviour is consistent with the docs (2) python 3 should remain compatible with python 2 (3) abcmeta is the sucksorz. those don't seem like great arguments against making it just work right, to me. |
|||
| msg160430 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2012年05月11日 17:32 | |
> perhaps it could just work in a simple, consistent way? That would be best obviously. But as Benjamin explained it's quite delicate to make it work while avoiding pitfalls where code involved in exception checking may itself fail with arbitrary errors - say, enter an infinite recursion. It's also why I think it would be a bad idea to fix it in 3.2 (the bugfix branch). In 3.3 we can take riskier decisions. |
|||
| msg160432 - (view) | Author: Benjamin Peterson (benjamin.peterson) * (Python committer) | Date: 2012年05月11日 17:37 | |
Basically, someone needs to produce a patch and we can go from there. |
|||
| msg160435 - (view) | Author: George-Cristian Bîrzan (gcbirzan) | Date: 2012年05月11日 17:47 | |
I posted on python dev that this would slow exception checking considerably so that is a concern. As for possible bugs, this has been working in the 2 branch for a while now, so I don't think that is the biggest issue. As for possible use cases, writing a wrapper around backend, each with its own exceptions and still being able to catch a 'base' exception in your code while still having the ability to catch specific exceptions, without doing awkward stuff like looking at __cause__ (let alone that you have to reraise that in 2 for code that has to run on both branches). Yes, you could patch the exceptions' bases but that is what Abc was created to avoid. Sorry for the mistakes and weird phrasing, posting this off my phone. |
|||
| msg160436 - (view) | Author: George-Cristian Bîrzan (gcbirzan) | Date: 2012年05月11日 17:49 | |
I have a patch, with tests, but no Internet on my computer so going out, will post it when I get back/my Internet comes back |
|||
| msg160461 - (view) | Author: James Henstridge (jamesh) | Date: 2012年05月12日 00:54 | |
Benjamin: if you are after a use case for this feature, see https://code.djangoproject.com/ticket/15901 In Django, there are multiple database backends, each of which currently catch the adapter's DatabaseError and reraise it as Django's DatabaseError so that Django code can handle database errors in a standard way without having to care about which backend they came from. Unfortunately, this loses some information from the exception. My idea for solving that bug was to make Django's DatabaseError an ABC. By registering the various adapter's DatabaseErrors with the ABC, it would not be necessary to catch and reraise them in the backends while still preserving the ability to catch the generic errors in the core. This works fine in Python 2.x, but it was pointed out that it would cause compatibility problems when porting to Python 3.2. |
|||
| msg160468 - (view) | Author: George-Cristian Bîrzan (gcbirzan) | Date: 2012年05月12日 10:48 | |
As promissed the patch. It doesn't break any tests, and it passes the ones I added. I have a pybench one as well, which even though trivial, does point to the fact that there is a degradation in performance, but not sure it's worth posting here. |
|||
| msg161473 - (view) | Author: Jim Jewett (Jim.Jewett) * (Python triager) | Date: 2012年05月24日 02:26 | |
When does the performance hit occur? If it is only when an exception has been raised, and its own class is not listed by the except clause, then I personally wouldn't worry about it; tracing the MRO *could* get arbitrarily long already; it just doesn't in practice. The same should be true of virtual subclassing. On the other hand, if it adds another module or three to the required startup set, that might be a concern... |
|||
| msg200418 - (view) | Author: Alyssa Coghlan (ncoghlan) * (Python committer) | Date: 2013年10月19日 13:54 | |
The performance hit is that such a change would potentially make it more expensive to figure out that a raised exception *doesn't* match a given "except" clause, along with the complexity of introducing execution of arbitrary code while still unwinding the stack looking for an exception handler for the original exception.
As Benjamin noted above we already support dynamic exception handling through dynamically bound tuple lookups, so I don't think this feature is needed for the Django used case:
>>> caught_exceptions = ()
>>> def f(to_raise):
... try:
... raise to_raise
... except caught_exceptions:
... print("Caught the exception")
...
>>> f(Exception)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in f
Exception
>>> caught_exceptions = (Exception,)
>>> f(Exception)
Caught the exception
I know Guido indicated above that he considers the current behaviour a bug, and I even agree that enshrining the two slightly different definitions of "issubclass" is ugly, but the complete lack of use cases without other solutions and the complex implications of unifying them mean that I think it may be worth accepting the additional complexity in the language definition instead.
That means the question in my mind is whether we can make it less surprising/user-hostile by issuing a warning at class definition time.
Since all exceptions are required to inherit from BaseException in order to be permitted in raise statements *or* except clauses, it seems to me that having a check in PyType ready that emits a warning when it detects the use of the virtual subclass machinery should suffice. That is, all of these should emit a warning:
class BadExceptionABC_1(BaseException, metaclass=abc.ABCMeta): pass
class BadExceptionABC_2(abc.ABC, BaseException): pass
class BadExceptionABC_3(BaseException):
def __instancecheck__(*args): return False
class BadExceptionABC_4(BaseException):
def __subclasscheck__(*args): return False
We could even go further and make it a DeprecationWarning intially and upgrade to a full TypeError in a later release (although we obviously can't do that if Guido would prefer to unify the behaviour instead).
|
|||
| msg200420 - (view) | Author: Alyssa Coghlan (ncoghlan) * (Python committer) | Date: 2013年10月19日 14:07 | |
Actually, I take back the performance comment - Jim's right that in the normal case, the slowdown should be minimal (it's just some additional checks that certain slots aren't populated on each listed exception class), and types can already influence that by messing with the MRO. That just leaves the complexity argument associated with running arbitrary code at an unexpected place in the eval loop, and for that the tests in the patch would need to be strengthened with some pathological examples like: - __subclasscheck__ raising an exception - __subclasscheck__ raising and then suppressing an exception - __subclasscheck__ invoking the garbage collector - __subclasscheck__ hitting the recursion limit - __subclasscheck__ provoking MemoryError The games the current patch already has to play with the recursion limit also bother me. However, if an alternate approach could be found that avoids the adjustment of the recursion limit in the eval loop, that also sensibly survived the kinds of arbitrary code execution torture tests I mention above, then I'd be far more sanguine about the idea of actually resolving the discrepancy rather than formalising it as part of the general fact that the exception hierarchy isn't as flexible as most of the rest of the language. |
|||
| msg200421 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2013年10月19日 14:10 | |
> Actually, I take back the performance comment - Jim's right that in > the normal case, the slowdown should be minimal (it's just some > additional checks that certain slots aren't populated on each listed > exception class), and types can already influence that by messing with > the MRO. I think that the performance question can only really be answered by running (micro-)benchmarks here. |
|||
| msg200829 - (view) | Author: Yuriy Taraday (yorik.sar) | Date: 2013年10月21日 19:34 | |
Can someone please point out why do we have to do that dance with recursion limit? I've came upon this problem as well. I had some (bad) API I had to work with. It always raised the same exception with the only difference in the message. So I thought I could do something like this: def message_contains(msg): class _MyExc(object): def __instancecheck__(self, exc): return msg in exc.args[0] return _MyExc But after I tried it in number of different ways I found out that it's not possible. So here's another reason to change this behavior. |
|||
| msg201329 - (view) | Author: Alyssa Coghlan (ncoghlan) * (Python committer) | Date: 2013年10月26日 08:28 | |
Because context managers are closer to try/finally blocks than they are to exception handling, the class-based implementation for the contextlib.suppress API uses issubclass rather than emulating the CPython exception handling semantics: http://hg.python.org/cpython/file/09153a9a3bb9/Lib/contextlib.py#l202 The exception checking in the unittest module is similarly based on issubclass: http://hg.python.org/cpython/file/09153a9a3bb9/Lib/unittest/case.py#l129 I'm planning to add the catch() and ExitLabel() context managers to contextlib2 this evening, and those too will be based on issubclass(). Perhaps as a near term thing, we should put an "implementation detail" notice somewhere in the language reference, pointing that it's the code using issubclass that is considered correct here, and CPython's exception handling that is considered out of line? |
|||
| msg202019 - (view) | Author: Alyssa Coghlan (ncoghlan) * (Python committer) | Date: 2013年11月03日 12:36 | |
A point on the safety/correctness front: I remembered we already run arbitrary code at roughly this point in the eval loop, as we have to invoke __iter__ to get the exceptions to check when an iterable is used in except clause. That means allowing the subclass check hooks to run here isn't as radical a change as I first thought. |
|||
| msg205830 - (view) | Author: Guido van Rossum (gvanrossum) * (Python committer) | Date: 2013年12月10日 15:44 | |
"I remembered we already run arbitrary code at roughly this point in the eval loop, as we have to invoke __iter__ to get the exceptions to check when an iterable is used in except clause." Are you sure? IIRC the except clause only accept exceptions and tuples of exceptions, not iterators. |
|||
| msg205880 - (view) | Author: Alyssa Coghlan (ncoghlan) * (Python committer) | Date: 2013年12月11日 04:37 | |
Ah, you're right - I found the example I was thinking of (Richard Jones's "Don't do this!" talk), and it was just demonstrating that the except clause accepts any expressions producing a tuple or BaseException instance, not that we call __iter__ at that point. And since we do identity checks for the exception type matching (rather than equality checks), it looks like all the avenues for arbitrary code execution while checking if an exception handler matches a thrown an exception are closed off. |
|||
| msg228158 - (view) | Author: Antony Lee (Antony.Lee) * | Date: 2014年10月02日 04:53 | |
"it looks like all the avenues for arbitrary code execution while checking if an exception handler matches a thrown an exception are closed off." This seems to be directly contradicted by your previous sentence: "the except clause accepts any expressions producing a tuple or BaseException instance". e.g. === >>> def f(): raise AttributeError ... >>> try: raise IndexError ... except f(): raise KeyError ... Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 2, in <module> File "<stdin>", line 1, in f AttributeError === (note that f() is evaluated only if the body of "try" actually raises) |
|||
| msg228159 - (view) | Author: Guido van Rossum (gvanrossum) * (Python committer) | Date: 2014年10月02日 05:10 | |
ISTM Nick meant that the exception that was raised can't cause arbitrary code execution. On Wednesday, October 1, 2014, Antony Lee <report@bugs.python.org> wrote: > > Antony Lee added the comment: > > "it looks like all the avenues for arbitrary code execution while checking > if an exception handler matches a thrown an exception are closed off." > > This seems to be directly contradicted by your previous sentence: "the > except clause accepts any expressions producing a tuple or BaseException > instance". > > e.g. > > === > > >>> def f(): raise AttributeError > ... > >>> try: raise IndexError > ... except f(): raise KeyError > ... > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > IndexError > > During handling of the above exception, another exception occurred: > > Traceback (most recent call last): > File "<stdin>", line 2, in <module> > File "<stdin>", line 1, in f > AttributeError > > === > > (note that f() is evaluated only if the body of "try" actually raises) > > ---------- > nosy: +Antony.Lee > > _______________________________________ > Python tracker <report@bugs.python.org <javascript:;>> > <http://bugs.python.org/issue12029> > _______________________________________ > |
|||
| msg228171 - (view) | Author: Alyssa Coghlan (ncoghlan) * (Python committer) | Date: 2014年10月02日 07:31 | |
Right, I had a specific concern related to the way the C level code works. On closer inspection, it turned out all the Python level code execution is complete by the time we reach the point I was worried about. |
|||
| msg228195 - (view) | Author: Georg Brandl (georg.brandl) * (Python committer) | Date: 2014年10月02日 10:01 | |
I'm attaching a patch that works without changing the recursion limit, and adds some tests for pathological cases. Instead, PyErr_GivenExceptionMatches is changed so that if an exception was previously set, it is replaced by an exception that PyObject_IsSubclass raises. In that way recursion errors should be propagated properly. In exception matching, this means that exceptions (including recursion errors) from PyObject_IsSubclass are ignored. There is already an explicit test for this behavior in test_exceptions. This behavior *could* be changed if intended by introducing a variant of PyErr_GivenExceptionMatches that can set an exception even if none was set before, and calling that in cmp_outcome in ceval. |
|||
| msg228196 - (view) | Author: Georg Brandl (georg.brandl) * (Python committer) | Date: 2014年10月02日 10:09 | |
New version including (I think) correct refcount handling. |
|||
| msg228198 - (view) | Author: Georg Brandl (georg.brandl) * (Python committer) | Date: 2014年10月02日 10:20 | |
Clarifying some comments in this one. |
|||
| msg228209 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2014年10月02日 10:51 | |
I'm worried about the runtime cost of this. Code like this is an extremely common idiom and should remain fast: try: x = d[key] except KeyError: # do something else |
|||
| msg228213 - (view) | Author: Georg Brandl (georg.brandl) * (Python committer) | Date: 2014年10月02日 11:09 | |
Agreed. Since type has __subclasscheck__ (why I don't know) this might result in a slowdown since all checks have to go through calling it in PyObject_IsSubclass. Just noticed that given_exception_matches_inner can be simplified a bit since PyObject_IsSubclass already checks for tuples by itself. |
|||
| msg228214 - (view) | Author: Georg Brandl (georg.brandl) * (Python committer) | Date: 2014年10月02日 11:15 | |
Quick microbenchmark:
try:
{}["a"]
except KeyError:
pass
original tip: 1.35 usec
with patch v3: 1.55 usec
so it's about 15% slowdown for catching a simple exception on my machine.
|
|||
| msg228215 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2014年10月02日 11:19 | |
> Since type has __subclasscheck__ (why I don't know) Ouch, really? That means the PyType_IsSubtype path in PyObject_IsSubclass() is never taken? I think we should add a tp_subclasscheck slot to minimize the general cost of this. Also, try to see if there aren't redundant type / tuple checks along the way. |
|||
| msg228216 - (view) | Author: Georg Brandl (georg.brandl) * (Python committer) | Date: 2014年10月02日 11:29 | |
OK, with these two patches (speedup and v4) I can't see a significant slowdown anymore. |
|||
| msg228219 - (view) | Author: Georg Brandl (georg.brandl) * (Python committer) | Date: 2014年10月02日 11:40 | |
IsSubclass speedup patch now tracked in #22540. |
|||
| msg234434 - (view) | Author: Yuriy Taraday (yorik.sar) | Date: 2015年01月21日 13:29 | |
Can we move forward and land this patch? It seems to be working and for some reason it even makes that microbenchmark work faster. |
|||
| msg253270 - (view) | Author: Josh Rosenberg (josh.r) * (Python triager) | Date: 2015年10月21日 01:47 | |
Does this introduce a slowdown when the type doesn't match? That is, clearly George's example:
try:
{}["a"]
except KeyError:
pass
won't be slowed because the fast path will get an immediate hit. But what about:
try:
{}["a"]
except TypeError:
pass
except ValueError:
pass
except KeyError:
pass
(or with the KeyError handler higher up the call stack). The fast path speeds up the handled case, but it doesn't seem like it would help the unhandled case (where it would need to check the slow path for each unhandled exception type one at a time).
|
|||
| msg253272 - (view) | Author: Josh Rosenberg (josh.r) * (Python triager) | Date: 2015年10月21日 01:52 | |
On rereading #22540, maybe that won't be an issue (in the common case where no custom metaclasses are used for the exceptions to be caught, it looks like maybe there is no slow path to traverse?). Still worth double checking. |
|||
| msg253288 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2015年10月21日 14:15 | |
Note from discussion on duplicate issue 25448: when this is fixed, the try/except documentation should be updated to indicate that the except clause test is equivalent to 'issubclass', so that the handling of virtual subclasses are implied by the doc. (The current proposed patch contains no doc changes.) Apparently this also affects pypy. |
|||
| msg253958 - (view) | Author: Martin Panter (martin.panter) * (Python committer) | Date: 2015年11月03日 02:39 | |
In the current (v4) patch, it looks like there is an unneeded "allow_new_exception" parameter that is always set to zero. So maybe the patch needs more careful thought. Also I agree it needs documentation, what’s new, "changed in version 3.6", etc. |
|||
| msg273436 - (view) | Author: Alyssa Coghlan (ncoghlan) * (Python committer) | Date: 2016年08月23日 12:11 | |
This question came up again recently over in #27814, in the context of a proposal to add an "unless" parameter to contextlib.suppress(). I declined the RFE mainly on the basis of API complexity, but I also noted you can get something comparable in the current API by using virtual subclassing to say "If a subclass of these, but not of these": http://bugs.python.org/issue27814#msg273434 So the status quo is currently giving us a slightly odd discrepancy between normal except clauses and code that emulates them via issubclass() |
|||
| msg315257 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2018年04月13日 19:09 | |
Silencing exceptions like MemoryError, RecursionError or KeyboardInterrupt and returning a lying result doesn't look like a good idea to me. These exceptions can be raised in virtually any code for causes not related to executed code. MemoryError -- if other parts of the program allocated too much memory, RecursionError -- if the exception check is performed too deep in the execution stack, KeyboardInterrupt -- for obvious reasons. |
|||
| msg315267 - (view) | Author: Michael McCoy (Michael McCoy) * | Date: 2018年04月13日 21:12 | |
Amalgamating the patch history here, I've updated the tests on Github (PR6160) to include tests for both the recursive case and ensure the correct error is propagated up if an exception occurs during the subclass check. I've also added a check to ensure that unittest's assertRaises behaves as expected. (The test currently passes on master, which is a bug if this doesn't get merged.) Finally, the PR updates the documentation for try/except. |
|||
| msg315268 - (view) | Author: Michael McCoy (Michael McCoy) * | Date: 2018年04月13日 21:37 | |
Sorry, my last message referred to Github PR6460 / pull_request6160. |
|||
| msg412778 - (view) | Author: Guido van Rossum (gvanrossum) * (Python committer) | Date: 2022年02月07日 18:12 | |
Fixing the version field. Since it's a feature, this could not go into any version before 3.11. Maybe Irit can look through the discussion and patch and see if there's value to doing this? (Feel free to decline!) |
|||
| msg412798 - (view) | Author: Michael McCoy (Michael McCoy) * | Date: 2022年02月07日 23:00 | |
Checking my comment history here, a past me was terribly bad at linking the correct PR on github.This is the correct link: https://github.com/python/cpython/pull/6461 On Mon, Feb 7, 2022 at 10:12 AM Guido van Rossum <report@bugs.python.org> wrote: > > Guido van Rossum <guido@python.org> added the comment: > > Fixing the version field. Since it's a feature, this could not go into any > version before 3.11. > > Maybe Irit can look through the discussion and patch and see if there's > value to doing this? (Feel free to decline!) > > ---------- > nosy: +iritkatriel > versions: +Python 3.11 -Python 3.4, Python 3.5, Python 3.6, Python 3.7, > Python 3.8, Python 3.9 > > _______________________________________ > Python tracker <report@bugs.python.org> > <https://bugs.python.org/issue12029> > _______________________________________ > |
|||
| msg412799 - (view) | Author: Irit Katriel (iritkatriel) * (Python committer) | Date: 2022年02月07日 23:23 | |
To summarise the discussion so far: The arguments in favour of changing exception matching to match on virtual base classes are: 1. It is confusing that it doesn't follow issubclass semantics. 2. Two use cases were presented as practical motivation. - one in msg135521, which can be solved with the pattern in msg200418 - one in msg200829, which is typically done with except: if condition: handle raise The arguments against the change are 1. safety - calling python code from the exception propagation code 2. possible performance impact I am not too worried about the performance of exception handling. I am also not impressed by the use cases. For me it's mostly between the safety issue and the aesthetic language consistency issue. The code path from when a RAISE opcode executes and until control passes to an except clause, is a very sensitive one and I have a lot of sympathy to the position that we should just change the documentation to say that matching is on non-virtual base classes. It is much easier to implement this feature than to predict how it would behave in all cases. If we do decide to implement this, then I don't think the patch is the way we should do it. If the IsSubclass call fails, this should result in a "goto error", like when the match type is invalid: https://github.com/python/cpython/blob/7ba1cc8049fbcb94ac039ab02522f78177130588/Python/ceval.c#L3831 This means that the failure to determine whether the exception is a match is the dominant error, rather than something we print to the ether via the unraisablehook and interpret as non-match. |
|||
| msg412801 - (view) | Author: Guido van Rossum (gvanrossum) * (Python committer) | Date: 2022年02月08日 00:13 | |
Thanks you. I think it's reasonable to reject the feature request and instead update the docs, so let's do that. |
|||
| msg415700 - (view) | Author: Irit Katriel (iritkatriel) * (Python committer) | Date: 2022年03月21日 20:41 | |
New changeset 45833b50f0ccf2abb01304c900afee05b6d01b9e by Irit Katriel in branch 'main': bpo-12029: [doc] clarify that except does not match virtual subclasses of the specified exception type (GH-32027) https://github.com/python/cpython/commit/45833b50f0ccf2abb01304c900afee05b6d01b9e |
|||
| msg415705 - (view) | Author: Irit Katriel (iritkatriel) * (Python committer) | Date: 2022年03月21日 21:22 | |
New changeset 7fc12540e3e873d8ff49711e70fd691185f977b9 by Irit Katriel in branch '3.10': bpo-12029: [doc] clarify that except does not match virtual subclasses of the specified exception type (GH-32027) (GH-32034) https://github.com/python/cpython/commit/7fc12540e3e873d8ff49711e70fd691185f977b9 |
|||
| msg415707 - (view) | Author: Irit Katriel (iritkatriel) * (Python committer) | Date: 2022年03月21日 21:28 | |
New changeset 2d5e9f8d6296cc52da9823bb57e7f03d60b34d27 by Irit Katriel in branch '3.9': bpo-12029: [doc] clarify that except does not match virtual subclasses of the specified exception type (GH-32027) (GH-32035) https://github.com/python/cpython/commit/2d5e9f8d6296cc52da9823bb57e7f03d60b34d27 |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:17 | admin | set | github: 56238 |
| 2022年03月21日 21:28:16 | iritkatriel | set | messages: + msg415707 |
| 2022年03月21日 21:28:15 | iritkatriel | set | status: open -> closed resolution: fixed stage: patch review -> resolved |
| 2022年03月21日 21:22:53 | iritkatriel | set | messages: + msg415705 |
| 2022年03月21日 21:03:17 | iritkatriel | set | pull_requests: + pull_request30126 |
| 2022年03月21日 20:51:45 | iritkatriel | set | pull_requests: + pull_request30125 |
| 2022年03月21日 20:41:44 | iritkatriel | set | messages: + msg415700 |
| 2022年03月21日 11:57:18 | iritkatriel | set | pull_requests: + pull_request30116 |
| 2022年02月08日 19:51:02 | georg.brandl | set | nosy:
- georg.brandl |
| 2022年02月08日 19:39:26 | iritkatriel | set | nosy:
+ docs@python title: Allow catching virtual subclasses in except clauses -> [doc] clarify that except does not match virtual subclasses of the specified exception type assignee: docs@python versions: + Python 3.9, Python 3.10 components: + Documentation |
| 2022年02月08日 00:13:52 | gvanrossum | set | messages: + msg412801 |
| 2022年02月07日 23:23:46 | iritkatriel | set | messages: + msg412799 |
| 2022年02月07日 23:00:58 | Michael McCoy | set | messages: + msg412798 |
| 2022年02月07日 18:12:44 | gvanrossum | set | nosy:
+ iritkatriel messages: + msg412778 versions: + Python 3.11, - Python 3.4, Python 3.5, Python 3.6, Python 3.7, Python 3.8, Python 3.9 |
| 2022年02月07日 17:44:52 | Václav Dvořák | set | versions: + Python 3.9 |
| 2022年02月07日 17:31:53 | Václav Dvořák | set | nosy:
+ Václav Dvořák |
| 2020年07月02日 18:34:44 | charettes | set | nosy:
+ charettes |
| 2018年05月31日 15:13:13 | eric.snow | set | nosy:
+ eric.snow |
| 2018年04月13日 21:37:41 | Michael McCoy | set | messages:
+ msg315268 versions: + Python 3.4, Python 3.6, Python 3.7, Python 3.8 |
| 2018年04月13日 21:12:21 | Michael McCoy | set | nosy:
+ Michael McCoy messages: + msg315267 |
| 2018年04月13日 20:47:21 | Antony.Lee | set | nosy:
- Antony.Lee |
| 2018年04月13日 20:13:00 | Michael McCoy | set | pull_requests: + pull_request6160 |
| 2018年04月13日 20:12:26 | serhiy.storchaka | link | issue33271 superseder |
| 2018年04月13日 19:09:29 | serhiy.storchaka | set | nosy:
+ serhiy.storchaka messages: + msg315257 |
| 2016年08月24日 13:46:32 | ppperry | set | title: Catching virtual subclasses in except clauses -> Allow catching virtual subclasses in except clauses |
| 2016年08月23日 16:51:54 | berker.peksag | set | nosy:
+ berker.peksag |
| 2016年08月23日 12:11:58 | ncoghlan | set | messages: + msg273436 |
| 2015年11月03日 15:10:48 | r.david.murray | unlink | issue25537 dependencies |
| 2015年11月03日 03:04:41 | martin.panter | link | issue25537 dependencies |
| 2015年11月03日 02:39:38 | martin.panter | set | nosy:
+ martin.panter messages: + msg253958 |
| 2015年10月21日 14:15:19 | r.david.murray | set | nosy:
+ fijal, alex, r.david.murray messages: + msg253288 |
| 2015年10月21日 02:32:09 | eryksun | link | issue25448 superseder |
| 2015年10月21日 01:52:09 | josh.r | set | messages: + msg253272 |
| 2015年10月21日 01:47:47 | josh.r | set | nosy:
+ josh.r messages: + msg253270 |
| 2015年07月21日 07:35:35 | ethan.furman | set | nosy:
- ethan.furman |
| 2015年01月21日 14:11:23 | berker.peksag | set | stage: needs patch -> patch review |
| 2015年01月21日 13:29:09 | yorik.sar | set | messages:
+ msg234434 versions: + Python 3.5, - Python 3.3 |
| 2014年10月02日 11:40:06 | georg.brandl | set | dependencies:
+ speed up isinstance and issubclass for the usual cases messages: + msg228219 |
| 2014年10月02日 11:29:16 | georg.brandl | set | files: + exception_proper_subclass_matching_v4.patch |
| 2014年10月02日 11:29:10 | georg.brandl | set | files:
+ pyobject_issubclass_isinstance_speedup.patch messages: + msg228216 |
| 2014年10月02日 11:19:50 | pitrou | set | messages: + msg228215 |
| 2014年10月02日 11:15:29 | georg.brandl | set | messages: + msg228214 |
| 2014年10月02日 11:09:45 | georg.brandl | set | messages: + msg228213 |
| 2014年10月02日 10:51:08 | pitrou | set | messages: + msg228209 |
| 2014年10月02日 10:21:02 | georg.brandl | set | files: - exception_proper_subclass_matching.patch |
| 2014年10月02日 10:20:29 | georg.brandl | set | files:
+ exception_proper_subclass_matching_v3.patch messages: + msg228198 |
| 2014年10月02日 10:09:37 | georg.brandl | set | files:
+ exception_proper_subclass_matching_v2.patch messages: + msg228196 |
| 2014年10月02日 10:01:50 | georg.brandl | set | files:
+ exception_proper_subclass_matching.patch nosy: + georg.brandl messages: + msg228195 |
| 2014年10月02日 07:31:47 | ncoghlan | set | messages: + msg228171 |
| 2014年10月02日 05:10:07 | gvanrossum | set | messages: + msg228159 |
| 2014年10月02日 04:53:05 | Antony.Lee | set | nosy:
+ Antony.Lee messages: + msg228158 |
| 2013年12月11日 04:37:45 | ncoghlan | set | messages: + msg205880 |
| 2013年12月10日 15:44:38 | gvanrossum | set | messages: + msg205830 |
| 2013年12月10日 12:07:39 | jwilk | set | nosy:
+ jwilk |
| 2013年11月03日 12:36:15 | ncoghlan | set | messages: + msg202019 |
| 2013年10月26日 08:28:09 | ncoghlan | set | messages: + msg201329 |
| 2013年10月21日 19:34:25 | yorik.sar | set | nosy:
+ yorik.sar messages: + msg200829 |
| 2013年10月21日 17:04:21 | ethan.furman | set | nosy:
+ ethan.furman |
| 2013年10月20日 21:15:25 | barry | set | nosy:
+ barry |
| 2013年10月19日 14:10:47 | pitrou | set | messages: + msg200421 |
| 2013年10月19日 14:07:14 | ncoghlan | set | messages: + msg200420 |
| 2013年10月19日 13:54:25 | ncoghlan | set | messages: + msg200418 |
| 2013年10月19日 13:33:32 | ncoghlan | set | nosy:
+ ncoghlan |
| 2012年09月16日 21:37:51 | Trundle | set | nosy:
+ Trundle |
| 2012年05月24日 02:26:45 | Jim.Jewett | set | nosy:
+ Jim.Jewett messages: + msg161473 |
| 2012年05月12日 10:48:57 | gcbirzan | set | files:
+ issue12029.patch keywords: + patch messages: + msg160468 |
| 2012年05月12日 01:09:05 | jamesh | set | type: behavior -> enhancement |
| 2012年05月12日 00:54:20 | jamesh | set | type: enhancement -> behavior messages: + msg160461 |
| 2012年05月11日 20:17:09 | Yury.Selivanov | set | nosy:
+ Yury.Selivanov |
| 2012年05月11日 17:49:48 | gcbirzan | set | messages: + msg160436 |
| 2012年05月11日 17:47:57 | gcbirzan | set | nosy:
+ gcbirzan messages: + msg160435 |
| 2012年05月11日 17:37:20 | benjamin.peterson | set | messages: + msg160432 |
| 2012年05月11日 17:32:28 | pitrou | set | messages: + msg160430 |
| 2012年05月11日 17:22:13 | acooke | set | nosy:
- acooke |
| 2012年05月11日 17:20:31 | acooke | set | messages: + msg160428 |
| 2012年05月11日 17:09:00 | pitrou | set | nosy:
+ pitrou messages: + msg160427 |
| 2012年05月11日 17:04:52 | benjamin.peterson | set | messages: + msg160426 |
| 2012年05月11日 16:57:39 | pitrou | set | nosy:
+ benjamin.peterson type: behavior -> enhancement versions: - Python 3.2 |
| 2012年05月11日 16:44:47 | eric.araujo | set | stage: needs patch versions: + Python 3.2 |
| 2012年05月11日 16:37:40 | gvanrossum | set | nosy:
+ gvanrossum messages: + msg160418 |
| 2012年05月11日 11:31:55 | eric.araujo | set | title: ABC registration of Exceptions -> Catching virtual subclasses in except clauses versions: + Python 3.3, - Python 3.2 |
| 2012年05月11日 04:44:47 | jamesh | set | nosy:
+ jamesh messages: + msg160399 |
| 2011年07月27日 15:08:12 | eric.araujo | set | files: - generictramadolhclonline.html |
| 2011年07月27日 15:08:10 | eric.araujo | set | files: - cheapcodfedextramadolvery.html |
| 2011年07月27日 12:48:12 | junior1971 | set | files: + generictramadolhclonline.html |
| 2011年07月27日 12:04:51 | junior1971 | set | files: + cheapcodfedextramadolvery.html |
| 2011年05月24日 02:45:08 | cvrebert | set | messages: + msg136717 |
| 2011年05月24日 02:10:15 | cvrebert | set | messages: + msg136712 |
| 2011年05月13日 17:07:20 | eric.araujo | set | nosy:
+ eric.araujo |
| 2011年05月08日 09:32:58 | daniel.urban | set | nosy:
+ daniel.urban |
| 2011年05月08日 09:02:07 | cvrebert | set | nosy:
+ cvrebert |
| 2011年05月08日 08:53:43 | acooke | create | |