Skip to content

Commit f767423

Browse files
cmaloneyclaude
andauthored
gh-161242: Use AC vectorcall for AttributeError, ImportError, NameError (#161462)
These exceptions and their subclasses had no vectorcall, and `__init__` parsed keywords through PyArg_ParseTupleAndKeywords with a temporary empty tuple on every call. Error messages are unchanged except when more keywords than parameters are given, which now names the unexpected keyword. The clinic inputs have no docstring, so docstrings are unchanged and these exceptions don't gain a `__text_signature__`. pyperf microbenchmark (PGO+LTO, run serially): | Benchmark | base | vectorcall | |----------------------------------|:-------:|:---------------------:| | AttributeError(s, name=s, obj=s) | 127 ns | 41.9 ns: 3.02x faster | | ImportError(s, name=s, path=s) | 129 ns | 43.4 ns: 2.96x faster | | NameError(s, name=s) | 88.3 ns | 39.3 ns: 2.24x faster | | ModuleNotFoundError(s, name=s) | 89.9 ns | 40.6 ns: 2.21x faster | | AttributeError(s) | 39.4 ns | 32.1 ns: 1.23x faster | | UnboundLocalError(s) | 38.6 ns | 31.8 ns: 1.22x faster | | NameError(s) | 38.5 ns | 32.2 ns: 1.19x faster | | ImportError(s) | 40.7 ns | 34.4 ns: 1.18x faster | | attribute_error_to_none() | 176 ns | 173 ns: 1.02x faster | Benchmark code: ```python import pyperf runner = pyperf.Runner() setup = """s = 'x' class O: pass o = O() def attribute_error_to_none(): try: o.x except AttributeError: pass """ for stmt in ["AttributeError(s)", "AttributeError(s, name=s, obj=s)", "NameError(s)", "NameError(s, name=s)", "ImportError(s)", "ImportError(s, name=s, path=s)", "ModuleNotFoundError(s, name=s)", "UnboundLocalError(s)", "attribute_error_to_none()"]: runner.timeit(stmt, stmt, setup) ``` Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 5f46ac9 commit f767423

4 files changed

Lines changed: 389 additions & 55 deletions

File tree

‎Lib/test/test_call.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def test_varargs14_kw(self):
208208
itertools.product, 0, repeat=1, foo=2)
209209

210210
def test_varargs15_kw(self):
211-
msg = r"^ImportError\(\) takes at most 3 keyword arguments \(4 given\)$"
211+
msg = r"^ImportError\(\) got an unexpected keyword argument 'foo'$"
212212
self.assertRaisesRegex(TypeError, msg,
213213
ImportError, 0, name=1, path=2, name_from=3, foo=3)
214214

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Speed up :exc:`AttributeError`, :exc:`ImportError` and
2+
:exc:`NameError` by enabling :ref:`vectorcall`. Unexpected
3+
keyword arguments are now reported by name.

‎Objects/clinic/exceptions.c.h‎

Lines changed: 328 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)