<p dir="ltr"><br>
On 7 Nov 2013 21:34, "Victor Stinner" <<a href="mailto:victor.stinner@gmail.com">victor.stinner@gmail.com</a>> wrote:<br>
><br>
> 2013/11/7 Steven D'Aprano <<a href="mailto:steve@pearwood.info">steve@pearwood.info</a>>:<br>
> > My initial instinct here was to say that sounded like premature<br>
> > optimization, but to my surprise the overhead of generating the error<br>
> > message is actually significant -- at least from pure Python 3.3 code.<br>
><br>
> I ran a quick and dirty benchmark by replacing the error message with None.<br>
><br>
> Original:<br>
><br>
> $ ./python -m timeit 'hasattr(1, "y")'<br>
> 1000000 loops, best of 3: 0.354 usec per loop<br>
> $ ./python -m timeit -s 's=1' 'try: s.y' 'except AttributeError: pass'<br>
> 1000000 loops, best of 3: 0.471 usec per loop<br>
><br>
> Patched:<br>
><br>
> $ ./python -m timeit 'hasattr(1, "y")'<br>
> 10000000 loops, best of 3: 0.106 usec per loop<br>
> $ ./python -m timeit -s 's=1' 'try: s.y' 'except AttributeError: pass'<br>
> 10000000 loops, best of 3: 0.191 usec per loop<br>
><br>
> hasattr() is 3.3x faster and try/except is 2.4x faster on such micro benchmark.<br>
><br>
> > Given that, I wonder whether it would be worth coming up with a more<br>
> > general solution to the question of lazily generating error messages<br>
> > rather than changing AttributeError specifically.<br>
><br>
> My first question is about keeping strong references to objects (type<br>
> object for AttributeError). Is it an issue? If it is an issue, it's<br>
> maybe better to not modify the code :-)<br>
><br>
><br>
> Yes, the lazy formatting idea can be applied to various other<br>
> exceptions. For example, TypeError message is usually build using<br>
> PyErr_Format() to mention the name of the invalid type. Example:<br>
><br>
>         PyErr_Format(PyExc_TypeError, "exec() arg 2 must be a dict, not %.100s",<br>
>                      globals->ob_type->tp_name);<br>
><br>
> But it's not easy to store arbitary C types for PyUnicode_FromFormat()<br>
> parameters. Argument types can be char*, Py_ssize_t, PyObject*, int,<br>
> etc.<br>
><br>
> I proposed to modify (first/only) AttributeError, because it is more<br>
> common to ignore the AttributeError than other errors like TypeError.<br>
> (TypeError or UnicodeDecodeError are usually unexpected.)<br>
><br>
> >> It would be nice to only format the message on demand. The<br>
> >> AttributeError would keep a reference to the type.<br>
> ><br>
> > Since only the type name is used, why keep a reference to the type<br>
> > instead of just type.__name__?<br>
><br>
> In the C language, type.__name__ does not exist, it's a char* object.<br>
> If the type object is destroyed, type->tp_name becomes an invalid<br>
> pointer. So AttributeError should keep a reference on the type object.<br>
><br>
> >> AttributeError.args would be (type, attr) instead of (message,).<br>
> >> ImportError was also modified to add a new "name "attribute".</p>
<p dir="ltr">The existing signature continued to be supported, though.</p>
<p dir="ltr">> ><br>
> > I don't like changing the signature of AttributeError. I've got code<br>
> > that raises AttributeError explicitly.<br>
><br>
> The constructor may support different signature for backward<br>
> compatibility: AttributeError(message: str) and AttributeError(type:<br>
> type, attr: str).<br>
><br>
> I'm asking if anyone relies on AttributeError.args attribute.</p>
<p dir="ltr">The bigger problem is you can't change the constructor signature in a backwards incompatible way. You would need a new class method as an alternative constructor instead, or else use optional parameters.</p>

<p dir="ltr">Cheers,<br>
Nick.<br></p>
<p dir="ltr">><br>
> Victor<br>
> _______________________________________________<br>
> Python-Dev mailing list<br>
> <a href="mailto:Python-Dev@python.org">Python-Dev@python.org</a><br>
> <a href="https://mail.python.org/mailman/listinfo/python-dev">https://mail.python.org/mailman/listinfo/python-dev</a><br>
> Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com">https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com</a><br>
</p>