
PyObject *tmp; Py_identifier(update);
As I understand it, the macro expands to both the ID variable declaration and the init-at-first-call code, right?
No. The variable will only get static initialization with the char*. The initialization on first call (of the PyObject*) happens in the helper functions, such as PyObject_GetAttrId.
I'm not sure how often users will need more than one identifier in a function
That's actually fairly common.
Also note that existing code needs to be changed in order to take advantage of this. It might be possible to optimise PyObject_CallMethod() internally by making the lookup either reuse a number of cached Python strings, or by supporting a lookup of char* values in a dict *somehow*. However, this appears to be substantially more involved than just moving a smaller burden on the users.
I think this would have to hash the string in any case, since keying by char* pointer value cannot work (there might be a different string at the same memory the next time). So even if this could side-step many of the steps, you'd keep at least one iteration over the characters; if this is hashing, you actually need two iterations (the second one to determine whether it's the right string). The Py_IDENTIFIER API can do the lookup in constant time for all but the first call. Regards, Martin