[Python-Dev] should list's call to __len__ swallow SystemExit?
Guido van Rossum
guido at python.org
Wed Jan 14 19:19:34 CET 2009
On Wed, Jan 14, 2009 at 10:11 AM, Raymond Hettinger <python at rcn.com> wrote:
> _PyObject_LengthHint() is specified to never fail.
> If any exception occurs along the way, it returns a
> default value. In the context of checking for length
> hints from an iterator, this seems reasonable to me.
> If you want this changed, I can use a negative return
> value for other than an attribute error, and modify
> the calling code to handle the exception.
> To me this isn't worth making the code slower and
> more complex. But I can also see wanting to catch
> a SystemError at any possible step.
It has the potential of masking errors, and thus I'd like to see it fixed.
> I presume this same issue occurs everywhere the C API
> has a *this never fails* specification so that we have
> simpler, faster calling code at the expense of being able
> to raise a SystemError in every possible piece of code.
"This never fails" C APIs that invoke Python code (or e.g. allocate
memory) are not supposed to exist in CPython, for the reason above.
There used to be several but we gradually killed them all. I'm sorry I
wasn't involved more deeply in the review of this feature, I would
have warned about it.
> From: "Guido van Rossum" <guido at python.org>
>> There seems to be an unconditional PyErr_Clear() in
>> _PyObject_LengthHint(). I think that could and should be much more
>> careful; it probably should only ignore AttributeErrors (though there
>> may be unittests to the contrary).
>> On Tue, Jan 13, 2009 at 8:24 PM, Dino Viehland <dinov at microsoft.com>
>>> We had a bug reported that effectively boils down to we're not swallowing
>>> exceptions when list calls __len__
>>> We can obviously make the change to catch exceptions here in IronPython
>>> even if it seems like a bad idea to me ☺ But CPython seems to catch not
>>> only normal exceptions, but also SystemExit. It seems like there's been a
>>> move away from this so I thought I'd mention it here. I tested it on 2.6.1
>>> and 3.0.
>>> import sys
>>> class A(object):
>>> def __iter__(self): return iter(range(10))
>>> def __len__(self):
>>> except Exception as e:
>>> print('can I catch it?', e)
>>> which prints:
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> Python-Dev mailing list
>>> Python-Dev at python.org
>> --Guido van Rossum (home page: http://www.python.org/~guido/)
>> Python-Dev mailing list
>> Python-Dev at python.org
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-Dev